memorix 0.7.0 → 0.7.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../node_modules/tsup/assets/esm_shims.js","../../src/store/persistence.ts","../../src/memory/graph.ts","../../src/types.ts","../../src/embedding/fastembed-provider.ts","../../src/embedding/transformers-provider.ts","../../src/embedding/provider.ts","../../src/store/orama-store.ts","../../src/compact/token-budget.ts","../../src/memory/entity-extractor.ts","../../src/memory/observations.ts","../../src/memory/auto-relations.ts","../../src/compact/index-format.ts","../../src/compact/engine.ts","../../src/project/detector.ts","../../src/rules/utils.ts","../../src/rules/adapters/cursor.ts","../../src/rules/adapters/claude-code.ts","../../src/rules/adapters/codex.ts","../../src/rules/adapters/windsurf.ts","../../src/rules/adapters/antigravity.ts","../../src/rules/adapters/copilot.ts","../../src/rules/adapters/kiro.ts","../../src/rules/syncer.ts","../../src/workspace/mcp-adapters/windsurf.ts","../../src/workspace/mcp-adapters/cursor.ts","../../src/workspace/mcp-adapters/codex.ts","../../src/workspace/mcp-adapters/claude-code.ts","../../src/workspace/mcp-adapters/copilot.ts","../../src/workspace/mcp-adapters/antigravity.ts","../../src/workspace/mcp-adapters/kiro.ts","../../src/workspace/workflow-sync.ts","../../src/workspace/sanitizer.ts","../../src/workspace/applier.ts","../../src/workspace/engine.ts","../../src/hooks/installers/index.ts","../../src/memory/retention.ts","../../src/skills/engine.ts","../../src/dashboard/server.ts","../../src/server.ts","../../src/cli/commands/serve.ts","../../src/cli/commands/status.ts","../../src/cli/commands/sync.ts","../../src/hooks/normalizer.ts","../../src/hooks/pattern-detector.ts","../../src/hooks/handler.ts","../../src/cli/commands/hook.ts","../../src/cli/commands/hooks-install.ts","../../src/cli/commands/hooks-uninstall.ts","../../src/cli/commands/hooks-status.ts","../../src/cli/commands/hooks.ts","../../src/cli/commands/dashboard.ts","../../src/cli/commands/cleanup.ts","../../src/cli/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Persistence Layer\n *\n * Saves and restores the Orama database to/from disk.\n * Source: @orama/plugin-data-persistence (official Orama plugin)\n *\n * Data is stored in a single global directory shared across all agents:\n * ~/.memorix/data/ (all files: observations.json, graph.jsonl, counter.json)\n */\n\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\n\n/** Default base data directory */\nconst DEFAULT_DATA_DIR = path.join(os.homedir(), '.memorix', 'data');\n\n/**\n * Sanitize a projectId for use as a directory name.\n * Replaces `/` with `--`, removes other unsafe chars.\n */\nfunction sanitizeProjectId(projectId: string): string {\n return projectId.replace(/\\//g, '--').replace(/[<>:\"|?*\\\\]/g, '_');\n}\n\n/**\n * Get the project-specific data directory for Memorix storage.\n * Each project gets its own subdirectory under ~/.memorix/data/\n *\n * Example: projectId \"AVIDS2/memorix\" → ~/.memorix/data/AVIDS2--memorix/\n *\n * @param projectId - Git-based project identifier (e.g. \"user/repo\")\n */\nexport async function getProjectDataDir(projectId: string, baseDir?: string): Promise<string> {\n // Reject sentinel IDs to prevent garbage directories\n if (projectId === '__invalid__') {\n throw new Error('Cannot create data directory for invalid project');\n }\n const base = baseDir ?? DEFAULT_DATA_DIR;\n const dirName = sanitizeProjectId(projectId);\n const dataDir = path.join(base, dirName);\n await fs.mkdir(dataDir, { recursive: true });\n return dataDir;\n}\n\n/**\n * Get the base data directory (parent of all project dirs).\n */\nexport function getBaseDataDir(baseDir?: string): string {\n return baseDir ?? DEFAULT_DATA_DIR;\n}\n\n/**\n * List all project data directories.\n * Used for cross-project (global) search.\n */\nexport async function listProjectDirs(baseDir?: string): Promise<string[]> {\n const base = baseDir ?? DEFAULT_DATA_DIR;\n try {\n const entries = await fs.readdir(base, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => path.join(base, e.name));\n } catch {\n return [];\n }\n}\n\n/**\n * Migrate legacy global data to project-specific directory.\n * If observations.json exists directly in the base data dir (old format),\n * move it into the correct project subdirectory.\n */\nexport async function migrateGlobalData(projectId: string, baseDir?: string): Promise<boolean> {\n const base = baseDir ?? DEFAULT_DATA_DIR;\n const globalObsPath = path.join(base, 'observations.json');\n const migratedObsPath = path.join(base, 'observations.json.migrated');\n\n // Check if global data exists (either live or already-migrated backup)\n let sourceObsPath: string | null = null;\n try {\n await fs.access(globalObsPath);\n sourceObsPath = globalObsPath;\n } catch {\n // Check for .migrated backup that wasn't fully merged\n try {\n await fs.access(migratedObsPath);\n sourceObsPath = migratedObsPath;\n } catch {\n return false; // No global data to migrate\n }\n }\n\n // Read the source (global) observations\n let globalObs: unknown[] = [];\n try {\n const data = await fs.readFile(sourceObsPath, 'utf-8');\n globalObs = JSON.parse(data);\n if (!Array.isArray(globalObs) || globalObs.length === 0) return false;\n } catch {\n return false;\n }\n\n // Read existing project observations (may have been partially written)\n const projectDir = await getProjectDataDir(projectId, baseDir);\n const projectObsPath = path.join(projectDir, 'observations.json');\n let projectObs: unknown[] = [];\n try {\n const data = await fs.readFile(projectObsPath, 'utf-8');\n projectObs = JSON.parse(data);\n if (!Array.isArray(projectObs)) projectObs = [];\n } catch { /* no existing data */ }\n\n // If project already has >= global data, skip (already migrated properly)\n if (projectObs.length >= globalObs.length) {\n return false;\n }\n\n // Merge: global data + project data, deduplicate by ID\n const existingIds = new Set(projectObs.map((o: any) => o.id));\n const merged = [...projectObs];\n for (const obs of globalObs) {\n if (!existingIds.has((obs as any).id)) {\n merged.push(obs);\n }\n }\n\n // Sort by ID\n merged.sort((a: any, b: any) => (a.id ?? 0) - (b.id ?? 0));\n\n // Normalize projectId for all migrated records to the current project\n for (const obs of merged) {\n (obs as any).projectId = projectId;\n }\n\n // Write merged observations\n await fs.writeFile(projectObsPath, JSON.stringify(merged, null, 2), 'utf-8');\n\n // Copy graph and counter if they exist\n for (const file of ['graph.jsonl', 'counter.json']) {\n const src = path.join(base, file);\n const srcMigrated = path.join(base, file + '.migrated');\n const dst = path.join(projectDir, file);\n // Try live file first, then .migrated backup\n for (const source of [src, srcMigrated]) {\n try {\n await fs.access(source);\n await fs.copyFile(source, dst);\n break;\n } catch { /* try next */ }\n }\n }\n\n // Find max ID for counter\n const maxId = merged.reduce((max: number, o: any) => Math.max(max, o.id ?? 0), 0);\n await fs.writeFile(\n path.join(projectDir, 'counter.json'),\n JSON.stringify({ nextId: maxId + 1 }),\n 'utf-8',\n );\n\n // Rename source files to .migrated (if not already)\n for (const file of ['observations.json', 'graph.jsonl', 'counter.json']) {\n const src = path.join(base, file);\n try {\n await fs.access(src);\n await fs.rename(src, src + '.migrated');\n } catch { /* already migrated or doesn't exist */ }\n }\n\n return true;\n}\n\n/**\n * Get the file path for the Orama database file.\n */\nexport function getDbFilePath(projectDir: string): string {\n return path.join(projectDir, 'memorix.msp');\n}\n\n/**\n * Get the file path for the knowledge graph JSONL file.\n * (MCP-compatible format, same as official Memory Server)\n */\nexport function getGraphFilePath(projectDir: string): string {\n return path.join(projectDir, 'graph.jsonl');\n}\n\n/**\n * Check if a database file exists for the given project.\n */\nexport async function hasExistingData(projectDir: string): Promise<boolean> {\n try {\n await fs.access(getDbFilePath(projectDir));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Save the knowledge graph in JSONL format (MCP-compatible).\n * Each line is a JSON object with type: \"entity\" or \"relation\".\n *\n * Format adopted from MCP Official Memory Server.\n */\nexport async function saveGraphJsonl(\n projectDir: string,\n entities: Array<{ name: string; entityType: string; observations: string[] }>,\n relations: Array<{ from: string; to: string; relationType: string }>,\n): Promise<void> {\n const lines = [\n ...entities.map((e) =>\n JSON.stringify({ type: 'entity', name: e.name, entityType: e.entityType, observations: e.observations }),\n ),\n ...relations.map((r) =>\n JSON.stringify({ type: 'relation', from: r.from, to: r.to, relationType: r.relationType }),\n ),\n ];\n await fs.writeFile(getGraphFilePath(projectDir), lines.join('\\n'), 'utf-8');\n}\n\n/**\n * Load the knowledge graph from JSONL format.\n */\nexport async function loadGraphJsonl(\n projectDir: string,\n): Promise<{\n entities: Array<{ name: string; entityType: string; observations: string[] }>;\n relations: Array<{ from: string; to: string; relationType: string }>;\n}> {\n const filePath = getGraphFilePath(projectDir);\n try {\n const data = await fs.readFile(filePath, 'utf-8');\n const lines = data.split('\\n').filter((line) => line.trim() !== '');\n return lines.reduce(\n (graph, line) => {\n const item = JSON.parse(line);\n if (item.type === 'entity') {\n graph.entities.push({\n name: item.name,\n entityType: item.entityType,\n observations: item.observations,\n });\n }\n if (item.type === 'relation') {\n graph.relations.push({\n from: item.from,\n to: item.to,\n relationType: item.relationType,\n });\n }\n return graph;\n },\n {\n entities: [] as Array<{ name: string; entityType: string; observations: string[] }>,\n relations: [] as Array<{ from: string; to: string; relationType: string }>\n },\n );\n } catch (error) {\n if (error instanceof Error && 'code' in error && (error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { entities: [], relations: [] };\n }\n throw error;\n }\n}\n\n/**\n * Save observation data as JSON (for Orama restore).\n */\nexport async function saveObservationsJson(\n projectDir: string,\n observations: unknown[],\n): Promise<void> {\n const filePath = path.join(projectDir, 'observations.json');\n await fs.writeFile(filePath, JSON.stringify(observations, null, 2), 'utf-8');\n}\n\n/**\n * Load observation data from JSON.\n */\nexport async function loadObservationsJson(projectDir: string): Promise<unknown[]> {\n const filePath = path.join(projectDir, 'observations.json');\n try {\n const data = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(data);\n } catch (error) {\n if (error instanceof Error && 'code' in error && (error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n}\n\n/**\n * Save the next observation ID counter.\n */\nexport async function saveIdCounter(projectDir: string, nextId: number): Promise<void> {\n const filePath = path.join(projectDir, 'counter.json');\n await fs.writeFile(filePath, JSON.stringify({ nextId }), 'utf-8');\n}\n\n/**\n * Load the next observation ID counter.\n */\nexport async function loadIdCounter(projectDir: string): Promise<number> {\n const filePath = path.join(projectDir, 'counter.json');\n try {\n const data = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(data).nextId ?? 1;\n } catch {\n return 1;\n }\n}\n","/**\n * Knowledge Graph Manager\n *\n * Manages the Entity-Relation knowledge graph.\n * Source: MCP Official Memory Server v0.6.3 (complete rewrite with same API).\n *\n * Key differences from official implementation:\n * - Uses per-project JSONL files (official uses single file)\n * - Async initialization with persistence layer\n * - Project-scoped operations\n */\n\nimport type { Entity, Relation, KnowledgeGraph } from '../types.js';\nimport { saveGraphJsonl, loadGraphJsonl } from '../store/persistence.js';\n\nexport class KnowledgeGraphManager {\n private entities: Entity[] = [];\n private relations: Relation[] = [];\n private projectDir: string;\n private initialized = false;\n\n constructor(projectDir: string) {\n this.projectDir = projectDir;\n }\n\n /** Load graph from disk on first access */\n async init(): Promise<void> {\n if (this.initialized) return;\n const data = await loadGraphJsonl(this.projectDir);\n this.entities = data.entities;\n this.relations = data.relations;\n this.initialized = true;\n }\n\n /** Persist current state to disk */\n private async save(): Promise<void> {\n await saveGraphJsonl(this.projectDir, this.entities, this.relations);\n }\n\n /** Create new entities (skip duplicates by name) */\n async createEntities(entities: Entity[]): Promise<Entity[]> {\n await this.init();\n const newEntities = entities.filter(\n (e) => !this.entities.some((existing) => existing.name === e.name),\n );\n this.entities.push(...newEntities);\n await this.save();\n return newEntities;\n }\n\n /** Create new relations (skip duplicates) */\n async createRelations(relations: Relation[]): Promise<Relation[]> {\n await this.init();\n const newRelations = relations.filter(\n (r) =>\n !this.relations.some(\n (existing) =>\n existing.from === r.from &&\n existing.to === r.to &&\n existing.relationType === r.relationType,\n ),\n );\n this.relations.push(...newRelations);\n await this.save();\n return newRelations;\n }\n\n /** Add observations to existing entities */\n async addObservations(\n observations: { entityName: string; contents: string[] }[],\n ): Promise<{ entityName: string; addedObservations: string[] }[]> {\n await this.init();\n const results = observations.map((o) => {\n const entity = this.entities.find((e) => e.name === o.entityName);\n if (!entity) {\n throw new Error(`Entity with name ${o.entityName} not found`);\n }\n const newObs = o.contents.filter((c) => !entity.observations.includes(c));\n entity.observations.push(...newObs);\n return { entityName: o.entityName, addedObservations: newObs };\n });\n await this.save();\n return results;\n }\n\n /** Delete entities and their associated relations */\n async deleteEntities(entityNames: string[]): Promise<void> {\n await this.init();\n this.entities = this.entities.filter((e) => !entityNames.includes(e.name));\n this.relations = this.relations.filter(\n (r) => !entityNames.includes(r.from) && !entityNames.includes(r.to),\n );\n await this.save();\n }\n\n /** Delete specific observations from entities */\n async deleteObservations(\n deletions: { entityName: string; observations: string[] }[],\n ): Promise<void> {\n await this.init();\n for (const d of deletions) {\n const entity = this.entities.find((e) => e.name === d.entityName);\n if (entity) {\n entity.observations = entity.observations.filter(\n (o) => !d.observations.includes(o),\n );\n }\n }\n await this.save();\n }\n\n /** Delete specific relations */\n async deleteRelations(relations: Relation[]): Promise<void> {\n await this.init();\n this.relations = this.relations.filter(\n (r) =>\n !relations.some(\n (del) =>\n r.from === del.from &&\n r.to === del.to &&\n r.relationType === del.relationType,\n ),\n );\n await this.save();\n }\n\n /** Read the entire graph */\n async readGraph(): Promise<KnowledgeGraph> {\n await this.init();\n return { entities: this.entities, relations: this.relations };\n }\n\n /** Search nodes by query string (upgraded from official's basic includes) */\n async searchNodes(query: string): Promise<KnowledgeGraph> {\n await this.init();\n const lowerQuery = query.toLowerCase();\n\n const filteredEntities = this.entities.filter(\n (e) =>\n e.name.toLowerCase().includes(lowerQuery) ||\n e.entityType.toLowerCase().includes(lowerQuery) ||\n e.observations.some((o) => o.toLowerCase().includes(lowerQuery)),\n );\n\n const filteredNames = new Set(filteredEntities.map((e) => e.name));\n\n const filteredRelations = this.relations.filter(\n (r) => filteredNames.has(r.from) && filteredNames.has(r.to),\n );\n\n return { entities: filteredEntities, relations: filteredRelations };\n }\n\n /** Open specific nodes by name */\n async openNodes(names: string[]): Promise<KnowledgeGraph> {\n await this.init();\n\n const filteredEntities = this.entities.filter((e) => names.includes(e.name));\n const filteredNames = new Set(filteredEntities.map((e) => e.name));\n\n const filteredRelations = this.relations.filter(\n (r) => filteredNames.has(r.from) && filteredNames.has(r.to),\n );\n\n return { entities: filteredEntities, relations: filteredRelations };\n }\n}\n","/**\n * Memorix Core Types\n *\n * Data model sources:\n * - Entity/Relation/KnowledgeGraph: MCP Official Memory Server (v0.6.3)\n * - Observation/ObservationType: claude-mem Progressive Disclosure\n * - UnifiedRule/RuleSource: Memorix original (rules sync)\n *\n * Designed for extensibility: new agent formats (Kiro, Copilot, Antigravity)\n * can be added by extending RuleSource and adding format adapters.\n */\n\n// ============================================================\n// Knowledge Graph (adopted from MCP Official Memory Server)\n// ============================================================\n\n/** A node in the knowledge graph representing a concept, component, or config */\nexport interface Entity {\n name: string;\n entityType: string;\n observations: string[];\n}\n\n/** A directed edge between two entities */\nexport interface Relation {\n from: string;\n to: string;\n relationType: string;\n}\n\n/** The complete knowledge graph */\nexport interface KnowledgeGraph {\n entities: Entity[];\n relations: Relation[];\n}\n\n// ============================================================\n// Observation (adopted from claude-mem Progressive Disclosure)\n// ============================================================\n\n/**\n * Observation type classification using claude-mem's icon-based legend system.\n *\n * Icon mapping:\n * 🎯 session-request — User's original goal\n * 🔴 gotcha — Critical pitfall / trap\n * 🟡 problem-solution — Bug fix or workaround\n * 🔵 how-it-works — Technical explanation\n * 🟢 what-changed — Code/architecture change\n * 🟣 discovery — New learning or insight\n * 🟠 why-it-exists — Design rationale\n * 🟤 decision — Architecture decision\n * ⚖️ trade-off — Deliberate compromise\n */\nexport type ObservationType =\n | 'session-request'\n | 'gotcha'\n | 'problem-solution'\n | 'how-it-works'\n | 'what-changed'\n | 'discovery'\n | 'why-it-exists'\n | 'decision'\n | 'trade-off';\n\n/** Map from ObservationType to display icon */\nexport const OBSERVATION_ICONS: Record<ObservationType, string> = {\n 'session-request': '🎯',\n 'gotcha': '🔴',\n 'problem-solution': '🟡',\n 'how-it-works': '🔵',\n 'what-changed': '🟢',\n 'discovery': '🟣',\n 'why-it-exists': '🟠',\n 'decision': '🟤',\n 'trade-off': '⚖️',\n};\n\n/** A rich observation record attached to an entity */\nexport interface Observation {\n id: number;\n entityName: string;\n type: ObservationType;\n title: string;\n narrative: string;\n facts: string[];\n filesModified: string[];\n concepts: string[];\n tokens: number;\n createdAt: string;\n projectId: string;\n /** Whether the observation contains causal language (because, due to, etc.) */\n hasCausalLanguage?: boolean;\n}\n\n// ============================================================\n// Compact Engine (adopted from claude-mem 3-layer workflow)\n// ============================================================\n\n/** L1 index entry — lightweight, ~50-100 tokens per result */\nexport interface IndexEntry {\n id: number;\n time: string;\n type: ObservationType;\n icon: string;\n title: string;\n tokens: number;\n}\n\n/** L2 timeline context — observations around an anchor */\nexport interface TimelineContext {\n anchorId: number;\n anchorEntry: IndexEntry | null;\n before: IndexEntry[];\n after: IndexEntry[];\n}\n\n/** Search options for the compact engine */\nexport interface SearchOptions {\n query: string;\n limit?: number;\n type?: ObservationType;\n projectId?: string;\n since?: string;\n until?: string;\n /** Token budget — trim results to fit within this many tokens (0 = unlimited) */\n maxTokens?: number;\n}\n\n// ============================================================\n// Orama Document Schema\n// ============================================================\n\n/** The document shape stored in Orama */\nexport interface MemorixDocument {\n id: string;\n observationId: number;\n entityName: string;\n type: string;\n title: string;\n narrative: string;\n facts: string;\n filesModified: string;\n concepts: string;\n tokens: number;\n createdAt: string;\n projectId: string;\n /** Number of times this observation was returned in search results */\n accessCount: number;\n /** ISO timestamp of last access via search/detail */\n lastAccessedAt: string;\n}\n\n// ============================================================\n// Rules System (Memorix original — extensible for new agents)\n// ============================================================\n\n/**\n * Supported agent/IDE rule sources.\n * All 7 major AI IDEs are supported.\n */\nexport type RuleSource =\n | 'cursor'\n | 'claude-code'\n | 'codex'\n | 'windsurf'\n | 'antigravity'\n | 'copilot'\n | 'kiro'\n | 'memorix';\n\n/** A parsed rule in the unified intermediate representation */\nexport interface UnifiedRule {\n id: string;\n content: string;\n description?: string;\n source: RuleSource;\n scope: 'global' | 'project' | 'path-specific';\n paths?: string[];\n alwaysApply?: boolean;\n priority: number;\n hash: string;\n}\n\n/**\n * Format adapter interface — implement this for each agent/IDE.\n * Adding a new agent (e.g., Kiro) only requires implementing this interface.\n */\nexport interface RuleFormatAdapter {\n /** Unique identifier for this agent format */\n readonly source: RuleSource;\n\n /** File paths/globs this adapter can parse */\n readonly filePatterns: string[];\n\n /** Parse rule files into unified representation */\n parse(filePath: string, content: string): UnifiedRule[];\n\n /** Generate rule file content from unified representation */\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[];\n}\n\n// ============================================================\n// Project Identity\n// ============================================================\n\nexport interface ProjectInfo {\n id: string;\n name: string;\n gitRemote?: string;\n rootPath: string;\n}\n\n// ============================================================\n// Memorix Server Configuration\n// ============================================================\n\nexport interface MemorixConfig {\n dataDir: string;\n projectId: string;\n projectName: string;\n enableEmbeddings: boolean;\n enableRulesSync: boolean;\n watchRuleFiles: boolean;\n}\n\nexport const DEFAULT_CONFIG: Partial<MemorixConfig> = {\n enableEmbeddings: false,\n enableRulesSync: false,\n watchRuleFiles: false,\n};\n\n// ============================================================\n// Workspace Sync — Cross-Agent workspace migration\n// ============================================================\n\n/** Supported agent targets for workspace sync */\nexport type AgentTarget = 'windsurf' | 'cursor' | 'claude-code' | 'codex' | 'copilot' | 'antigravity' | 'kiro';\n\n/** A unified MCP server entry across all agent config formats */\nexport interface MCPServerEntry {\n name: string;\n /** Command for stdio transport */\n command: string;\n /** Args for stdio transport */\n args: string[];\n /** Environment variables */\n env?: Record<string, string> | null;\n /** URL for HTTP/SSE transport (Codex uses `url`, Windsurf uses `serverUrl`) */\n url?: string;\n /** HTTP headers (Windsurf uses `headers` for HTTP transport) */\n headers?: Record<string, string>;\n /** Whether this server is disabled */\n disabled?: boolean;\n}\n\n/** Unified workflow entry */\nexport interface WorkflowEntry {\n name: string;\n description: string;\n content: string;\n source: AgentTarget;\n filePath: string;\n}\n\n/** A skill folder discovered from an agent's skills directory */\nexport interface SkillEntry {\n name: string;\n description: string;\n sourcePath: string;\n sourceAgent: AgentTarget;\n}\n\n/** Conflict when two agents have a skill with the same folder name */\nexport interface SkillConflict {\n name: string;\n kept: SkillEntry;\n skipped: SkillEntry;\n}\n\n/** Result of a workspace sync operation */\nexport interface WorkspaceSyncResult {\n mcpServers: {\n scanned: MCPServerEntry[];\n generated: { filePath: string; content: string }[];\n };\n workflows: {\n scanned: WorkflowEntry[];\n generated: { filePath: string; content: string }[];\n };\n rules: {\n scanned: number;\n generated: number;\n };\n skills: {\n scanned: SkillEntry[];\n conflicts: SkillConflict[];\n copied: string[];\n skipped: string[];\n };\n}\n\n/** MCP config format adapter interface */\nexport interface MCPConfigAdapter {\n readonly source: AgentTarget;\n /** Parse MCP server entries from a config file */\n parse(content: string): MCPServerEntry[];\n /** Generate config file content from MCP server entries */\n generate(servers: MCPServerEntry[]): string;\n /** Get the default config file path for this agent */\n getConfigPath(projectRoot?: string): string;\n}\n","/**\n * FastEmbed Provider\n *\n * Local ONNX-based embedding using fastembed (Qdrant).\n * Model: BAAI/bge-small-en-v1.5 (384 dimensions, ~30MB)\n *\n * This is an optional dependency — if fastembed is not installed,\n * the provider module gracefully falls back to fulltext-only search.\n */\n\nimport type { EmbeddingProvider } from './provider.js';\n\n// Simple in-memory cache to avoid recomputing embeddings\nconst cache = new Map<string, number[]>();\nconst MAX_CACHE_SIZE = 5000;\n\nexport class FastEmbedProvider implements EmbeddingProvider {\n readonly name = 'fastembed-bge-small';\n readonly dimensions = 384;\n\n private model: { embed: (docs: string[], batchSize?: number) => AsyncGenerator<number[][]>; queryEmbed: (query: string) => Promise<number[]> };\n\n private constructor(model: FastEmbedProvider['model']) {\n this.model = model;\n }\n\n /**\n * Initialize the FastEmbed provider.\n * Downloads model on first use (~30MB), cached locally after.\n */\n static async create(): Promise<FastEmbedProvider> {\n // Dynamic import — throws if fastembed is not installed\n const { EmbeddingModel, FlagEmbedding } = await import('fastembed');\n const model = await FlagEmbedding.init({\n model: EmbeddingModel.BGESmallENV15,\n });\n return new FastEmbedProvider(model);\n }\n\n async embed(text: string): Promise<number[]> {\n // Check cache first\n const cached = cache.get(text);\n if (cached) return cached;\n\n const raw = await this.model.queryEmbed(text);\n // Ensure plain number[] (fastembed may return Float32Array)\n const result = Array.from(raw) as number[];\n if (result.length !== this.dimensions) {\n throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);\n }\n this.cacheSet(text, result);\n return result;\n }\n\n async embedBatch(texts: string[]): Promise<number[][]> {\n const results: number[][] = new Array(texts.length);\n const uncachedIndices: number[] = [];\n const uncachedTexts: string[] = [];\n\n // Check cache for each text\n for (let i = 0; i < texts.length; i++) {\n const cached = cache.get(texts[i]);\n if (cached) {\n results[i] = cached;\n } else {\n uncachedIndices.push(i);\n uncachedTexts.push(texts[i]);\n }\n }\n\n // Batch embed uncached texts\n if (uncachedTexts.length > 0) {\n let batchIdx = 0;\n for await (const batch of this.model.embed(uncachedTexts, 64)) {\n for (const vec of batch) {\n const originalIdx = uncachedIndices[batchIdx];\n const plain = Array.from(vec) as number[];\n results[originalIdx] = plain;\n this.cacheSet(uncachedTexts[batchIdx], plain);\n batchIdx++;\n }\n }\n }\n\n return results;\n }\n\n private cacheSet(key: string, value: number[]): void {\n // Evict oldest entries if cache is full\n if (cache.size >= MAX_CACHE_SIZE) {\n const firstKey = cache.keys().next().value;\n if (firstKey !== undefined) cache.delete(firstKey);\n }\n cache.set(key, value);\n }\n}\n","/**\r\n * Transformers.js Provider\r\n *\r\n * Pure JavaScript embedding using @huggingface/transformers (HuggingFace).\r\n * Model: Xenova/all-MiniLM-L6-v2 (384 dimensions, ~22MB quantized)\r\n *\r\n * Key advantages over fastembed:\r\n * - No native ONNX binding required (pure JS / WASM)\r\n * - Works out-of-the-box on Windows, macOS, Linux\r\n * - Supports quantized models (q8, q4) for smaller footprint\r\n *\r\n * This is an optional dependency — if @huggingface/transformers is not\r\n * installed, the provider module gracefully falls back to the next option.\r\n *\r\n * Inspired by Mem0's multi-provider embedding architecture.\r\n */\r\n\r\nimport type { EmbeddingProvider } from './provider.js';\r\n\r\n// In-memory LRU cache\r\nconst cache = new Map<string, number[]>();\r\nconst MAX_CACHE_SIZE = 5000;\r\n\r\nexport class TransformersProvider implements EmbeddingProvider {\r\n readonly name = 'transformers-minilm';\r\n readonly dimensions = 384;\r\n\r\n private extractor: any; // Pipeline instance\r\n\r\n private constructor(extractor: any) {\r\n this.extractor = extractor;\r\n }\r\n\r\n /**\r\n * Initialize the Transformers.js provider.\r\n * Downloads model on first use (~22MB quantized), cached locally after.\r\n */\r\n static async create(): Promise<TransformersProvider> {\r\n // Dynamic import — throws if @huggingface/transformers is not installed\r\n const { pipeline } = await import('@huggingface/transformers');\r\n const extractor = await pipeline(\r\n 'feature-extraction',\r\n 'Xenova/all-MiniLM-L6-v2',\r\n { dtype: 'q8' }, // Quantized for small footprint\r\n );\r\n return new TransformersProvider(extractor);\r\n }\r\n\r\n async embed(text: string): Promise<number[]> {\r\n // Check cache first\r\n const cached = cache.get(text);\r\n if (cached) return cached;\r\n\r\n const output = await this.extractor(text, {\r\n pooling: 'mean',\r\n normalize: true,\r\n });\r\n\r\n // output.tolist() returns [[...384 floats]]\r\n const result: number[] = Array.from(output.tolist()[0]);\r\n if (result.length !== this.dimensions) {\r\n throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);\r\n }\r\n\r\n this.cacheSet(text, result);\r\n return result;\r\n }\r\n\r\n async embedBatch(texts: string[]): Promise<number[][]> {\r\n const results: number[][] = new Array(texts.length);\r\n const uncachedIndices: number[] = [];\r\n const uncachedTexts: string[] = [];\r\n\r\n // Check cache for each text\r\n for (let i = 0; i < texts.length; i++) {\r\n const cached = cache.get(texts[i]);\r\n if (cached) {\r\n results[i] = cached;\r\n } else {\r\n uncachedIndices.push(i);\r\n uncachedTexts.push(texts[i]);\r\n }\r\n }\r\n\r\n // Batch embed uncached texts\r\n if (uncachedTexts.length > 0) {\r\n const output = await this.extractor(uncachedTexts, {\r\n pooling: 'mean',\r\n normalize: true,\r\n });\r\n const allVecs: number[][] = output.tolist();\r\n\r\n for (let i = 0; i < allVecs.length; i++) {\r\n const vec = Array.from(allVecs[i]) as number[];\r\n const originalIdx = uncachedIndices[i];\r\n results[originalIdx] = vec;\r\n this.cacheSet(uncachedTexts[i], vec);\r\n }\r\n }\r\n\r\n return results;\r\n }\r\n\r\n private cacheSet(key: string, value: number[]): void {\r\n if (cache.size >= MAX_CACHE_SIZE) {\r\n const firstKey = cache.keys().next().value;\r\n if (firstKey !== undefined) cache.delete(firstKey);\r\n }\r\n cache.set(key, value);\r\n }\r\n}\r\n","/**\n * Embedding Provider — Abstraction Layer\n *\n * Extensible embedding interface. Supports graceful degradation:\n * - fastembed installed → local ONNX inference (384-dim bge-small)\n * - @huggingface/transformers → pure JS WASM inference (384-dim MiniLM)\n * - nothing installed → null provider, search falls back to BM25\n *\n * Architecture inspired by Mem0's multi-provider embedding design.\n * Adding a new embedding backend only requires implementing EmbeddingProvider.\n */\n\nexport interface EmbeddingProvider {\n /** Provider name for logging/cache keys */\n readonly name: string;\n /** Vector dimensions (e.g., 384 for bge-small) */\n readonly dimensions: number;\n /** Generate embedding for a single text */\n embed(text: string): Promise<number[]>;\n /** Generate embeddings for multiple texts (batch) */\n embedBatch(texts: string[]): Promise<number[][]>;\n}\n\n/** Singleton provider instance (null = not available) */\nlet provider: EmbeddingProvider | null = null;\nlet initialized = false;\n\n/**\n * Get the embedding provider. Returns null if none available.\n * Lazy-initialized on first call.\n *\n * Provider priority:\n * 1. fastembed (fastest, but requires native ONNX binding)\n * 2. @huggingface/transformers (pure JS, best cross-platform compatibility)\n * 3. null → fulltext search only (BM25)\n */\nexport async function getEmbeddingProvider(): Promise<EmbeddingProvider | null> {\n if (initialized) return provider;\n initialized = true;\n\n // Try fastembed first (local ONNX, fastest)\n try {\n const { FastEmbedProvider } = await import('./fastembed-provider.js');\n provider = await FastEmbedProvider.create();\n console.error(`[memorix] Embedding provider: ${provider!.name} (${provider!.dimensions}d)`);\n return provider;\n } catch {\n // fastembed not installed — try next\n }\n\n // Try @huggingface/transformers (pure JS, no native deps)\n try {\n const { TransformersProvider } = await import('./transformers-provider.js');\n provider = await TransformersProvider.create();\n console.error(`[memorix] Embedding provider: ${provider!.name} (${provider!.dimensions}d)`);\n return provider;\n } catch {\n // transformers not installed — degrade to fulltext\n }\n\n console.error('[memorix] No embedding provider available — using fulltext search only');\n return null;\n}\n\n/**\n * Check if vector search is available.\n */\nexport async function isVectorSearchAvailable(): Promise<boolean> {\n const p = await getEmbeddingProvider();\n return p !== null;\n}\n\n/**\n * Reset provider (for testing).\n */\nexport function resetProvider(): void {\n provider = null;\n initialized = false;\n}\n","/**\n * Orama Store\n *\n * Full-text + vector + hybrid search engine backed by Orama.\n * Source: @orama/orama (10.1K stars, <2KB, pure JS, zero deps)\n *\n * Schema designed to store Observations with all searchable fields.\n * Vector search (embeddings) will be added in P1 phase.\n */\n\nimport { create, insert, search, remove, count, type AnyOrama } from '@orama/orama';\nimport type { MemorixDocument, SearchOptions, IndexEntry } from '../types.js';\nimport { OBSERVATION_ICONS, type ObservationType } from '../types.js';\nimport { getEmbeddingProvider, type EmbeddingProvider } from '../embedding/provider.js';\n\nlet db: AnyOrama | null = null;\nlet embeddingEnabled = false;\n\n/**\n * Initialize or return the Orama database instance.\n * Schema conditionally includes vector field based on embedding provider.\n * Graceful degradation: no provider → fulltext only, provider → hybrid.\n */\nexport async function getDb(): Promise<AnyOrama> {\n if (db) return db;\n\n // Check if embedding provider is available\n const provider = await getEmbeddingProvider();\n embeddingEnabled = provider !== null;\n\n const baseSchema = {\n id: 'string' as const,\n observationId: 'number' as const,\n entityName: 'string' as const,\n type: 'string' as const,\n title: 'string' as const,\n narrative: 'string' as const,\n facts: 'string' as const,\n filesModified: 'string' as const,\n concepts: 'string' as const,\n tokens: 'number' as const,\n createdAt: 'string' as const,\n projectId: 'string' as const,\n accessCount: 'number' as const,\n lastAccessedAt: 'string' as const,\n };\n\n const schema = embeddingEnabled\n ? { ...baseSchema, embedding: 'vector[384]' as const }\n : baseSchema;\n\n db = await create({ schema });\n\n return db;\n}\n\n/**\n * Reset the database instance (useful for testing).\n */\nexport async function resetDb(): Promise<void> {\n db = null;\n embeddingEnabled = false;\n}\n\n/**\n * Check if embedding/vector search is active.\n */\nexport function isEmbeddingEnabled(): boolean {\n return embeddingEnabled;\n}\n\n/**\n * Generate embedding for text content using the available provider.\n * Returns null if no provider is available.\n */\nexport async function generateEmbedding(text: string): Promise<number[] | null> {\n const provider = await getEmbeddingProvider();\n if (!provider) return null;\n return provider.embed(text);\n}\n\n/**\n * Insert an observation document into the store.\n */\nexport async function insertObservation(doc: MemorixDocument): Promise<void> {\n const database = await getDb();\n await insert(database, doc);\n}\n\n/**\n * Remove an observation document by its Orama internal ID.\n */\nexport async function removeObservation(oramaId: string): Promise<void> {\n const database = await getDb();\n await remove(database, oramaId);\n}\n\n/**\n * Search observations using Orama full-text search.\n * Returns L1 IndexEntry array (compact, ~50-100 tokens per result).\n *\n * Progressive Disclosure Layer 1 — adopted from claude-mem.\n */\nexport async function searchObservations(options: SearchOptions): Promise<IndexEntry[]> {\n const database = await getDb();\n\n const filters: Record<string, unknown> = {};\n if (options.projectId) {\n filters['projectId'] = options.projectId;\n }\n if (options.type) {\n filters['type'] = options.type;\n }\n\n // Determine search mode: hybrid (with vector) or fulltext (default)\n let searchParams: Record<string, unknown> = {\n term: options.query,\n limit: options.limit ?? 20,\n ...(Object.keys(filters).length > 0 ? { where: filters } : {}),\n };\n\n // If embedding provider is available and we have a query, use hybrid search\n if (embeddingEnabled && options.query && options.query.trim().length > 0) {\n try {\n const provider = await getEmbeddingProvider();\n if (provider) {\n const queryVector = await provider.embed(options.query);\n searchParams = {\n ...searchParams,\n mode: 'hybrid',\n vector: {\n value: queryVector,\n property: 'embedding',\n },\n similarity: 0.7,\n };\n }\n } catch {\n // Fallback to fulltext if embedding fails\n }\n }\n\n const results = await search(database, searchParams);\n\n let entries = results.hits.map((hit) => {\n const doc = hit.document as unknown as MemorixDocument;\n const obsType = doc.type as ObservationType;\n return {\n id: doc.observationId,\n time: formatTime(doc.createdAt),\n type: obsType,\n icon: OBSERVATION_ICONS[obsType] ?? '❓',\n title: doc.title,\n tokens: doc.tokens,\n };\n });\n\n // Apply token budget if specified (inspired by MemCP)\n if (options.maxTokens && options.maxTokens > 0) {\n entries = applyTokenBudget(entries, options.maxTokens);\n }\n\n // Record access for returned results (inspired by mcp-memory-service)\n const hitIds = results.hits.map((h) => (h.document as unknown as MemorixDocument).id);\n recordAccessBatch(hitIds).catch(() => {});\n\n return entries;\n}\n\n/**\n * Get full observation documents by their observation IDs.\n *\n * Progressive Disclosure Layer 3 — adopted from claude-mem.\n */\nexport async function getObservationsByIds(\n ids: number[],\n projectId?: string,\n): Promise<MemorixDocument[]> {\n const database = await getDb();\n\n // Search for each ID individually and collect results\n const results: MemorixDocument[] = [];\n\n for (const id of ids) {\n const searchResult = await search(database, {\n term: '',\n where: {\n observationId: { eq: id },\n ...(projectId ? { projectId } : {}),\n },\n limit: 1,\n });\n\n if (searchResult.hits.length > 0) {\n results.push(searchResult.hits[0].document as unknown as MemorixDocument);\n }\n }\n\n return results;\n}\n\n/**\n * Get observations around an anchor for timeline context.\n *\n * Progressive Disclosure Layer 2 — adopted from claude-mem.\n */\nexport async function getTimeline(\n anchorId: number,\n projectId?: string,\n depthBefore = 3,\n depthAfter = 3,\n): Promise<{ before: IndexEntry[]; anchor: IndexEntry | null; after: IndexEntry[] }> {\n const database = await getDb();\n\n // Get all observations sorted by time (no projectId filter — shared across agents)\n const searchParams: { term: string; where?: Record<string, unknown>; limit: number } = {\n term: '',\n limit: 1000,\n };\n if (projectId) {\n searchParams.where = { projectId };\n }\n const allResults = await search(database, searchParams);\n\n const docs = allResults.hits\n .map((h) => h.document as unknown as MemorixDocument)\n .sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n\n const anchorIndex = docs.findIndex((d) => d.observationId === anchorId);\n if (anchorIndex === -1) {\n return { before: [], anchor: null, after: [] };\n }\n\n const toIndexEntry = (doc: MemorixDocument): IndexEntry => {\n const obsType = doc.type as ObservationType;\n return {\n id: doc.observationId,\n time: formatTime(doc.createdAt),\n type: obsType,\n icon: OBSERVATION_ICONS[obsType] ?? '❓',\n title: doc.title,\n tokens: doc.tokens,\n };\n };\n\n const before = docs\n .slice(Math.max(0, anchorIndex - depthBefore), anchorIndex)\n .map(toIndexEntry);\n\n const after = docs\n .slice(anchorIndex + 1, anchorIndex + 1 + depthAfter)\n .map(toIndexEntry);\n\n return {\n before,\n anchor: toIndexEntry(docs[anchorIndex]),\n after,\n };\n}\n\n/**\n * Record access for observations returned in search results.\n * Increments accessCount and updates lastAccessedAt.\n * Inspired by mcp-memory-service's record_access() pattern.\n */\nasync function recordAccessBatch(oramaIds: string[]): Promise<void> {\n const database = await getDb();\n const now = new Date().toISOString();\n\n for (const id of oramaIds) {\n try {\n // Fetch current doc\n const result = await search(database, {\n term: '',\n where: { id },\n limit: 1,\n });\n if (result.hits.length === 0) continue;\n const doc = result.hits[0].document as unknown as MemorixDocument;\n\n // Remove and re-insert with updated access metadata\n await remove(database, id);\n await insert(database, {\n ...doc,\n accessCount: (doc.accessCount ?? 0) + 1,\n lastAccessedAt: now,\n });\n } catch {\n // Best-effort — don't break search if access tracking fails\n }\n }\n}\n\n/**\n * Trim search results to fit within a token budget.\n * Inspired by MemCP's _apply_token_budget() pattern.\n */\nfunction applyTokenBudget(entries: IndexEntry[], maxTokens: number): IndexEntry[] {\n const budgeted: IndexEntry[] = [];\n let tokensUsed = 0;\n\n for (const entry of entries) {\n if (tokensUsed + entry.tokens > maxTokens && budgeted.length > 0) {\n break;\n }\n budgeted.push(entry);\n tokensUsed += entry.tokens;\n }\n\n return budgeted;\n}\n\n/**\n * Get total observation count, optionally filtered by project.\n */\nexport async function getObservationCount(projectId?: string): Promise<number> {\n const database = await getDb();\n if (!projectId) {\n return await count(database);\n }\n const results = await search(database, {\n term: '',\n where: { projectId },\n limit: 0,\n });\n return results.count;\n}\n\n/**\n * Format ISO date string to compact time display.\n */\nfunction formatTime(isoDate: string): string {\n try {\n const date = new Date(isoDate);\n return date.toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n });\n } catch {\n return isoDate;\n }\n}\n","/**\n * Token Budget Manager\n *\n * Provides token counting and budget management for Progressive Disclosure.\n * Source: gpt-tokenizer (737 stars, JS port of OpenAI's tiktoken)\n *\n * Used by the Compact Engine to determine which layer of detail\n * fits within the caller's token budget.\n */\n\nimport { countTokens, isWithinTokenLimit } from 'gpt-tokenizer';\n\n/**\n * Count tokens in a string.\n */\nexport function countTextTokens(text: string): number {\n return countTokens(text);\n}\n\n/**\n * Check if text fits within a token limit.\n * Returns the token count if within limit, false otherwise.\n */\nexport function fitsInBudget(text: string, limit: number): number | false {\n return isWithinTokenLimit(text, limit);\n}\n\n/**\n * Truncate text to fit within a token budget.\n * Truncates at sentence boundaries when possible.\n */\nexport function truncateToTokenBudget(text: string, budget: number): string {\n if (fitsInBudget(text, budget) !== false) {\n return text;\n }\n\n // Binary search for the right length\n const sentences = text.split(/(?<=[.!?])\\s+/);\n let result = '';\n\n for (const sentence of sentences) {\n const candidate = result ? `${result} ${sentence}` : sentence;\n if (fitsInBudget(candidate, budget) === false) {\n break;\n }\n result = candidate;\n }\n\n // If no complete sentence fits, truncate by characters\n if (!result) {\n // Rough estimate: 1 token ≈ 4 chars for English, ≈ 1.5 chars for Chinese\n const estimatedChars = budget * 2;\n result = text.slice(0, estimatedChars);\n // Refine\n while (fitsInBudget(result, budget) === false && result.length > 0) {\n result = result.slice(0, Math.floor(result.length * 0.9));\n }\n if (result.length < text.length) {\n result += '...';\n }\n }\n\n return result;\n}\n\n/**\n * Estimate the token cost of an IndexEntry line.\n * Used to predict compact index size.\n */\nexport function estimateIndexEntryTokens(title: string): number {\n // Format: \"| #ID | Time | Icon | Title | ~Tokens |\"\n // Overhead is roughly 15 tokens for formatting\n return countTextTokens(title) + 15;\n}\n","/**\n * Entity Extractor\n *\n * Regex-based entity extraction from observation content.\n * Inspired by MemCP's RegexEntityExtractor (MAGMA paper).\n *\n * Extracts: file paths, module paths, URLs, @mentions, CamelCase identifiers.\n * Also detects causal patterns for automatic edge typing.\n */\n\nconst ENTITY_PATTERNS: Array<{ kind: string; pattern: RegExp }> = [\n // File paths (e.g. src/auth/jwt.ts, ./config.json)\n { kind: 'file', pattern: /(?:^|[\\s\"'(])([.\\w/-]+\\.\\w{1,10})(?:[\\s\"'),]|$)/g },\n // Module/package paths (e.g. @orama/orama, memcp.core.graph)\n { kind: 'module', pattern: /(?:^|[\\s\"'(,])(@[\\w-]+\\/[\\w.-]+)|\\b([a-zA-Z_]\\w*(?:\\.[a-zA-Z_]\\w*){2,})\\b/g },\n // URLs\n { kind: 'url', pattern: /https?:\\/\\/[^\\s\"'<>)]+/g },\n // @mentions\n { kind: 'mention', pattern: /@([a-zA-Z_]\\w+)/g },\n // CamelCase identifiers (likely class/type names)\n { kind: 'identifier', pattern: /\\b([A-Z][a-z]+(?:[A-Z][a-z]+)+)\\b/g },\n];\n\n/**\n * Patterns that indicate causal relationships.\n * Used to auto-detect causal edge types in Knowledge Graph.\n */\nconst CAUSAL_PATTERN = /\\b(?:because|therefore|due to|caused by|as a result|decided to|chosen because|so that|in order to|leads to|results in|fixed by|resolved by)\\b/i;\n\nexport interface ExtractedEntities {\n files: string[];\n modules: string[];\n urls: string[];\n mentions: string[];\n identifiers: string[];\n hasCausalLanguage: boolean;\n}\n\n/**\n * Extract entities from text content.\n * Returns deduplicated lists of each entity type.\n */\nexport function extractEntities(content: string): ExtractedEntities {\n const result: ExtractedEntities = {\n files: [],\n modules: [],\n urls: [],\n mentions: [],\n identifiers: [],\n hasCausalLanguage: false,\n };\n\n const seen = new Set<string>();\n\n for (const { kind, pattern } of ENTITY_PATTERNS) {\n // Reset lastIndex for global regexes\n pattern.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(content)) !== null) {\n const entity = (match[1] ?? match[2] ?? match[0]).trim().replace(/^[\"'(]+|[\"'),]+$/g, '');\n if (entity.length < 3 || (kind === 'file' && entity.length < 5)) continue;\n\n const key = `${kind}:${entity.toLowerCase()}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n switch (kind) {\n case 'file':\n result.files.push(entity);\n break;\n case 'module':\n result.modules.push(entity);\n break;\n case 'url':\n result.urls.push(entity);\n break;\n case 'mention':\n result.mentions.push(entity);\n break;\n case 'identifier':\n result.identifiers.push(entity);\n break;\n }\n }\n }\n\n result.hasCausalLanguage = CAUSAL_PATTERN.test(content);\n\n return result;\n}\n\n/**\n * Auto-generate concepts from extracted entities.\n * Merges with any user-provided concepts.\n */\nexport function enrichConcepts(\n userConcepts: string[],\n extracted: ExtractedEntities,\n): string[] {\n const all = new Set(userConcepts.map((c) => c.toLowerCase()));\n const enriched = [...userConcepts];\n\n // Add file names (without path) as concepts\n for (const f of extracted.files) {\n const name = f.split('/').pop()?.replace(/\\.\\w+$/, '') ?? '';\n if (name.length >= 3 && !all.has(name.toLowerCase())) {\n all.add(name.toLowerCase());\n enriched.push(name);\n }\n }\n\n // Add module names as concepts\n for (const m of extracted.modules) {\n const short = m.split(/[./]/).pop() ?? '';\n if (short.length >= 3 && !all.has(short.toLowerCase())) {\n all.add(short.toLowerCase());\n enriched.push(short);\n }\n }\n\n // Add CamelCase identifiers as concepts\n for (const id of extracted.identifiers) {\n if (!all.has(id.toLowerCase())) {\n all.add(id.toLowerCase());\n enriched.push(id);\n }\n }\n\n return enriched;\n}\n","/**\n * Observations Manager\n *\n * Manages rich observation records with auto-classification and token counting.\n * Source: claude-mem's observation data model with structured fields.\n *\n * Each observation is stored both in the knowledge graph (as entity observation)\n * and in the Orama search index (for full-text + vector search).\n */\n\nimport type { Observation, ObservationType, MemorixDocument } from '../types.js';\nimport { insertObservation, generateEmbedding, isEmbeddingEnabled } from '../store/orama-store.js';\nimport { saveObservationsJson, loadObservationsJson, saveIdCounter, loadIdCounter } from '../store/persistence.js';\nimport { countTextTokens } from '../compact/token-budget.js';\nimport { extractEntities, enrichConcepts } from './entity-extractor.js';\n\n/** In-memory observation list (loaded from persistence on init) */\nlet observations: Observation[] = [];\nlet nextId = 1;\nlet projectDir: string | null = null;\n\n/**\n * Initialize the observations manager with a project directory.\n */\nexport async function initObservations(dir: string): Promise<void> {\n projectDir = dir;\n const loaded = await loadObservationsJson(dir);\n observations = loaded as Observation[];\n nextId = await loadIdCounter(dir);\n}\n\n/**\n * Store a new observation.\n *\n * This is the primary write API — called by the `memorix_store` MCP tool.\n * Automatically:\n * 1. Assigns an incremental ID\n * 2. Counts tokens for the observation content\n * 3. Inserts into Orama for full-text search\n * 4. Persists to disk\n */\nexport async function storeObservation(input: {\n entityName: string;\n type: ObservationType;\n title: string;\n narrative: string;\n facts?: string[];\n filesModified?: string[];\n concepts?: string[];\n projectId: string;\n}): Promise<Observation> {\n const id = nextId++;\n const now = new Date().toISOString();\n\n // Auto-extract entities from narrative (inspired by MemCP RegexEntityExtractor)\n const contentForExtraction = [input.title, input.narrative, ...(input.facts ?? [])].join(' ');\n const extracted = extractEntities(contentForExtraction);\n\n // Auto-enrich concepts with extracted entities\n const enrichedConcepts = enrichConcepts(input.concepts ?? [], extracted);\n\n // Auto-enrich filesModified with extracted file paths\n const userFiles = new Set((input.filesModified ?? []).map((f) => f.toLowerCase()));\n const enrichedFiles = [...(input.filesModified ?? [])];\n for (const f of extracted.files) {\n if (!userFiles.has(f.toLowerCase())) {\n enrichedFiles.push(f);\n }\n }\n\n // Count tokens for the full observation content\n const fullText = [\n input.title,\n input.narrative,\n ...(input.facts ?? []),\n ...enrichedFiles,\n ...enrichedConcepts,\n ].join(' ');\n const tokens = countTextTokens(fullText);\n\n const observation: Observation = {\n id,\n entityName: input.entityName,\n type: input.type,\n title: input.title,\n narrative: input.narrative,\n facts: input.facts ?? [],\n filesModified: enrichedFiles,\n concepts: enrichedConcepts,\n tokens,\n createdAt: now,\n projectId: input.projectId,\n hasCausalLanguage: extracted.hasCausalLanguage,\n };\n\n observations.push(observation);\n\n // Generate embedding if provider is available (graceful degradation)\n const searchableText = [input.title, input.narrative, ...(input.facts ?? [])].join(' ');\n const embedding = await generateEmbedding(searchableText);\n\n // Insert into Orama search index\n const doc: MemorixDocument = {\n id: `obs-${id}`,\n observationId: id,\n entityName: input.entityName,\n type: input.type,\n title: input.title,\n narrative: input.narrative,\n facts: (input.facts ?? []).join('\\n'),\n filesModified: enrichedFiles.join('\\n'),\n concepts: enrichedConcepts.join(', '),\n tokens,\n createdAt: now,\n projectId: input.projectId,\n accessCount: 0,\n lastAccessedAt: '',\n ...(embedding ? { embedding } : {}),\n };\n\n await insertObservation(doc);\n\n // Persist to disk\n if (projectDir) {\n await saveObservationsJson(projectDir, observations);\n await saveIdCounter(projectDir, nextId);\n }\n\n return observation;\n}\n\n/**\n * Get an observation by ID.\n */\nexport function getObservation(id: number): Observation | undefined {\n return observations.find((o) => o.id === id);\n}\n\n/**\n * Get all observations for a project.\n */\nexport function getProjectObservations(projectId: string): Observation[] {\n return observations.filter((o) => o.projectId === projectId);\n}\n\n/**\n * Get the total number of stored observations.\n */\nexport function getObservationCount(): number {\n return observations.length;\n}\n\n/**\n * Reload observations into the Orama index.\n * Called during server startup to restore the search index.\n */\nexport async function reindexObservations(): Promise<number> {\n let count = 0;\n for (const obs of observations) {\n try {\n // Generate embedding during reindex if provider is available\n let embedding: number[] | null = null;\n if (isEmbeddingEnabled()) {\n try {\n const searchableText = [obs.title, obs.narrative, ...obs.facts].join(' ');\n embedding = await generateEmbedding(searchableText);\n } catch {\n // Embedding generation failed for this observation — skip vector, use fulltext\n }\n }\n\n const doc: MemorixDocument = {\n id: `obs-${obs.id}`,\n observationId: obs.id,\n entityName: obs.entityName,\n type: obs.type,\n title: obs.title,\n narrative: obs.narrative,\n facts: obs.facts.join('\\n'),\n filesModified: obs.filesModified.join('\\n'),\n concepts: obs.concepts.join(', '),\n tokens: obs.tokens,\n createdAt: obs.createdAt,\n projectId: obs.projectId,\n accessCount: 0,\n lastAccessedAt: '',\n ...(embedding ? { embedding } : {}),\n };\n await insertObservation(doc);\n count++;\n } catch (err) {\n console.error(`[memorix] Failed to reindex observation #${obs.id}: ${err}`);\n }\n }\n return count;\n}\n","/**\n * Auto-Relation Creator\n *\n * Automatically creates Knowledge Graph relations from entity extraction.\n * Inspired by mcp-memory-service's typed relationships and MemCP's MAGMA 4-graph.\n *\n * When an observation is stored:\n * 1. Extract entities from narrative (files, modules, CamelCase)\n * 2. Find matching existing entities in the graph\n * 3. Auto-create relations: \"references\", \"modifies\", or \"causes\" (if causal)\n *\n * This is \"implicit memory\" — the agent doesn't need to call create_relations.\n */\n\nimport type { Observation, Relation } from '../types.js';\nimport type { KnowledgeGraphManager } from './graph.js';\nimport type { ExtractedEntities } from './entity-extractor.js';\n\n/**\n * Infer relation type based on observation type and causal language.\n */\nfunction inferRelationType(obs: Observation): string {\n if (obs.hasCausalLanguage) return 'causes';\n\n switch (obs.type) {\n case 'problem-solution':\n return 'fixes';\n case 'decision':\n case 'trade-off':\n return 'decides';\n case 'what-changed':\n return 'modifies';\n case 'gotcha':\n return 'warns_about';\n default:\n return 'references';\n }\n}\n\n/**\n * Auto-create relations from a stored observation.\n *\n * Scans the knowledge graph for entities matching extracted file names,\n * modules, and identifiers, then creates typed relations.\n *\n * Returns the number of relations created.\n */\nexport async function createAutoRelations(\n obs: Observation,\n extracted: ExtractedEntities,\n graphManager: KnowledgeGraphManager,\n): Promise<number> {\n const relationType = inferRelationType(obs);\n const relations: Relation[] = [];\n\n // Get all existing entity names from the graph\n const graph = await graphManager.readGraph();\n const existingNames = new Set(graph.entities.map((e) => e.name.toLowerCase()));\n\n // Skip self-references\n const selfName = obs.entityName.toLowerCase();\n\n // Check extracted identifiers against existing entities\n const candidates = [\n ...extracted.identifiers,\n ...extracted.files.map((f) => f.split('/').pop()?.replace(/\\.\\w+$/, '') ?? ''),\n ...extracted.modules.map((m) => m.split(/[./]/).pop() ?? ''),\n ].filter((c) => c.length >= 3);\n\n for (const candidate of candidates) {\n const lower = candidate.toLowerCase();\n if (lower === selfName) continue;\n\n // Find matching entity (case-insensitive)\n const matchedEntity = graph.entities.find(\n (e) => e.name.toLowerCase() === lower,\n );\n\n if (matchedEntity) {\n relations.push({\n from: obs.entityName,\n to: matchedEntity.name,\n relationType,\n });\n }\n }\n\n // Also create relations from explicit filesModified → existing entities\n for (const file of obs.filesModified) {\n const basename = file.split('/').pop()?.replace(/\\.\\w+$/, '') ?? '';\n if (basename.length < 3 || basename.toLowerCase() === selfName) continue;\n\n const matchedEntity = graph.entities.find(\n (e) => e.name.toLowerCase() === basename.toLowerCase(),\n );\n\n if (matchedEntity) {\n relations.push({\n from: obs.entityName,\n to: matchedEntity.name,\n relationType: 'modifies',\n });\n }\n }\n\n if (relations.length === 0) return 0;\n\n // Deduplicate\n const unique = relations.filter(\n (r, i, arr) =>\n arr.findIndex(\n (o) => o.from === r.from && o.to === r.to && o.relationType === r.relationType,\n ) === i,\n );\n\n const created = await graphManager.createRelations(unique);\n return created.length;\n}\n","/**\n * Index Formatter\n *\n * Formats observation search results into the compact index table format.\n * Source: claude-mem's Progressive Disclosure index format.\n *\n * Output is a markdown table that agents can scan efficiently:\n * | ID | Time | T | Title | Tokens |\n * |-------|----------|----|--------------------------|--------|\n * | #42 | 2:14 PM | 🔴 | port 3001 conflict fix | ~155 |\n */\n\nimport type { IndexEntry, TimelineContext } from '../types.js';\n\n/**\n * Format a list of IndexEntries as a compact markdown table.\n * Grouped by date for readability (claude-mem pattern).\n */\nexport function formatIndexTable(entries: IndexEntry[], query?: string): string {\n if (entries.length === 0) {\n return query\n ? `No observations found matching \"${query}\".`\n : 'No observations found.';\n }\n\n const lines: string[] = [];\n\n if (query) {\n lines.push(`Found ${entries.length} observation(s) matching \"${query}\":\\n`);\n }\n\n lines.push('| ID | Time | T | Title | Tokens |');\n lines.push('|----|------|---|-------|--------|');\n\n for (const entry of entries) {\n lines.push(\n `| #${entry.id} | ${entry.time} | ${entry.icon} | ${entry.title} | ~${entry.tokens} |`,\n );\n }\n\n lines.push('');\n lines.push(PROGRESSIVE_DISCLOSURE_HINT);\n\n return lines.join('\\n');\n}\n\n/**\n * Format a timeline context around an anchor observation.\n */\nexport function formatTimeline(timeline: TimelineContext): string {\n if (!timeline.anchorEntry) {\n return `Observation #${timeline.anchorId} not found.`;\n }\n\n const lines: string[] = [];\n lines.push(`Timeline around #${timeline.anchorId}:\\n`);\n\n if (timeline.before.length > 0) {\n lines.push('**Before:**');\n lines.push('| ID | Time | T | Title | Tokens |');\n lines.push('|----|------|---|-------|--------|');\n for (const entry of timeline.before) {\n lines.push(`| #${entry.id} | ${entry.time} | ${entry.icon} | ${entry.title} | ~${entry.tokens} |`);\n }\n lines.push('');\n }\n\n lines.push('**► Anchor:**');\n lines.push('| ID | Time | T | Title | Tokens |');\n lines.push('|----|------|---|-------|--------|');\n const a = timeline.anchorEntry;\n lines.push(`| #${a.id} | ${a.time} | ${a.icon} | ${a.title} | ~${a.tokens} |`);\n lines.push('');\n\n if (timeline.after.length > 0) {\n lines.push('**After:**');\n lines.push('| ID | Time | T | Title | Tokens |');\n lines.push('|----|------|---|-------|--------|');\n for (const entry of timeline.after) {\n lines.push(`| #${entry.id} | ${entry.time} | ${entry.icon} | ${entry.title} | ~${entry.tokens} |`);\n }\n lines.push('');\n }\n\n lines.push(PROGRESSIVE_DISCLOSURE_HINT);\n return lines.join('\\n');\n}\n\n/**\n * Format full observation details (Layer 3).\n * Adopted from claude-mem's observation detail format.\n */\nexport function formatObservationDetail(doc: {\n observationId: number;\n type: string;\n title: string;\n narrative: string;\n facts: string;\n filesModified: string;\n concepts: string;\n createdAt: string;\n projectId: string;\n entityName: string;\n}): string {\n const icon = getTypeIcon(doc.type);\n const lines: string[] = [];\n\n lines.push(`#${doc.observationId} ${icon} ${doc.title}`);\n lines.push('─'.repeat(50));\n lines.push(`Date: ${new Date(doc.createdAt).toLocaleString()}`);\n lines.push(`Type: ${doc.type}`);\n lines.push(`Entity: ${doc.entityName}`);\n lines.push(`Project: ${doc.projectId}`);\n lines.push('');\n lines.push(`Narrative: ${doc.narrative}`);\n\n const facts = doc.facts ? doc.facts.split('\\n').filter(Boolean) : [];\n if (facts.length > 0) {\n lines.push('');\n lines.push('Facts:');\n for (const fact of facts) {\n lines.push(`- ${fact}`);\n }\n }\n\n const files = doc.filesModified ? doc.filesModified.split('\\n').filter(Boolean) : [];\n if (files.length > 0) {\n lines.push('');\n lines.push('Files Modified:');\n for (const file of files) {\n lines.push(`- ${file}`);\n }\n }\n\n if (doc.concepts) {\n lines.push('');\n lines.push(`Concepts: ${doc.concepts}`);\n }\n\n return lines.join('\\n');\n}\n\n/** Icon lookup by observation type string */\nfunction getTypeIcon(type: string): string {\n const icons: Record<string, string> = {\n 'session-request': '🎯',\n 'gotcha': '🔴',\n 'problem-solution': '🟡',\n 'how-it-works': '🔵',\n 'what-changed': '🟢',\n 'discovery': '🟣',\n 'why-it-exists': '🟠',\n 'decision': '🟤',\n 'trade-off': '⚖️',\n };\n return icons[type] ?? '❓';\n}\n\n/**\n * Progressive Disclosure instruction hint.\n * Appended to L1/L2 results to teach the agent the workflow.\n */\nconst PROGRESSIVE_DISCLOSURE_HINT = `💡 **Progressive Disclosure:** This index shows WHAT exists and retrieval COST.\n- Use \\`memorix_detail\\` to fetch full observation details by ID\n- Use \\`memorix_timeline\\` to see chronological context around an observation\n- Critical types (🔴 gotcha, 🟤 decision, ⚖️ trade-off) are often worth fetching immediately`;\n","/**\n * Compact Engine\n *\n * Orchestrates the 3-layer Progressive Disclosure workflow.\n * Source: claude-mem's proven architecture (27K stars, ~10x token savings).\n *\n * Layer 1 (search) → Compact index with IDs (~50-100 tokens/result)\n * Layer 2 (timeline) → Chronological context around an observation\n * Layer 3 (detail) → Full observation content (~500-1000 tokens/result)\n */\n\nimport type { SearchOptions, IndexEntry, TimelineContext, MemorixDocument } from '../types.js';\nimport { searchObservations, getTimeline } from '../store/orama-store.js';\nimport { getObservation } from '../memory/observations.js';\nimport { formatIndexTable, formatTimeline, formatObservationDetail } from './index-format.js';\nimport { countTextTokens } from './token-budget.js';\n\n/**\n * Layer 1: Search and return a compact index.\n * Agent scans this to decide which observations to fetch in detail.\n */\nexport async function compactSearch(options: SearchOptions): Promise<{\n entries: IndexEntry[];\n formatted: string;\n totalTokens: number;\n}> {\n const entries = await searchObservations(options);\n const formatted = formatIndexTable(entries, options.query);\n const totalTokens = countTextTokens(formatted);\n\n return { entries, formatted, totalTokens };\n}\n\n/**\n * Layer 2: Get timeline context around an anchor observation.\n * Shows what happened before and after for temporal understanding.\n */\nexport async function compactTimeline(\n anchorId: number,\n projectId?: string,\n depthBefore = 3,\n depthAfter = 3,\n): Promise<{\n timeline: TimelineContext;\n formatted: string;\n totalTokens: number;\n}> {\n const result = await getTimeline(anchorId, projectId, depthBefore, depthAfter);\n\n const timeline: TimelineContext = {\n anchorId,\n anchorEntry: result.anchor,\n before: result.before,\n after: result.after,\n };\n\n const formatted = formatTimeline(timeline);\n const totalTokens = countTextTokens(formatted);\n\n return { timeline, formatted, totalTokens };\n}\n\n/**\n * Layer 3: Get full observation details by IDs.\n * Only called after the agent has filtered via L1/L2.\n */\nexport async function compactDetail(\n ids: number[],\n): Promise<{\n documents: MemorixDocument[];\n formatted: string;\n totalTokens: number;\n}> {\n // Use in-memory observations for reliable ID lookup (Orama where-clause\n // can be unreliable with empty term + number filter)\n const documents: MemorixDocument[] = [];\n for (const id of ids) {\n const obs = getObservation(id);\n if (obs) {\n documents.push({\n id: `obs-${obs.id}`,\n observationId: obs.id,\n entityName: obs.entityName,\n type: obs.type,\n title: obs.title,\n narrative: obs.narrative,\n facts: obs.facts.join('\\n'),\n filesModified: obs.filesModified.join('\\n'),\n concepts: obs.concepts.join(', '),\n tokens: obs.tokens,\n createdAt: obs.createdAt,\n projectId: obs.projectId,\n accessCount: 0,\n lastAccessedAt: '',\n });\n }\n }\n\n const formattedParts = documents.map((doc: MemorixDocument) =>\n formatObservationDetail(doc),\n );\n\n const formatted = formattedParts.join('\\n\\n' + '═'.repeat(50) + '\\n\\n');\n const totalTokens = countTextTokens(formatted);\n\n return { documents, formatted, totalTokens };\n}\n","/**\n * Project Detector\n *\n * Identifies the current project using Git remote URL.\n * Source: shared-agent-memory's Git-based project isolation pattern.\n *\n * Extensible: fallback strategies can be added for non-git projects\n * (e.g., package.json name, directory name, etc.)\n */\n\nimport { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport type { ProjectInfo } from '../types.js';\n\n/**\n * Detect the current project identity from Git remote or fallback.\n * @param cwd - Working directory to detect from (defaults to process.cwd())\n */\nexport function detectProject(cwd?: string): ProjectInfo {\n const basePath = cwd ?? process.cwd();\n // Priority: git root > package.json dir > CWD\n const rootPath = getGitRoot(basePath) ?? findPackageRoot(basePath) ?? basePath;\n const gitRemote = getGitRemote(rootPath);\n\n if (gitRemote) {\n const id = normalizeGitRemote(gitRemote);\n const name = id.split('/').pop() ?? path.basename(rootPath);\n return { id, name, gitRemote, rootPath };\n }\n\n // Validate the root before creating a fallback project.\n // This prevents home dirs, system dirs, and IDE config dirs from\n // becoming phantom projects with garbage data directories.\n if (!isValidProjectRoot(rootPath)) {\n // Use a generic sentinel ID — data will NOT be persisted\n console.error(`[memorix] Skipped invalid project root: ${rootPath}`);\n return { id: '__invalid__', name: 'unknown', rootPath };\n }\n\n // Fallback: use \"local/<dirname>\" to distinguish non-git projects\n const name = path.basename(rootPath);\n const id = `local/${name}`;\n console.error(`[memorix] Warning: no git remote found at ${rootPath}, using fallback projectId: ${id}`);\n return { id, name, rootPath };\n}\n\n/**\n * Check whether a directory looks like a real project root.\n * Returns false for home directories, OS system directories,\n * drive roots, and IDE/tool configuration directories.\n */\nfunction isValidProjectRoot(dirPath: string): boolean {\n const resolved = path.resolve(dirPath);\n const home = path.resolve(os.homedir());\n\n // Reject the home directory itself (e.g., C:\\Users\\Lenovo, /home/user)\n if (resolved === home) return false;\n\n // Reject drive roots (C:\\, D:\\, /)\n if (resolved === path.parse(resolved).root) return false;\n\n // Reject immediate children of home that are IDE/tool config dirs\n const basename = path.basename(resolved).toLowerCase();\n const knownNonProjectDirs = new Set([\n // IDE / editor config dirs\n '.vscode', '.cursor', '.windsurf', '.kiro', '.codex',\n '.gemini', '.claude', '.github', '.git',\n // OS / system dirs\n 'desktop', 'documents', 'downloads', 'pictures', 'videos', 'music',\n 'appdata', 'application data', 'library',\n // Package manager / tool dirs\n 'node_modules', '.npm', '.yarn', '.pnpm-store',\n '.config', '.local', '.cache', '.ssh', '.memorix',\n ]);\n if (knownNonProjectDirs.has(basename)) {\n const parent = path.resolve(path.dirname(resolved));\n // Only block if it's directly under home or a drive root\n if (parent === home || parent === path.parse(parent).root) {\n return false;\n }\n }\n\n // Must have at least ONE project indicator file\n const projectIndicators = [\n 'package.json', 'Cargo.toml', 'go.mod', 'pyproject.toml',\n 'setup.py', 'pom.xml', 'build.gradle', 'Makefile',\n 'CMakeLists.txt', 'composer.json', 'Gemfile',\n '.git', 'README.md', 'README',\n ];\n return projectIndicators.some(f => existsSync(path.join(resolved, f)));\n}\n\n/**\n * Walk up from cwd to find the nearest directory containing package.json.\n * Useful for non-git projects where the MCP server CWD may differ from project root.\n */\nfunction findPackageRoot(cwd: string): string | null {\n let dir = path.resolve(cwd);\n const root = path.parse(dir).root;\n while (dir !== root) {\n if (existsSync(path.join(dir, 'package.json'))) {\n return dir;\n }\n dir = path.dirname(dir);\n }\n return null;\n}\n\n/**\n * Get the Git repository root directory.\n * Returns null if not inside a git repository.\n */\nfunction getGitRoot(cwd: string): string | null {\n try {\n const root = execSync('git rev-parse --show-toplevel', {\n cwd,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n return root || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get the Git remote URL for the given directory.\n * Returns null if not a git repository or no remote configured.\n */\nfunction getGitRemote(cwd: string): string | null {\n try {\n const remote = execSync('git remote get-url origin', {\n cwd,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n return remote || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Normalize a Git remote URL to a consistent project ID.\n *\n * Examples:\n * https://github.com/user/repo.git → user/repo\n * git@github.com:user/repo.git → user/repo\n * ssh://git@github.com/user/repo → user/repo\n */\nfunction normalizeGitRemote(remote: string): string {\n let normalized = remote;\n\n // Remove trailing .git\n normalized = normalized.replace(/\\.git$/, '');\n\n // Handle SSH format: git@github.com:user/repo\n const sshMatch = normalized.match(/^[\\w-]+@[\\w.-]+:(.+)$/);\n if (sshMatch) {\n return sshMatch[1];\n }\n\n // Handle HTTPS/SSH URL format\n try {\n const url = new URL(normalized);\n // Remove leading slash\n return url.pathname.replace(/^\\//, '');\n } catch {\n // If URL parsing fails, take last two segments\n const segments = normalized.split('/').filter(Boolean);\n return segments.slice(-2).join('/');\n }\n}\n","/**\n * Rules Utilities\n *\n * Shared helpers for rule parsing: content hashing, ID generation, etc.\n */\n\nimport { createHash } from 'node:crypto';\n\n/** Generate a deterministic content hash for deduplication */\nexport function hashContent(content: string): string {\n return createHash('sha256')\n .update(content.trim())\n .digest('hex')\n .substring(0, 16);\n}\n\n/** Generate a rule ID from source + file path */\nexport function generateRuleId(source: string, filePath: string): string {\n const sanitized = filePath.replace(/[\\/\\\\]/g, '-').replace(/^\\./, '');\n return `${source}:${sanitized}`;\n}\n","/**\n * Cursor Rule Format Adapter\n *\n * Parses and generates rules in Cursor's formats:\n * - .cursor/rules/*.mdc (Markdown + frontmatter with description, alwaysApply, globs)\n * - .cursorrules (legacy plain text)\n * - AGENTS.md (pure Markdown)\n *\n * Source: Cursor official documentation on Project Rules.\n */\n\nimport matter from 'gray-matter';\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\nimport { hashContent, generateRuleId } from '../utils.js';\n\nexport class CursorAdapter implements RuleFormatAdapter {\n readonly source: RuleSource = 'cursor';\n\n readonly filePatterns = [\n '.cursor/rules/*.mdc',\n '.cursorrules',\n 'AGENTS.md',\n ];\n\n parse(filePath: string, content: string): UnifiedRule[] {\n if (filePath.endsWith('.mdc')) {\n return this.parseMdc(filePath, content);\n }\n if (filePath === '.cursorrules' || filePath.endsWith('/.cursorrules')) {\n return this.parseLegacy(filePath, content);\n }\n if (filePath.endsWith('AGENTS.md')) {\n return this.parseAgentsMd(filePath, content);\n }\n return [];\n }\n\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\n return rules.map((rule, i) => {\n const fm: Record<string, unknown> = {};\n if (rule.description) fm.description = rule.description;\n if (rule.alwaysApply !== undefined) fm.alwaysApply = rule.alwaysApply;\n if (rule.paths && rule.paths.length > 0) fm.globs = rule.paths;\n\n const fileName = rule.id\n .replace(/^cursor:/, '')\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n || `rule-${i}`;\n\n const body = Object.keys(fm).length > 0\n ? matter.stringify(rule.content, fm)\n : rule.content;\n\n return {\n filePath: `.cursor/rules/${fileName}.mdc`,\n content: body,\n };\n });\n }\n\n private parseMdc(filePath: string, content: string): UnifiedRule[] {\n const { data, content: body } = matter(content);\n const trimmed = body.trim();\n if (!trimmed) return [];\n\n const globs = data.globs as string[] | undefined;\n const hasGlobs = Array.isArray(globs) && globs.length > 0;\n const alwaysApply = data.alwaysApply === true;\n\n let scope: UnifiedRule['scope'] = 'project';\n if (alwaysApply) scope = 'global';\n else if (hasGlobs) scope = 'path-specific';\n\n return [{\n id: generateRuleId('cursor', filePath),\n content: trimmed,\n description: data.description as string | undefined,\n source: 'cursor',\n scope,\n paths: hasGlobs ? globs : undefined,\n alwaysApply,\n priority: alwaysApply ? 10 : 5,\n hash: hashContent(trimmed),\n }];\n }\n\n private parseLegacy(filePath: string, content: string): UnifiedRule[] {\n const trimmed = content.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('cursor', filePath),\n content: trimmed,\n source: 'cursor',\n scope: 'project',\n priority: 3,\n hash: hashContent(trimmed),\n }];\n }\n\n private parseAgentsMd(filePath: string, content: string): UnifiedRule[] {\n const trimmed = content.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('cursor', filePath),\n content: trimmed,\n source: 'cursor',\n scope: 'project',\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n}\n","/**\n * Claude Code Rule Format Adapter\n *\n * Parses and generates rules in Claude Code's formats:\n * - CLAUDE.md / .claude/CLAUDE.md (project-level Markdown)\n * - .claude/rules/*.md (Markdown with optional `paths` frontmatter)\n *\n * Source: Claude Code official documentation.\n */\n\nimport matter from 'gray-matter';\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\nimport { hashContent, generateRuleId } from '../utils.js';\n\nexport class ClaudeCodeAdapter implements RuleFormatAdapter {\n readonly source: RuleSource = 'claude-code';\n\n readonly filePatterns = [\n 'CLAUDE.md',\n '.claude/CLAUDE.md',\n '.claude/rules/*.md',\n ];\n\n parse(filePath: string, content: string): UnifiedRule[] {\n // .claude/rules/*.md may have `paths` frontmatter\n if (filePath.includes('.claude/rules/')) {\n return this.parseModularRule(filePath, content);\n }\n // CLAUDE.md — project-level\n return this.parseClaudeMd(filePath, content);\n }\n\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\n const projectRules = rules.filter(r => r.scope !== 'path-specific');\n const pathRules = rules.filter(r => r.scope === 'path-specific');\n\n const files: { filePath: string; content: string }[] = [];\n\n if (projectRules.length > 0) {\n files.push({\n filePath: 'CLAUDE.md',\n content: projectRules.map(r => r.content).join('\\n\\n'),\n });\n }\n\n for (const rule of pathRules) {\n const fm: Record<string, unknown> = {};\n if (rule.paths && rule.paths.length > 0) fm.paths = rule.paths;\n\n const fileName = rule.id\n .replace(/^claude-code:/, '')\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n || 'rule';\n\n files.push({\n filePath: `.claude/rules/${fileName}.md`,\n content: Object.keys(fm).length > 0\n ? matter.stringify(rule.content, fm)\n : rule.content,\n });\n }\n\n return files;\n }\n\n private parseClaudeMd(filePath: string, content: string): UnifiedRule[] {\n const trimmed = content.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('claude-code', filePath),\n content: trimmed,\n source: 'claude-code',\n scope: 'project',\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n\n private parseModularRule(filePath: string, content: string): UnifiedRule[] {\n const { data, content: body } = matter(content);\n const trimmed = body.trim();\n if (!trimmed) return [];\n\n const paths = data.paths as string[] | undefined;\n const hasPaths = Array.isArray(paths) && paths.length > 0;\n\n return [{\n id: generateRuleId('claude-code', filePath),\n content: trimmed,\n description: data.description as string | undefined,\n source: 'claude-code',\n scope: hasPaths ? 'path-specific' : 'project',\n paths: hasPaths ? paths : undefined,\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n}\n","/**\n * OpenAI Codex Rule Format Adapter\n *\n * Parses and generates rules in Codex's formats:\n * - .agents/skills/[name]/SKILL.md (Markdown + frontmatter with name, description)\n * - AGENTS.md (pure Markdown)\n *\n * Source: OpenAI Codex Skills documentation.\n */\n\nimport matter from 'gray-matter';\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\nimport { hashContent, generateRuleId } from '../utils.js';\n\nexport class CodexAdapter implements RuleFormatAdapter {\n readonly source: RuleSource = 'codex';\n\n readonly filePatterns = [\n '.agents/skills/*/SKILL.md',\n 'AGENTS.md',\n ];\n\n parse(filePath: string, content: string): UnifiedRule[] {\n if (filePath.includes('SKILL.md')) {\n return this.parseSkillMd(filePath, content);\n }\n if (filePath.endsWith('AGENTS.md')) {\n return this.parseAgentsMd(filePath, content);\n }\n return [];\n }\n\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\n return rules.map((rule, i) => {\n const skillName = rule.id\n .replace(/^codex:/, '')\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n || `skill-${i}`;\n\n const fm: Record<string, unknown> = {\n name: skillName,\n };\n\n // Codex needs description to know WHEN to trigger the skill.\n // If no description exists, auto-generate from content (first 120 chars).\n if (rule.description) {\n fm.description = rule.description;\n } else {\n fm.description = this.autoDescription(rule.content);\n }\n\n return {\n filePath: `.agents/skills/${skillName}/SKILL.md`,\n content: matter.stringify(rule.content, fm),\n };\n });\n }\n\n /** Extract a short description from rule content for Codex skill triggering */\n private autoDescription(content: string): string {\n // Take first meaningful line, strip markdown formatting\n const lines = content.split('\\n').map(l => l.trim()).filter(Boolean);\n const first = lines[0]?.replace(/^#+\\s*/, '').replace(/^[-*]\\s*/, '') || 'Project rules';\n if (first.length <= 120) return first;\n return first.substring(0, 117) + '...';\n }\n\n private parseSkillMd(filePath: string, content: string): UnifiedRule[] {\n const { data, content: body } = matter(content);\n const trimmed = body.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('codex', filePath),\n content: trimmed,\n description: (data.description as string) || undefined,\n source: 'codex',\n scope: 'project',\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n\n private parseAgentsMd(filePath: string, content: string): UnifiedRule[] {\n const trimmed = content.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('codex', filePath),\n content: trimmed,\n source: 'codex',\n scope: 'project',\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n}\n","/**\n * Windsurf Rule Format Adapter\n *\n * Parses and generates rules in Windsurf's formats:\n * - .windsurfrules (legacy plain text)\n * - .windsurf/rules/*.md (Markdown with optional frontmatter)\n *\n * Source: Windsurf/Codeium documentation.\n */\n\nimport matter from 'gray-matter';\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\nimport { hashContent, generateRuleId } from '../utils.js';\n\nexport class WindsurfAdapter implements RuleFormatAdapter {\n readonly source: RuleSource = 'windsurf';\n\n readonly filePatterns = [\n '.windsurfrules',\n '.windsurf/rules/*.md',\n ];\n\n parse(filePath: string, content: string): UnifiedRule[] {\n if (filePath === '.windsurfrules' || filePath.endsWith('/.windsurfrules')) {\n return this.parseLegacy(filePath, content);\n }\n if (filePath.includes('.windsurf/rules/')) {\n return this.parseModularRule(filePath, content);\n }\n return [];\n }\n\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\n return rules.map((rule, i) => {\n const fm: Record<string, unknown> = {};\n if (rule.description) fm.description = rule.description;\n\n const fileName = rule.id\n .replace(/^windsurf:/, '')\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n || `rule-${i}`;\n\n const body = Object.keys(fm).length > 0\n ? matter.stringify(rule.content, fm)\n : rule.content;\n\n return {\n filePath: `.windsurf/rules/${fileName}.md`,\n content: body,\n };\n });\n }\n\n private parseLegacy(filePath: string, content: string): UnifiedRule[] {\n const trimmed = content.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('windsurf', filePath),\n content: trimmed,\n source: 'windsurf',\n scope: 'project',\n priority: 3,\n hash: hashContent(trimmed),\n }];\n }\n\n private parseModularRule(filePath: string, content: string): UnifiedRule[] {\n const { data, content: body } = matter(content);\n const trimmed = body.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('windsurf', filePath),\n content: trimmed,\n description: data.description as string | undefined,\n source: 'windsurf',\n scope: 'project',\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n}\n","/**\r\n * Antigravity IDE Rule Format Adapter\r\n *\r\n * Parses and generates rules in Antigravity's formats:\r\n * - GEMINI.md (global rules, similar to CLAUDE.md)\r\n * - .agent/rules/*.md (workspace rules, Markdown with optional frontmatter)\r\n * - .agent/skills/[name]/SKILL.md (skills, Markdown + YAML frontmatter)\r\n *\r\n * Source: Antigravity official documentation (https://antigravity.google/docs/agent/rules)\r\n *\r\n * Note: Antigravity is Google's agent-first IDE, a VS Code fork.\r\n * Global rules: ~/.gemini/GEMINI.md\r\n * Workspace rules: <project>/.agent/rules/*.md\r\n * Skills: <project>/.agent/skills/[name]/SKILL.md\r\n * Workflows: <project>/.agent/workflows/*.md\r\n */\r\n\r\nimport matter from 'gray-matter';\r\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\r\nimport { hashContent, generateRuleId } from '../utils.js';\r\n\r\nexport class AntigravityAdapter implements RuleFormatAdapter {\r\n readonly source: RuleSource = 'antigravity';\r\n\r\n readonly filePatterns = [\r\n 'GEMINI.md',\r\n '.agent/rules/*.md',\r\n '.agent/skills/*/SKILL.md',\r\n ];\r\n\r\n parse(filePath: string, content: string): UnifiedRule[] {\r\n // .agent/skills/*/SKILL.md — skill files with frontmatter\r\n if (filePath.includes('SKILL.md')) {\r\n return this.parseSkillMd(filePath, content);\r\n }\r\n // .agent/rules/*.md — workspace rules\r\n if (filePath.includes('.agent/rules/')) {\r\n return this.parseAgentRule(filePath, content);\r\n }\r\n // GEMINI.md — global project-level rules\r\n if (filePath === 'GEMINI.md' || filePath.endsWith('/GEMINI.md')) {\r\n return this.parseGeminiMd(filePath, content);\r\n }\r\n return [];\r\n }\r\n\r\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\r\n const projectRules = rules.filter(r => r.scope !== 'path-specific');\r\n const pathRules = rules.filter(r => r.scope === 'path-specific');\r\n\r\n const files: { filePath: string; content: string }[] = [];\r\n\r\n // Generate workspace rules as .agent/rules/*.md\r\n for (const rule of [...projectRules, ...pathRules]) {\r\n const fm: Record<string, unknown> = {};\r\n if (rule.description) fm.description = rule.description;\r\n\r\n const fileName = rule.id\r\n .replace(/^antigravity:/, '')\r\n .replace(/[^a-zA-Z0-9-_]/g, '-')\r\n || 'rule';\r\n\r\n const body = Object.keys(fm).length > 0\r\n ? matter.stringify(rule.content, fm)\r\n : rule.content;\r\n\r\n files.push({\r\n filePath: `.agent/rules/${fileName}.md`,\r\n content: body,\r\n });\r\n }\r\n\r\n return files;\r\n }\r\n\r\n private parseGeminiMd(filePath: string, content: string): UnifiedRule[] {\r\n const trimmed = content.trim();\r\n if (!trimmed) return [];\r\n\r\n return [{\r\n id: generateRuleId('antigravity', filePath),\r\n content: trimmed,\r\n source: 'antigravity',\r\n scope: 'global',\r\n priority: 10,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n\r\n private parseAgentRule(filePath: string, content: string): UnifiedRule[] {\r\n const { data, content: body } = matter(content);\r\n const trimmed = body.trim();\r\n if (!trimmed) return [];\r\n\r\n return [{\r\n id: generateRuleId('antigravity', filePath),\r\n content: trimmed,\r\n description: data.description as string | undefined,\r\n source: 'antigravity',\r\n scope: 'project',\r\n priority: 5,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n\r\n private parseSkillMd(filePath: string, content: string): UnifiedRule[] {\r\n const { data, content: body } = matter(content);\r\n const trimmed = body.trim();\r\n if (!trimmed) return [];\r\n\r\n return [{\r\n id: generateRuleId('antigravity', filePath),\r\n content: trimmed,\r\n description: (data.description as string) || undefined,\r\n source: 'antigravity',\r\n scope: 'project',\r\n priority: 5,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n}\r\n","/**\r\n * GitHub Copilot Rule Format Adapter\r\n *\r\n * Parses and generates rules in Copilot's formats:\r\n * - .github/copilot-instructions.md (repository-wide instructions, plain Markdown)\r\n * - .github/instructions/*.instructions.md (path-specific, YAML frontmatter with `applyTo` glob)\r\n *\r\n * Source: https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot\r\n */\r\n\r\nimport matter from 'gray-matter';\r\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\r\nimport { hashContent, generateRuleId } from '../utils.js';\r\n\r\nexport class CopilotAdapter implements RuleFormatAdapter {\r\n readonly source: RuleSource = 'copilot';\r\n\r\n readonly filePatterns = [\r\n '.github/copilot-instructions.md',\r\n '.github/instructions/*.instructions.md',\r\n ];\r\n\r\n parse(filePath: string, content: string): UnifiedRule[] {\r\n // Path-specific instruction files (.github/instructions/*.instructions.md)\r\n if (filePath.includes('.instructions.md') && filePath.includes('.github/instructions')) {\r\n return this.parsePathSpecific(filePath, content);\r\n }\r\n // Repository-wide instructions (.github/copilot-instructions.md)\r\n if (filePath.includes('copilot-instructions.md')) {\r\n return this.parseRepoWide(filePath, content);\r\n }\r\n return [];\r\n }\r\n\r\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\r\n // If only one rule with no path-specific globs, output as copilot-instructions.md\r\n if (rules.length === 1 && (!rules[0].paths || rules[0].paths.length === 0)) {\r\n return [{\r\n filePath: '.github/copilot-instructions.md',\r\n content: rules[0].content,\r\n }];\r\n }\r\n\r\n // Multiple rules → output as path-specific instruction files\r\n return rules.map((rule, i) => {\r\n const fm: Record<string, unknown> = {};\r\n\r\n // Preserve applyTo if available\r\n if (rule.paths && rule.paths.length > 0) {\r\n fm.applyTo = rule.paths.join(',');\r\n }\r\n if (rule.description) {\r\n fm.description = rule.description;\r\n }\r\n\r\n const fileName = rule.id\r\n .replace(/^copilot:/, '')\r\n .replace(/[^a-zA-Z0-9-_]/g, '-')\r\n || `instruction-${i}`;\r\n\r\n const body = Object.keys(fm).length > 0\r\n ? matter.stringify(rule.content, fm)\r\n : rule.content;\r\n\r\n return {\r\n filePath: `.github/instructions/${fileName}.instructions.md`,\r\n content: body,\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Parse repository-wide .github/copilot-instructions.md\r\n * This is plain Markdown with no frontmatter.\r\n */\r\n private parseRepoWide(filePath: string, content: string): UnifiedRule[] {\r\n const trimmed = content.trim();\r\n if (!trimmed) return [];\r\n\r\n return [{\r\n id: generateRuleId('copilot', filePath),\r\n content: trimmed,\r\n description: 'Repository-wide Copilot instructions',\r\n source: 'copilot',\r\n scope: 'project',\r\n priority: 3,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n\r\n /**\r\n * Parse path-specific .github/instructions/*.instructions.md\r\n * These have YAML frontmatter with `applyTo` glob pattern(s).\r\n */\r\n private parsePathSpecific(filePath: string, content: string): UnifiedRule[] {\r\n const { data, content: body } = matter(content);\r\n const trimmed = body.trim();\r\n if (!trimmed) return [];\r\n\r\n const applyTo = data.applyTo as string | undefined;\r\n const hasApplyTo = !!applyTo;\r\n\r\n const rule: UnifiedRule = {\r\n id: generateRuleId('copilot', filePath),\r\n content: trimmed,\r\n source: 'copilot',\r\n scope: hasApplyTo ? 'path-specific' : 'project',\r\n priority: 5,\r\n hash: hashContent(trimmed),\r\n };\r\n\r\n // Extract applyTo glob pattern(s) → store in paths[]\r\n if (hasApplyTo) {\r\n rule.paths = applyTo!.split(',').map(p => p.trim());\r\n }\r\n\r\n // Extract description if present\r\n if (data.description) {\r\n rule.description = data.description as string;\r\n }\r\n\r\n return [rule];\r\n }\r\n}\r\n","/**\r\n * Kiro Rule Format Adapter\r\n *\r\n * Parses and generates rules in Kiro's formats:\r\n * - .kiro/steering/*.md (Markdown steering rules with optional frontmatter)\r\n * - AGENTS.md (always included, pure Markdown)\r\n *\r\n * Source: Kiro official documentation on Steering Rules.\r\n * https://kiro.dev/docs/steering/\r\n *\r\n * Kiro uses \".kiro/steering/\" for project-level rules\r\n * and \"~/.kiro/steering/\" for user-level (global) rules.\r\n *\r\n * Frontmatter inclusion modes:\r\n * - always (default): loaded into every interaction\r\n * - fileMatch + fileMatchPattern: conditional on file globs\r\n * - manual: on-demand via #name in chat\r\n * - auto + name + description: auto-included when relevant\r\n */\r\n\r\nimport matter from 'gray-matter';\r\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\r\nimport { hashContent, generateRuleId } from '../utils.js';\r\n\r\n/** Kiro inclusion mode values */\r\ntype KiroInclusion = 'always' | 'fileMatch' | 'manual' | 'auto';\r\n\r\nexport class KiroAdapter implements RuleFormatAdapter {\r\n readonly source: RuleSource = 'kiro';\r\n\r\n readonly filePatterns = [\r\n '.kiro/steering/*.md',\r\n 'AGENTS.md',\r\n ];\r\n\r\n parse(filePath: string, content: string): UnifiedRule[] {\r\n if (filePath.includes('.kiro/steering/')) {\r\n return this.parseSteeringRule(filePath, content);\r\n }\r\n if (filePath.endsWith('AGENTS.md')) {\r\n return this.parseAgentsMd(filePath, content);\r\n }\r\n return [];\r\n }\r\n\r\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\r\n return rules.map((rule, i) => {\r\n const fm: Record<string, unknown> = {};\r\n if (rule.description) fm.description = rule.description;\r\n\r\n // Map unified scope → Kiro inclusion mode\r\n if (rule.paths && rule.paths.length > 0) {\r\n fm.inclusion = 'fileMatch';\r\n fm.fileMatchPattern = rule.paths.length === 1\r\n ? rule.paths[0]\r\n : rule.paths;\r\n } else if (rule.alwaysApply) {\r\n fm.inclusion = 'always';\r\n }\r\n\r\n const fileName = rule.id\r\n .replace(/^kiro:/, '')\r\n .replace(/[^a-zA-Z0-9-_]/g, '-')\r\n || `rule-${i}`;\r\n\r\n const body = Object.keys(fm).length > 0\r\n ? matter.stringify(rule.content, fm)\r\n : rule.content;\r\n\r\n return {\r\n filePath: `.kiro/steering/${fileName}.md`,\r\n content: body,\r\n };\r\n });\r\n }\r\n\r\n private parseSteeringRule(filePath: string, content: string): UnifiedRule[] {\r\n const { data, content: body } = matter(content);\r\n const trimmed = body.trim();\r\n if (!trimmed) return [];\r\n\r\n // Kiro uses \"inclusion\" field: always | fileMatch | manual | auto\r\n const inclusion = (data.inclusion as KiroInclusion | undefined) ?? 'always';\r\n const alwaysApply = inclusion === 'always' || inclusion === 'auto';\r\n\r\n // fileMatchPattern can be a string or string[]\r\n let paths: string[] | undefined;\r\n if (inclusion === 'fileMatch' && data.fileMatchPattern) {\r\n paths = Array.isArray(data.fileMatchPattern)\r\n ? data.fileMatchPattern\r\n : [data.fileMatchPattern];\r\n }\r\n\r\n let scope: UnifiedRule['scope'] = 'project';\r\n if (alwaysApply) scope = 'global';\r\n else if (paths && paths.length > 0) scope = 'path-specific';\r\n\r\n return [{\r\n id: generateRuleId('kiro', filePath),\r\n content: trimmed,\r\n description: data.description as string | undefined,\r\n source: 'kiro',\r\n scope,\r\n paths,\r\n alwaysApply,\r\n priority: alwaysApply ? 10 : 5,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n\r\n private parseAgentsMd(filePath: string, content: string): UnifiedRule[] {\r\n const trimmed = content.trim();\r\n if (!trimmed) return [];\r\n\r\n return [{\r\n id: generateRuleId('kiro', filePath),\r\n content: trimmed,\r\n source: 'kiro',\r\n scope: 'project',\r\n alwaysApply: true,\r\n priority: 10,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n}\r\n\r\n","/**\n * Rules Syncer\n *\n * Core sync engine for cross-agent rule synchronization.\n * Scans project for rule files from all supported agents,\n * deduplicates by content hash, detects conflicts, and\n * generates output in any target agent format.\n *\n * This is the ~15% original logic in Memorix — dedup and\n * conflict detection are not found in any existing tool.\n */\n\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { UnifiedRule, RuleSource, RuleFormatAdapter } from '../types.js';\nimport { CursorAdapter } from './adapters/cursor.js';\nimport { ClaudeCodeAdapter } from './adapters/claude-code.js';\nimport { CodexAdapter } from './adapters/codex.js';\nimport { WindsurfAdapter } from './adapters/windsurf.js';\nimport { AntigravityAdapter } from './adapters/antigravity.js';\nimport { CopilotAdapter } from './adapters/copilot.js';\nimport { KiroAdapter } from './adapters/kiro.js';\n\n/** A detected conflict between two rules */\nexport interface RuleConflict {\n ruleA: UnifiedRule;\n ruleB: UnifiedRule;\n reason: string;\n}\n\n/** Sync status report */\nexport interface SyncStatus {\n totalRules: number;\n uniqueRules: number;\n sources: RuleSource[];\n conflicts: RuleConflict[];\n}\n\n/** File scan patterns for each adapter */\ninterface ScanEntry {\n adapter: RuleFormatAdapter;\n paths: string[];\n}\n\nexport class RulesSyncer {\n private readonly projectRoot: string;\n private readonly adapters: Map<RuleSource, RuleFormatAdapter>;\n\n constructor(projectRoot: string) {\n this.projectRoot = projectRoot;\n this.adapters = new Map();\n\n const all: RuleFormatAdapter[] = [\n new CursorAdapter(),\n new ClaudeCodeAdapter(),\n new CodexAdapter(),\n new WindsurfAdapter(),\n new AntigravityAdapter(),\n new CopilotAdapter(),\n new KiroAdapter(),\n ];\n for (const a of all) {\n this.adapters.set(a.source, a);\n }\n }\n\n /** Scan the project root for all known rule files and parse them */\n async scanRules(): Promise<UnifiedRule[]> {\n const rules: UnifiedRule[] = [];\n\n const scanEntries = this.buildScanEntries();\n\n for (const entry of scanEntries) {\n for (const scanPath of entry.paths) {\n const found = await this.findFiles(scanPath);\n for (const filePath of found) {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const relativePath = path.relative(this.projectRoot, filePath).replace(/\\\\/g, '/');\n const parsed = entry.adapter.parse(relativePath, content);\n rules.push(...parsed);\n } catch {\n // Skip unreadable files\n }\n }\n }\n }\n\n return rules;\n }\n\n /** Remove duplicate rules by content hash, keeping highest priority */\n deduplicateRules(rules: UnifiedRule[]): UnifiedRule[] {\n const byHash = new Map<string, UnifiedRule>();\n\n for (const rule of rules) {\n const existing = byHash.get(rule.hash);\n if (!existing || rule.priority > existing.priority) {\n byHash.set(rule.hash, rule);\n }\n }\n\n return Array.from(byHash.values());\n }\n\n /** Detect conflicts: rules with overlapping paths but different content */\n detectConflicts(rules: UnifiedRule[]): RuleConflict[] {\n const conflicts: RuleConflict[] = [];\n\n for (let i = 0; i < rules.length; i++) {\n for (let j = i + 1; j < rules.length; j++) {\n const a = rules[i];\n const b = rules[j];\n\n // Only compare rules from different sources\n if (a.source === b.source) continue;\n // Only compare if both have overlapping paths\n if (a.scope === 'path-specific' && b.scope === 'path-specific') {\n if (this.pathsOverlap(a.paths || [], b.paths || [])) {\n conflicts.push({\n ruleA: a,\n ruleB: b,\n reason: `Overlapping paths: ${a.source} vs ${b.source}`,\n });\n }\n }\n }\n }\n\n return conflicts;\n }\n\n /** Generate rule files for a target agent format */\n generateForTarget(\n rules: UnifiedRule[],\n target: RuleSource,\n ): { filePath: string; content: string }[] {\n const adapter = this.adapters.get(target);\n if (!adapter) {\n throw new Error(`No adapter for target: ${target}`);\n }\n return adapter.generate(rules);\n }\n\n /** Get a full sync status report */\n async syncStatus(): Promise<SyncStatus> {\n const rules = await this.scanRules();\n const deduped = this.deduplicateRules(rules);\n const conflicts = this.detectConflicts(deduped);\n const sources = [...new Set(rules.map(r => r.source))];\n\n return {\n totalRules: rules.length,\n uniqueRules: deduped.length,\n sources,\n conflicts,\n };\n }\n\n /** Build scan entries mapping adapters to their file search paths */\n private buildScanEntries(): ScanEntry[] {\n const entries: ScanEntry[] = [];\n\n for (const adapter of this.adapters.values()) {\n const absolutePaths = adapter.filePatterns.map(p =>\n path.join(this.projectRoot, p),\n );\n entries.push({ adapter, paths: absolutePaths });\n }\n\n return entries;\n }\n\n /** Find files matching a glob-like path (simple implementation) */\n private async findFiles(pattern: string): Promise<string[]> {\n const dir = path.dirname(pattern);\n const fileGlob = path.basename(pattern);\n\n try {\n const stat = await fs.stat(dir);\n if (!stat.isDirectory()) {\n // It's a direct file path\n try {\n await fs.access(pattern);\n return [pattern];\n } catch {\n return [];\n }\n }\n } catch {\n // If dir doesn't exist, check if pattern itself is a file\n try {\n await fs.access(pattern);\n return [pattern];\n } catch {\n return [];\n }\n }\n\n // If it's a glob pattern (contains *), list dir and filter\n if (fileGlob.includes('*')) {\n try {\n const files = await fs.readdir(dir);\n const ext = fileGlob.replace('*', '');\n return files\n .filter(f => ext ? f.endsWith(ext) : true)\n .map(f => path.join(dir, f));\n } catch {\n return [];\n }\n }\n\n // Direct file\n try {\n await fs.access(path.join(dir, fileGlob));\n return [path.join(dir, fileGlob)];\n } catch {\n return [];\n }\n }\n\n /** Check if two sets of glob paths overlap (simplified: exact match) */\n private pathsOverlap(a: string[], b: string[]): boolean {\n for (const pa of a) {\n for (const pb of b) {\n if (pa === pb) return true;\n }\n }\n return false;\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * Windsurf MCP config adapter.\n * Format: JSON file at ~/.codeium/windsurf/mcp_config.json\n *\n * Supports two transport modes:\n * 1. stdio: { command, args, env? }\n * 2. HTTP: { serverUrl, headers? }\n *\n * Also handles: disabled, disabledTools, env: null\n */\nexport class WindsurfMCPAdapter implements MCPConfigAdapter {\n readonly source = 'windsurf' as const;\n\n parse(content: string): MCPServerEntry[] {\n try {\n const config = JSON.parse(content);\n const servers = config.mcpServers ?? config.mcp_servers ?? {};\n return Object.entries(servers).map(([name, entry]: [string, any]) => {\n const result: MCPServerEntry = {\n name,\n command: entry.command ?? '',\n args: entry.args ?? [],\n };\n\n // HTTP transport: Windsurf uses \"serverUrl\" (not \"url\")\n if (entry.serverUrl) {\n result.url = entry.serverUrl;\n } else if (entry.url) {\n result.url = entry.url;\n }\n\n // Headers (for HTTP transport)\n if (entry.headers && typeof entry.headers === 'object' && Object.keys(entry.headers).length > 0) {\n result.headers = entry.headers;\n }\n\n // Env (can be null in Windsurf)\n if (entry.env && typeof entry.env === 'object' && Object.keys(entry.env).length > 0) {\n result.env = entry.env;\n }\n\n // Disabled flag\n if (entry.disabled === true) {\n result.disabled = true;\n }\n\n return result;\n });\n } catch {\n return [];\n }\n }\n\n generate(servers: MCPServerEntry[]): string {\n const mcpServers: Record<string, any> = {};\n for (const s of servers) {\n const entry: Record<string, any> = {};\n\n if (s.url) {\n // HTTP transport — Windsurf uses \"serverUrl\"\n entry.serverUrl = s.url;\n if (s.headers && Object.keys(s.headers).length > 0) {\n entry.headers = s.headers;\n }\n } else {\n // stdio transport\n entry.command = s.command;\n entry.args = s.args;\n }\n\n if (s.env && Object.keys(s.env).length > 0) {\n entry.env = s.env;\n }\n\n if (s.disabled === true) {\n entry.disabled = true;\n }\n\n mcpServers[s.name] = entry;\n }\n return JSON.stringify({ mcpServers }, null, 2);\n }\n\n getConfigPath(_projectRoot?: string): string {\n return join(homedir(), '.codeium', 'windsurf', 'mcp_config.json');\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * Cursor MCP config adapter.\n * Format: JSON file at ~/.cursor/mcp.json or .cursor/mcp.json (project-level)\n * Structure: { mcpServers: { [name]: { command, args, env?, url? } } }\n */\nexport class CursorMCPAdapter implements MCPConfigAdapter {\n readonly source = 'cursor' as const;\n\n parse(content: string): MCPServerEntry[] {\n try {\n const config = JSON.parse(content);\n const servers = config.mcpServers ?? {};\n return Object.entries(servers).map(([name, entry]: [string, any]) => ({\n name,\n command: entry.command ?? '',\n args: entry.args ?? [],\n ...(entry.env && Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),\n ...(entry.url ? { url: entry.url } : {}),\n }));\n } catch {\n return [];\n }\n }\n\n generate(servers: MCPServerEntry[]): string {\n const mcpServers: Record<string, any> = {};\n for (const s of servers) {\n const entry: Record<string, any> = {};\n if (s.url) {\n entry.url = s.url;\n } else {\n entry.command = s.command;\n entry.args = s.args;\n }\n if (s.env && Object.keys(s.env).length > 0) {\n entry.env = s.env;\n }\n mcpServers[s.name] = entry;\n }\n return JSON.stringify({ mcpServers }, null, 2);\n }\n\n getConfigPath(projectRoot?: string): string {\n if (projectRoot) {\n return join(projectRoot, '.cursor', 'mcp.json');\n }\n return join(homedir(), '.cursor', 'mcp.json');\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * Codex MCP config adapter.\n * Format: TOML file at ~/.codex/config.toml or .codex/config.toml (project-level)\n *\n * Structure:\n * [mcp_servers.<name>]\n * command = \"npx\"\n * args = [\"-y\", \"memorix-mcp\"]\n * url = \"https://...\" # for HTTP servers\n *\n * [mcp_servers.<name>.env]\n * KEY = \"value\"\n *\n * We implement a lightweight TOML parser (no external deps) sufficient\n * for MCP server config blocks. This avoids adding a TOML dependency.\n */\nexport class CodexMCPAdapter implements MCPConfigAdapter {\n readonly source = 'codex' as const;\n\n parse(content: string): MCPServerEntry[] {\n if (!content.trim()) return [];\n\n const servers: MCPServerEntry[] = [];\n const lines = content.split('\\n');\n\n let currentServer: string | null = null;\n let isEnvBlock = false;\n const serverMap = new Map<\n string,\n { command: string; args: string[]; env: Record<string, string>; url?: string; enabled?: boolean }\n >();\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n\n // Skip comments and empty lines\n if (!line || line.startsWith('#')) continue;\n\n // Match [mcp_servers.<name>.env]\n const envMatch = line.match(/^\\[mcp_servers\\.([^.\\]]+)\\.env\\]$/);\n if (envMatch) {\n currentServer = envMatch[1];\n isEnvBlock = true;\n if (!serverMap.has(currentServer)) {\n serverMap.set(currentServer, { command: '', args: [], env: {} });\n }\n continue;\n }\n\n // Match [mcp_servers.<name>]\n const serverMatch = line.match(/^\\[mcp_servers\\.([^.\\]]+)\\]$/);\n if (serverMatch) {\n currentServer = serverMatch[1];\n isEnvBlock = false;\n if (!serverMap.has(currentServer)) {\n serverMap.set(currentServer, { command: '', args: [], env: {} });\n }\n continue;\n }\n\n // Any other section header resets context\n if (line.startsWith('[')) {\n currentServer = null;\n isEnvBlock = false;\n continue;\n }\n\n // Parse key = value within current server block\n if (currentServer) {\n const kvMatch = line.match(/^(\\w+)\\s*=\\s*(.+)$/);\n if (!kvMatch) continue;\n\n const key = kvMatch[1];\n const rawValue = kvMatch[2].trim();\n const entry = serverMap.get(currentServer)!;\n\n if (isEnvBlock) {\n entry.env[key] = this.parseTomlString(rawValue);\n } else if (key === 'command') {\n entry.command = this.parseTomlString(rawValue);\n } else if (key === 'args') {\n entry.args = this.parseTomlArray(rawValue);\n } else if (key === 'url') {\n entry.url = this.parseTomlString(rawValue);\n } else if (key === 'enabled') {\n entry.enabled = rawValue === 'true';\n }\n }\n }\n\n for (const [name, entry] of serverMap) {\n servers.push({\n name,\n command: entry.command,\n args: entry.args,\n ...(Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),\n ...(entry.url ? { url: entry.url } : {}),\n });\n }\n\n return servers;\n }\n\n generate(servers: MCPServerEntry[]): string {\n const blocks: string[] = [];\n\n for (const s of servers) {\n const lines: string[] = [];\n lines.push(`[mcp_servers.${s.name}]`);\n\n if (s.url) {\n lines.push(`url = ${this.toTomlString(s.url)}`);\n } else {\n lines.push(`command = ${this.toTomlString(s.command)}`);\n lines.push(`args = [${s.args.map((a) => this.toTomlString(a)).join(', ')}]`);\n }\n\n if (s.env && Object.keys(s.env).length > 0) {\n lines.push('');\n lines.push(`[mcp_servers.${s.name}.env]`);\n for (const [key, value] of Object.entries(s.env)) {\n lines.push(`${key} = ${this.toTomlString(value)}`);\n }\n }\n\n blocks.push(lines.join('\\n'));\n }\n\n return blocks.join('\\n\\n') + '\\n';\n }\n\n getConfigPath(projectRoot?: string): string {\n if (projectRoot) {\n return join(projectRoot, '.codex', 'config.toml');\n }\n return join(homedir(), '.codex', 'config.toml');\n }\n\n // ---- TOML helpers ----\n\n private parseTomlString(raw: string): string {\n const trimmed = raw.trim();\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n }\n\n private parseTomlArray(raw: string): string[] {\n const trimmed = raw.trim();\n if (!trimmed.startsWith('[') || !trimmed.endsWith(']')) return [];\n const inner = trimmed.slice(1, -1);\n const result: string[] = [];\n // Simple CSV parse respecting quotes\n let current = '';\n let inQuote = false;\n let quoteChar = '';\n for (const ch of inner) {\n if (inQuote) {\n if (ch === quoteChar) {\n inQuote = false;\n } else {\n current += ch;\n }\n } else if (ch === '\"' || ch === \"'\") {\n inQuote = true;\n quoteChar = ch;\n } else if (ch === ',') {\n const val = current.trim();\n if (val) result.push(val);\n current = '';\n } else {\n current += ch;\n }\n }\n const last = current.trim();\n if (last) result.push(last);\n return result;\n }\n\n private toTomlString(value: string): string {\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * Claude Code MCP config adapter.\n * Format: JSON file at ~/.claude.json or project-level .claude/settings.json\n * Structure: { mcpServers: { [name]: { command, args, env?, url? } } }\n */\nexport class ClaudeCodeMCPAdapter implements MCPConfigAdapter {\n readonly source = 'claude-code' as const;\n\n parse(content: string): MCPServerEntry[] {\n try {\n const config = JSON.parse(content);\n const servers = config.mcpServers ?? {};\n return Object.entries(servers).map(([name, entry]: [string, any]) => ({\n name,\n command: entry.command ?? '',\n args: entry.args ?? [],\n ...(entry.env && Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),\n ...(entry.url ? { url: entry.url } : {}),\n }));\n } catch {\n return [];\n }\n }\n\n generate(servers: MCPServerEntry[]): string {\n const mcpServers: Record<string, any> = {};\n for (const s of servers) {\n const entry: Record<string, any> = {};\n if (s.url) {\n entry.url = s.url;\n } else {\n entry.command = s.command;\n entry.args = s.args;\n }\n if (s.env && Object.keys(s.env).length > 0) {\n entry.env = s.env;\n }\n mcpServers[s.name] = entry;\n }\n return JSON.stringify({ mcpServers }, null, 2);\n }\n\n getConfigPath(projectRoot?: string): string {\n if (projectRoot) {\n return join(projectRoot, '.claude', 'settings.json');\n }\n return join(homedir(), '.claude.json');\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync, readFileSync } from 'node:fs';\n\n/**\n * VS Code Copilot MCP config adapter.\n *\n * Config location: %APPDATA%/Code/User/settings.json (global)\n * or .vscode/mcp.json (workspace-level)\n *\n * Format inside settings.json:\n * { \"mcp\": { \"servers\": { [name]: { command, args, env? } } } }\n *\n * IMPORTANT: settings.json contains many non-MCP settings.\n * generate() merges MCP servers into the existing file instead of overwriting.\n */\nexport class CopilotMCPAdapter implements MCPConfigAdapter {\n readonly source = 'copilot' as const;\n\n parse(content: string): MCPServerEntry[] {\n try {\n const config = JSON.parse(content);\n\n // settings.json format: { \"mcp\": { \"servers\": { ... } } }\n const servers = config?.mcp?.servers ?? {};\n\n return Object.entries(servers).map(([name, entry]: [string, any]) => {\n const result: MCPServerEntry = {\n name,\n command: entry.command ?? '',\n args: entry.args ?? [],\n };\n\n if (entry.url) {\n result.url = entry.url;\n }\n\n if (entry.env && typeof entry.env === 'object' && Object.keys(entry.env).length > 0) {\n result.env = entry.env;\n }\n\n return result;\n });\n } catch {\n return [];\n }\n }\n\n generate(servers: MCPServerEntry[]): string {\n const mcpServers: Record<string, any> = {};\n for (const s of servers) {\n const entry: Record<string, any> = {};\n if (s.url) {\n entry.url = s.url;\n } else {\n entry.command = s.command;\n entry.args = s.args;\n }\n if (s.env && Object.keys(s.env).length > 0) {\n entry.env = s.env;\n }\n mcpServers[s.name] = entry;\n }\n\n // Merge into existing settings.json if it exists\n const configPath = this.getConfigPath();\n let existing: Record<string, any> = {};\n if (existsSync(configPath)) {\n try {\n existing = JSON.parse(readFileSync(configPath, 'utf-8'));\n } catch {\n // If parse fails, start fresh\n }\n }\n\n // Merge MCP servers into existing mcp.servers (preserve other servers)\n const existingMcp = existing.mcp ?? {};\n const existingServers = existingMcp.servers ?? {};\n existing.mcp = {\n ...existingMcp,\n servers: { ...existingServers, ...mcpServers },\n };\n\n return JSON.stringify(existing, null, 4);\n }\n\n getConfigPath(_projectRoot?: string): string {\n // VS Code user settings path varies by OS\n const home = homedir();\n if (process.platform === 'win32') {\n return join(home, 'AppData', 'Roaming', 'Code', 'User', 'settings.json');\n } else if (process.platform === 'darwin') {\n return join(home, 'Library', 'Application Support', 'Code', 'User', 'settings.json');\n } else {\n return join(home, '.config', 'Code', 'User', 'settings.json');\n }\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\r\nimport { homedir } from 'node:os';\r\nimport { join } from 'node:path';\r\n\r\n/**\r\n * Antigravity IDE MCP Configuration Adapter.\r\n *\r\n * Antigravity uses two JSON config files for MCP servers:\r\n * 1. Global MCP: ~/.gemini/antigravity/mcp_config.json\r\n * Format: { \"mcpServers\": { \"name\": { command, args, env? } } }\r\n *\r\n * 2. Global settings: ~/.gemini/settings.json\r\n * Format: { \"mcpServers\": { \"name\": { command, args, env? } } }\r\n *\r\n * The mcp_config.json format is the primary config, same JSON structure\r\n * as Windsurf but at a different path. Also supports HTTP transport via url.\r\n *\r\n * Source: Antigravity official documentation (https://antigravity.google/docs/agent/mcp)\r\n * Verified on local machine: C:\\Users\\<USER>\\.gemini\\antigravity\\mcp_config.json\r\n */\r\nexport class AntigravityMCPAdapter implements MCPConfigAdapter {\r\n readonly source = 'antigravity' as const;\r\n\r\n parse(content: string): MCPServerEntry[] {\r\n try {\r\n const config = JSON.parse(content);\r\n const servers = config.mcpServers ?? config.mcp_servers ?? {};\r\n return Object.entries(servers).map(([name, entry]: [string, any]) => {\r\n const result: MCPServerEntry = {\r\n name,\r\n command: entry.command ?? '',\r\n args: entry.args ?? [],\r\n };\r\n\r\n // HTTP transport\r\n if (entry.serverUrl) {\r\n result.url = entry.serverUrl;\r\n } else if (entry.url) {\r\n result.url = entry.url;\r\n }\r\n\r\n // Headers (for HTTP transport)\r\n if (entry.headers && typeof entry.headers === 'object' && Object.keys(entry.headers).length > 0) {\r\n result.headers = entry.headers;\r\n }\r\n\r\n // Env\r\n if (entry.env && typeof entry.env === 'object' && Object.keys(entry.env).length > 0) {\r\n result.env = entry.env;\r\n }\r\n\r\n // Disabled flag\r\n if (entry.disabled === true) {\r\n result.disabled = true;\r\n }\r\n\r\n return result;\r\n });\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n generate(servers: MCPServerEntry[]): string {\r\n const mcpServers: Record<string, any> = {};\r\n for (const s of servers) {\r\n const entry: Record<string, any> = {};\r\n\r\n if (s.url) {\r\n // HTTP transport\r\n entry.url = s.url;\r\n if (s.headers && Object.keys(s.headers).length > 0) {\r\n entry.headers = s.headers;\r\n }\r\n } else {\r\n // stdio transport\r\n entry.command = s.command;\r\n entry.args = s.args;\r\n }\r\n\r\n if (s.env && Object.keys(s.env).length > 0) {\r\n entry.env = s.env;\r\n }\r\n\r\n if (s.disabled === true) {\r\n entry.disabled = true;\r\n }\r\n\r\n mcpServers[s.name] = entry;\r\n }\r\n return JSON.stringify({ mcpServers }, null, 2);\r\n }\r\n\r\n getConfigPath(_projectRoot?: string): string {\r\n // Antigravity primary MCP config location\r\n return join(homedir(), '.gemini', 'antigravity', 'mcp_config.json');\r\n }\r\n}\r\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\r\nimport { homedir } from 'node:os';\r\nimport { join } from 'node:path';\r\n\r\n/**\r\n * Kiro MCP config adapter.\r\n * Format: JSON file at .kiro/settings/mcp.json (project-level)\r\n * or ~/.kiro/settings/mcp.json (user-level)\r\n * Structure: { mcpServers: { [name]: { command, args, env?, disabled?, autoApprove?, timeout? } } }\r\n *\r\n * Source: Kiro official MCP documentation.\r\n */\r\nexport class KiroMCPAdapter implements MCPConfigAdapter {\r\n readonly source = 'kiro' as const;\r\n\r\n parse(content: string): MCPServerEntry[] {\r\n try {\r\n const config = JSON.parse(content);\r\n const servers = config.mcpServers ?? {};\r\n return Object.entries(servers).map(([name, entry]: [string, any]) => ({\r\n name,\r\n command: entry.command ?? '',\r\n args: entry.args ?? [],\r\n ...(entry.env && Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),\r\n ...(entry.url ? { url: entry.url } : {}),\r\n }));\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n generate(servers: MCPServerEntry[]): string {\r\n const mcpServers: Record<string, any> = {};\r\n for (const s of servers) {\r\n const entry: Record<string, any> = {};\r\n if (s.url) {\r\n entry.url = s.url;\r\n } else {\r\n entry.command = s.command;\r\n entry.args = s.args;\r\n }\r\n if (s.env && Object.keys(s.env).length > 0) {\r\n entry.env = s.env;\r\n }\r\n mcpServers[s.name] = entry;\r\n }\r\n return JSON.stringify({ mcpServers }, null, 2);\r\n }\r\n\r\n getConfigPath(projectRoot?: string): string {\r\n if (projectRoot) {\r\n return join(projectRoot, '.kiro', 'settings', 'mcp.json');\r\n }\r\n return join(homedir(), '.kiro', 'settings', 'mcp.json');\r\n }\r\n}\r\n","import matter from 'gray-matter';\nimport type { AgentTarget, WorkflowEntry } from '../types.js';\n\n/**\n * WorkflowSyncer — converts workflows between agent formats.\n *\n * Supported conversions:\n * Windsurf .windsurf/workflows/*.md → Codex SKILL.md\n * Windsurf .windsurf/workflows/*.md → Cursor .cursor/rules/*.mdc\n * Windsurf .windsurf/workflows/*.md → Claude Code CLAUDE.md section\n */\nexport class WorkflowSyncer {\n /**\n * Parse a Windsurf workflow markdown file into a WorkflowEntry.\n */\n parseWindsurfWorkflow(fileName: string, raw: string): WorkflowEntry {\n const name = fileName.replace(/\\.md$/i, '');\n let description = '';\n let content = raw;\n\n try {\n const parsed = matter(raw);\n description = parsed.data?.description ?? '';\n content = parsed.content.trim();\n } catch {\n // No frontmatter — use raw content\n }\n\n return {\n name,\n description,\n content,\n source: 'windsurf',\n filePath: `.windsurf/workflows/${fileName}`,\n };\n }\n\n /**\n * Convert a workflow to Codex SKILL.md format.\n */\n toCodexSkill(wf: WorkflowEntry): { filePath: string; content: string } {\n const safeName = this.sanitizeName(wf.name);\n const fm: Record<string, string> = { name: safeName };\n if (wf.description) {\n fm.description = wf.description;\n }\n const content = matter.stringify(wf.content, fm);\n return {\n filePath: `.agents/skills/${safeName}/SKILL.md`,\n content,\n };\n }\n\n /**\n * Convert a workflow to Cursor .mdc rule format.\n */\n toCursorRule(wf: WorkflowEntry): { filePath: string; content: string } {\n const safeName = this.sanitizeName(wf.name);\n const fm: Record<string, string> = {};\n if (wf.description) {\n fm.description = wf.description;\n }\n fm.globs = '';\n fm.alwaysApply = 'false';\n const content = matter.stringify(wf.content, fm);\n return {\n filePath: `.cursor/rules/${safeName}.mdc`,\n content,\n };\n }\n\n /**\n * Convert a workflow to a CLAUDE.md section string.\n */\n toClaudeSection(wf: WorkflowEntry): string {\n const lines: string[] = [];\n lines.push(`## Workflow: ${wf.name}`);\n if (wf.description) {\n lines.push('');\n lines.push(`> ${wf.description}`);\n }\n lines.push('');\n lines.push(wf.content);\n return lines.join('\\n');\n }\n\n /**\n * Convert all workflows to the target agent format.\n * Returns an array of { filePath, content } for each generated file.\n */\n convertAll(\n workflows: WorkflowEntry[],\n target: AgentTarget,\n ): { filePath: string; content: string }[] {\n if (target === 'windsurf') {\n // No conversion needed — already in Windsurf format\n return [];\n }\n\n if (target === 'codex') {\n return workflows.map((wf) => this.toCodexSkill(wf));\n }\n\n if (target === 'cursor') {\n return workflows.map((wf) => this.toCursorRule(wf));\n }\n\n if (target === 'claude-code') {\n // Merge all workflows into a single CLAUDE.md\n const sections = workflows.map((wf) => this.toClaudeSection(wf));\n return [\n {\n filePath: 'CLAUDE.md',\n content: sections.join('\\n\\n'),\n },\n ];\n }\n\n return [];\n }\n\n // ---- Helpers ----\n\n private sanitizeName(name: string): string {\n return name\n .replace(/[^a-zA-Z0-9_-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n || 'workflow';\n }\n}\n","/**\n * Sanitizer — mask sensitive values (tokens, keys, passwords) in output.\n *\n * Patterns detected:\n * - API keys / tokens (github_pat_*, ctx7sk-*, sk-*, ghp_*, ghu_*, etc.)\n * - Generic key=value where key contains \"token\", \"key\", \"secret\", \"password\"\n * - Bearer tokens\n */\n\nconst SENSITIVE_PATTERNS: { pattern: RegExp; replacement: string }[] = [\n // GitHub PAT (classic & fine-grained)\n { pattern: /ghp_[A-Za-z0-9_]{36,}/g, replacement: 'ghp_***' },\n { pattern: /github_pat_[A-Za-z0-9_]{60,}/g, replacement: 'github_pat_***' },\n { pattern: /ghu_[A-Za-z0-9_]{36,}/g, replacement: 'ghu_***' },\n { pattern: /ghs_[A-Za-z0-9_]{36,}/g, replacement: 'ghs_***' },\n // OpenAI / Anthropic style keys\n { pattern: /sk-[A-Za-z0-9_-]{20,}/g, replacement: 'sk-***' },\n // Context7 keys\n { pattern: /ctx7sk-[A-Za-z0-9-]{20,}/g, replacement: 'ctx7sk-***' },\n // Generic long hex/base64 tokens (32+ chars) in quoted values\n { pattern: /\"([A-Za-z0-9_-]{40,})\"/g, replacement: '\"***\"' },\n];\n\nconst SENSITIVE_KEY_PATTERN = /(?:token|key|secret|password|credential|auth)/i;\n\n/**\n * Mask sensitive values in a string.\n */\nexport function sanitize(input: string): string {\n let result = input;\n\n // Apply known token patterns\n for (const { pattern, replacement } of SENSITIVE_PATTERNS) {\n // Reset lastIndex for global regexes\n pattern.lastIndex = 0;\n result = result.replace(pattern, replacement);\n }\n\n return result;\n}\n\n/**\n * Mask sensitive values in MCPServerEntry env/headers objects.\n * Returns a new object with masked values.\n */\nexport function sanitizeRecord(\n record: Record<string, string> | undefined | null,\n): Record<string, string> | undefined {\n if (!record) return undefined;\n\n const masked: Record<string, string> = {};\n for (const [key, value] of Object.entries(record)) {\n if (SENSITIVE_KEY_PATTERN.test(key)) {\n masked[key] = '***';\n } else {\n masked[key] = value;\n }\n }\n return masked;\n}\n","/**\n * Workspace Sync Applier\n *\n * Writes generated workspace sync results to disk with safety features:\n * 1. Pre-flight validation (check writability)\n * 2. Backup existing files before overwrite\n * 3. Atomic write (write to temp, then rename)\n * 4. Rollback on failure\n *\n * Usage:\n * const applier = new WorkspaceSyncApplier();\n * const result = await applier.apply(syncResult);\n * if (!result.success) await applier.rollback(result.backups);\n */\n\nimport { existsSync, mkdirSync, copyFileSync, writeFileSync, unlinkSync, renameSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nexport interface ApplyResult {\n success: boolean;\n filesWritten: string[];\n backups: BackupEntry[];\n errors: string[];\n}\n\nexport interface BackupEntry {\n originalPath: string;\n backupPath: string;\n}\n\ninterface FileToWrite {\n filePath: string;\n content: string;\n}\n\n/**\n * Apply workspace sync results to disk with backup and rollback.\n */\nexport class WorkspaceSyncApplier {\n /**\n * Apply generated files to disk.\n *\n * Steps:\n * 1. Validate all target directories exist or can be created\n * 2. Backup existing files\n * 3. Write new files\n * 4. On any error → rollback all changes\n */\n async apply(files: FileToWrite[]): Promise<ApplyResult> {\n const result: ApplyResult = {\n success: false,\n filesWritten: [],\n backups: [],\n errors: [],\n };\n\n if (files.length === 0) {\n result.success = true;\n return result;\n }\n\n // Step 1: Pre-flight — ensure all directories exist\n for (const file of files) {\n try {\n const dir = dirname(file.filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n } catch (err) {\n result.errors.push(`Cannot create directory for ${file.filePath}: ${err}`);\n return result;\n }\n }\n\n // Step 2: Backup existing files\n for (const file of files) {\n if (existsSync(file.filePath)) {\n try {\n const backupPath = file.filePath + `.backup-${Date.now()}`;\n copyFileSync(file.filePath, backupPath);\n result.backups.push({\n originalPath: file.filePath,\n backupPath,\n });\n } catch (err) {\n result.errors.push(`Cannot backup ${file.filePath}: ${err}`);\n return result;\n }\n }\n }\n\n // Step 3: Write new files\n for (const file of files) {\n try {\n // Write to temp file first, then rename (pseudo-atomic)\n const tempPath = file.filePath + `.tmp-${Date.now()}`;\n writeFileSync(tempPath, file.content, 'utf-8');\n renameSync(tempPath, file.filePath);\n result.filesWritten.push(file.filePath);\n } catch (err) {\n result.errors.push(`Cannot write ${file.filePath}: ${err}`);\n // Rollback everything written so far\n this.rollback(result.backups);\n return result;\n }\n }\n\n result.success = true;\n return result;\n }\n\n /**\n * Rollback applied changes by restoring backups.\n */\n rollback(backups: BackupEntry[]): { restored: number; errors: string[] } {\n const errors: string[] = [];\n let restored = 0;\n\n for (const backup of backups) {\n try {\n copyFileSync(backup.backupPath, backup.originalPath);\n restored++;\n } catch (err) {\n errors.push(`Cannot restore ${backup.originalPath} from ${backup.backupPath}: ${err}`);\n }\n }\n\n return { restored, errors };\n }\n\n /**\n * Clean up backup files after successful apply.\n */\n cleanBackups(backups: BackupEntry[]): void {\n for (const backup of backups) {\n try {\n if (existsSync(backup.backupPath)) {\n unlinkSync(backup.backupPath);\n }\n } catch {\n // Best-effort cleanup\n }\n }\n }\n}\n","import { readFileSync, readdirSync, existsSync, cpSync, mkdirSync } from 'node:fs';\nimport { join, basename } from 'node:path';\nimport { homedir } from 'node:os';\nimport type {\n AgentTarget,\n MCPServerEntry,\n MCPConfigAdapter,\n WorkflowEntry,\n WorkspaceSyncResult,\n RuleSource,\n SkillEntry,\n SkillConflict,\n} from '../types.js';\nimport { WindsurfMCPAdapter } from './mcp-adapters/windsurf.js';\nimport { CursorMCPAdapter } from './mcp-adapters/cursor.js';\nimport { CodexMCPAdapter } from './mcp-adapters/codex.js';\nimport { ClaudeCodeMCPAdapter } from './mcp-adapters/claude-code.js';\nimport { CopilotMCPAdapter } from './mcp-adapters/copilot.js';\nimport { AntigravityMCPAdapter } from './mcp-adapters/antigravity.js';\nimport { KiroMCPAdapter } from './mcp-adapters/kiro.js';\nimport { WorkflowSyncer } from './workflow-sync.js';\nimport { RulesSyncer } from '../rules/syncer.js';\nimport { sanitize } from './sanitizer.js';\nimport { WorkspaceSyncApplier, type ApplyResult } from './applier.js';\n\n/** Scan result from workspace analysis */\nexport interface WorkspaceScanResult {\n mcpConfigs: Record<AgentTarget, MCPServerEntry[]>;\n workflows: WorkflowEntry[];\n rulesCount: number;\n skills: SkillEntry[];\n skillConflicts: SkillConflict[];\n}\n\n/**\n * WorkspaceSyncEngine — orchestrates cross-agent workspace migration.\n *\n * Capabilities:\n * 1. MCP config sync (JSON ↔ TOML across 4 agents)\n * 2. Workflow sync (Windsurf workflows → Codex skills / Cursor rules / CLAUDE.md)\n * 3. Rules sync (via existing RulesSyncer)\n */\nexport class WorkspaceSyncEngine {\n private adapters: Map<AgentTarget, MCPConfigAdapter>;\n private workflowSyncer: WorkflowSyncer;\n private rulesSyncer: RulesSyncer;\n\n constructor(private projectRoot: string) {\n this.adapters = new Map<AgentTarget, MCPConfigAdapter>([\n ['windsurf', new WindsurfMCPAdapter()],\n ['cursor', new CursorMCPAdapter()],\n ['codex', new CodexMCPAdapter()],\n ['claude-code', new ClaudeCodeMCPAdapter()],\n ['copilot', new CopilotMCPAdapter()],\n ['antigravity', new AntigravityMCPAdapter()],\n ['kiro', new KiroMCPAdapter()],\n ]);\n this.workflowSyncer = new WorkflowSyncer();\n this.rulesSyncer = new RulesSyncer(projectRoot);\n }\n\n /**\n * Scan the workspace for all agent configs, workflows, and rules.\n */\n async scan(): Promise<WorkspaceScanResult> {\n const mcpConfigs: Record<AgentTarget, MCPServerEntry[]> = {\n windsurf: [],\n cursor: [],\n codex: [],\n 'claude-code': [],\n copilot: [],\n antigravity: [],\n kiro: [],\n };\n\n // Scan MCP configs from each agent\n for (const [target, adapter] of this.adapters) {\n const configPath = adapter.getConfigPath(this.projectRoot);\n const globalPath = adapter.getConfigPath();\n\n // Try project-level first, then global\n for (const path of [configPath, globalPath]) {\n if (existsSync(path)) {\n try {\n const content = readFileSync(path, 'utf-8');\n const servers = adapter.parse(content);\n if (servers.length > 0) {\n mcpConfigs[target] = servers;\n break;\n }\n } catch {\n // Skip unreadable configs\n }\n }\n }\n }\n\n // Scan Windsurf workflows\n const workflows = this.scanWorkflows();\n\n // Scan rules\n let rulesCount = 0;\n try {\n const rules = await this.rulesSyncer.scanRules();\n rulesCount = rules.length;\n } catch {\n // Rules scan may fail if no rules exist\n }\n\n // Scan skills across all agents\n const { skills, conflicts: skillConflicts } = this.scanSkills();\n\n return { mcpConfigs, workflows, rulesCount, skills, skillConflicts };\n }\n\n /**\n * Migrate workspace configs to a target agent format.\n * @param items — optional list of specific item names (MCP servers / skills) to sync.\n * When provided, only matching items are included. Omit to sync all.\n */\n async migrate(target: AgentTarget, items?: string[]): Promise<WorkspaceSyncResult> {\n const scan = await this.scan();\n const result: WorkspaceSyncResult = {\n mcpServers: { scanned: [], generated: [] },\n workflows: { scanned: [], generated: [] },\n rules: { scanned: 0, generated: 0 },\n skills: { scanned: [], conflicts: [], copied: [], skipped: [] },\n };\n\n const itemFilter = items && items.length > 0\n ? new Set(items.map(i => i.toLowerCase()))\n : null;\n\n // 1. Merge all MCP servers from all sources (dedup by name)\n const allServers = new Map<string, MCPServerEntry>();\n for (const servers of Object.values(scan.mcpConfigs)) {\n for (const s of servers) {\n if (!allServers.has(s.name)) {\n if (!itemFilter || itemFilter.has(s.name.toLowerCase())) {\n allServers.set(s.name, s);\n }\n }\n }\n }\n result.mcpServers.scanned = Array.from(allServers.values());\n\n // Generate target MCP config (sanitize sensitive values in output)\n if (result.mcpServers.scanned.length > 0) {\n const adapter = this.adapters.get(target)!;\n const configContent = adapter.generate(result.mcpServers.scanned);\n const configPath = adapter.getConfigPath(this.projectRoot);\n result.mcpServers.generated.push({\n filePath: configPath,\n content: sanitize(configContent),\n });\n }\n\n // 2. Convert workflows to target format\n result.workflows.scanned = scan.workflows;\n if (scan.workflows.length > 0) {\n result.workflows.generated = this.workflowSyncer.convertAll(scan.workflows, target);\n }\n\n // 3. Rules sync\n try {\n const rules = await this.rulesSyncer.scanRules();\n result.rules.scanned = rules.length;\n if (rules.length > 0) {\n const deduped = this.rulesSyncer.deduplicateRules(rules);\n const ruleSource = this.agentToRuleSource(target);\n if (ruleSource) {\n const files = this.rulesSyncer.generateForTarget(deduped, ruleSource);\n result.rules.generated = files.length;\n }\n }\n } catch {\n // Rules may not exist\n }\n\n // 4. Skills sync (no format conversion, just copy folders)\n result.skills.scanned = itemFilter\n ? scan.skills.filter(sk => itemFilter.has(sk.name.toLowerCase()))\n : scan.skills;\n result.skills.conflicts = scan.skillConflicts;\n\n return result;\n }\n\n // ---- Private helpers ----\n\n /** Skills directories per agent */\n private static SKILLS_DIRS: Record<AgentTarget, string[]> = {\n codex: ['.codex/skills', '.agents/skills'],\n cursor: ['.cursor/skills', '.cursor/skills-cursor'],\n windsurf: ['.windsurf/skills'],\n 'claude-code': ['.claude/skills'],\n copilot: ['.github/skills', '.copilot/skills'],\n antigravity: ['.agent/skills', '.gemini/skills', '.gemini/antigravity/skills'],\n kiro: ['.kiro/skills'],\n };\n\n /** Get the target skills directory for an agent (null if agent has no skills support) */\n private getTargetSkillsDir(target: AgentTarget): string | null {\n const dirs = WorkspaceSyncEngine.SKILLS_DIRS[target];\n if (!dirs || dirs.length === 0) return null;\n return join(this.projectRoot, dirs[0]);\n }\n\n /**\n * Scan all agent skills directories and collect unique skills.\n */\n private scanSkills(): { skills: SkillEntry[]; conflicts: SkillConflict[] } {\n const skills: SkillEntry[] = [];\n const conflicts: SkillConflict[] = [];\n const seen = new Map<string, SkillEntry>();\n const home = homedir();\n\n for (const [agent, dirs] of Object.entries(WorkspaceSyncEngine.SKILLS_DIRS)) {\n for (const dir of dirs) {\n // Check project-level and global\n const paths = [\n join(this.projectRoot, dir),\n join(home, dir),\n ];\n\n for (const skillsRoot of paths) {\n if (!existsSync(skillsRoot)) continue;\n\n try {\n const entries = readdirSync(skillsRoot, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const skillMd = join(skillsRoot, entry.name, 'SKILL.md');\n if (!existsSync(skillMd)) continue;\n\n // Parse description from frontmatter\n let description = '';\n try {\n const content = readFileSync(skillMd, 'utf-8');\n const match = content.match(/^---[\\s\\S]*?description:\\s*[\"']?(.+?)[\"']?\\s*$/m);\n if (match) description = match[1];\n } catch { /* skip */ }\n\n const newEntry: SkillEntry = {\n name: entry.name,\n description,\n sourcePath: join(skillsRoot, entry.name),\n sourceAgent: agent as AgentTarget,\n };\n\n const existing = seen.get(entry.name);\n if (existing) {\n // Conflict: same name from different agent\n if (existing.sourceAgent !== agent) {\n conflicts.push({\n name: entry.name,\n kept: existing,\n skipped: newEntry,\n });\n }\n continue;\n }\n\n seen.set(entry.name, newEntry);\n skills.push(newEntry);\n }\n } catch { /* skip unreadable dirs */ }\n }\n }\n }\n\n return { skills, conflicts };\n }\n\n /**\n * Copy skills to a target agent's skills directory.\n * Returns list of copied skill names.\n */\n copySkills(skills: SkillEntry[], target: AgentTarget): { copied: string[]; skipped: string[] } {\n const targetDir = this.getTargetSkillsDir(target);\n const copied: string[] = [];\n const skipped: string[] = [];\n\n // Agent has no skills directory support (e.g. copilot)\n if (!targetDir) {\n return { copied, skipped };\n }\n\n for (const skill of skills) {\n // Don't copy a skill back to its own agent\n if (skill.sourceAgent === target) continue;\n\n const dest = join(targetDir, skill.name);\n if (existsSync(dest)) {\n skipped.push(`${skill.name} (already exists in ${target})`);\n continue;\n }\n\n try {\n mkdirSync(targetDir, { recursive: true });\n cpSync(skill.sourcePath, dest, { recursive: true });\n copied.push(skill.name);\n } catch { /* skip on error */ }\n }\n\n return { copied, skipped };\n }\n\n private scanWorkflows(): WorkflowEntry[] {\n const workflows: WorkflowEntry[] = [];\n const wfDir = join(this.projectRoot, '.windsurf', 'workflows');\n\n if (!existsSync(wfDir)) return workflows;\n\n try {\n const files = readdirSync(wfDir).filter((f) => f.endsWith('.md'));\n for (const file of files) {\n try {\n const content = readFileSync(join(wfDir, file), 'utf-8');\n workflows.push(this.workflowSyncer.parseWindsurfWorkflow(file, content));\n } catch {\n // Skip unreadable files\n }\n }\n } catch {\n // Directory read error\n }\n\n return workflows;\n }\n\n /**\n * Apply migration results to disk with backup and rollback.\n *\n * Safety features:\n * - Backs up every existing file before overwriting\n * - Atomic writes (temp → rename)\n * - Auto-rollback on any failure\n * - Returns backup paths for manual rollback if needed\n */\n async apply(target: AgentTarget, items?: string[]): Promise<ApplyResult & { migrationSummary: string }> {\n const syncResult = await this.migrate(target, items);\n const applier = new WorkspaceSyncApplier();\n\n // Collect all files to write\n const filesToWrite = [\n ...syncResult.mcpServers.generated,\n ...syncResult.workflows.generated,\n ];\n\n const applyResult = await applier.apply(filesToWrite);\n\n // Copy skills (no format conversion needed)\n let skillResult = { copied: [] as string[], skipped: [] as string[] };\n if (syncResult.skills.scanned.length > 0) {\n skillResult = this.copySkills(syncResult.skills.scanned, target);\n }\n\n // Build summary\n const lines: string[] = [];\n if (applyResult.success) {\n lines.push(`✅ Applied ${applyResult.filesWritten.length} file(s) for ${target}`);\n for (const f of applyResult.filesWritten) {\n lines.push(` → ${f}`);\n }\n if (skillResult.copied.length > 0) {\n lines.push(`\\n🧩 Copied ${skillResult.copied.length} skill(s):`);\n for (const sk of skillResult.copied) {\n lines.push(` → ${sk}`);\n }\n }\n if (skillResult.skipped.length > 0) {\n lines.push(`\\n⏭️ Skipped ${skillResult.skipped.length} skill(s):`);\n for (const sk of skillResult.skipped) {\n lines.push(` → ${sk}`);\n }\n }\n if (syncResult.skills.conflicts.length > 0) {\n lines.push(`\\n⚠️ Name conflicts (${syncResult.skills.conflicts.length}):`);\n for (const c of syncResult.skills.conflicts) {\n lines.push(` → \"${c.name}\": kept ${c.kept.sourceAgent}, skipped ${c.skipped.sourceAgent}`);\n }\n }\n if (applyResult.backups.length > 0) {\n lines.push(`\\n📦 Backups created (${applyResult.backups.length}):`);\n for (const b of applyResult.backups) {\n lines.push(` ${b.originalPath} → ${b.backupPath}`);\n }\n }\n // Clean up backups after successful apply\n applier.cleanBackups(applyResult.backups);\n } else {\n lines.push(`❌ Apply failed for ${target}`);\n for (const e of applyResult.errors) {\n lines.push(` Error: ${e}`);\n }\n if (applyResult.backups.length > 0) {\n lines.push(`\\n🔄 Rolled back ${applyResult.backups.length} file(s)`);\n }\n }\n\n return {\n ...applyResult,\n migrationSummary: lines.join('\\n'),\n };\n }\n\n // ---- Private helpers ----\n\n private agentToRuleSource(target: AgentTarget): RuleSource | null {\n const map: Record<AgentTarget, RuleSource> = {\n cursor: 'cursor',\n 'claude-code': 'claude-code',\n codex: 'codex',\n windsurf: 'windsurf',\n copilot: 'copilot',\n antigravity: 'antigravity',\n kiro: 'kiro',\n };\n return map[target] ?? null;\n }\n}\n","/**\n * Hook Installers\n *\n * Auto-detect installed agents and generate hook configurations.\n * Each agent has a different config format but the hook command is the same:\n * memorix hook\n *\n * The hook handler reads stdin JSON from the agent, normalizes it, and auto-stores.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { createRequire } from 'node:module';\nimport type { AgentName, AgentHookConfig } from '../types.js';\n\n/**\n * Resolve the hook command for the current platform.\n * On Windows, 'memorix' resolves to a .ps1 script that non-PowerShell\n * environments (like Windsurf hooks) can't execute.\n * Solution: use 'node /path/to/cli/index.js hook' instead.\n */\nfunction resolveHookCommand(): string {\n if (process.platform === 'win32') {\n // Try to find the CLI script path\n try {\n // 1. Check if running from source (development)\n const devPath = path.resolve(import.meta.dirname ?? __dirname, '../../cli/index.js');\n try {\n const fsStat = require('node:fs');\n if (fsStat.existsSync(devPath)) {\n return `node ${devPath.replace(/\\\\/g, '/')}`;\n }\n } catch { /* ignore */ }\n\n // 2. Find globally installed memorix\n const require_ = createRequire(import.meta.url);\n const pkgPath = require_.resolve('memorix/package.json');\n const cliPath = path.join(path.dirname(pkgPath), 'dist', 'cli', 'index.js');\n return `node ${cliPath.replace(/\\\\/g, '/')}`;\n } catch {\n // 3. Fallback: assume memorix is in PATH via cmd (not .ps1)\n return 'memorix';\n }\n }\n // On Unix, 'memorix' works directly\n return 'memorix';\n}\n\n/**\n * Generate Claude Code / VS Code Copilot hook config.\n * Both use the same format: .claude/settings.json or .github/hooks/*.json\n */\nfunction generateClaudeConfig(): Record<string, unknown> {\n const cmd = `${resolveHookCommand()} hook`;\n const hookEntry = {\n type: 'command',\n command: cmd,\n timeout: 10,\n };\n\n return {\n hooks: {\n SessionStart: [hookEntry],\n PostToolUse: [hookEntry],\n UserPromptSubmit: [hookEntry],\n PreCompact: [hookEntry],\n Stop: [hookEntry],\n },\n };\n}\n\n/**\n * Generate Windsurf Cascade hooks config.\n */\nfunction generateWindsurfConfig(): Record<string, unknown> {\n const cmd = `${resolveHookCommand()} hook`;\n const hookEntry = {\n command: cmd,\n show_output: false,\n };\n\n return {\n hooks: {\n post_write_code: [hookEntry],\n post_run_command: [hookEntry],\n post_mcp_tool_use: [hookEntry],\n pre_user_prompt: [hookEntry],\n post_cascade_response: [hookEntry],\n },\n };\n}\n\n/**\n * Generate Cursor hooks config.\n */\nfunction generateCursorConfig(): Record<string, unknown> {\n const cmd = `${resolveHookCommand()} hook`;\n return {\n hooks: {\n beforeSubmitPrompt: {\n command: cmd,\n },\n afterFileEdit: {\n command: cmd,\n },\n stop: {\n command: cmd,\n },\n },\n };\n}\n\n/**\n * Generate Kiro hooks config (Markdown + YAML format).\n */\nfunction generateKiroHookFile(): string {\n return `---\ntitle: Memorix Auto-Memory\ndescription: Automatically record development context for cross-agent memory sharing\nevent: file_saved\nfilePattern: \"**/*\"\n---\n\nRun the memorix hook command to analyze changes and store relevant memories:\n\n\\`\\`\\`bash\n${resolveHookCommand()} hook\n\\`\\`\\`\n`;\n}\n\n/**\n * Get the config file path for an agent (project-level).\n */\nfunction getProjectConfigPath(agent: AgentName, projectRoot: string): string {\n switch (agent) {\n case 'claude':\n case 'copilot':\n return path.join(projectRoot, '.github', 'hooks', 'memorix.json');\n case 'windsurf':\n return path.join(projectRoot, '.windsurf', 'hooks.json');\n case 'cursor':\n return path.join(projectRoot, '.cursor', 'hooks.json');\n case 'kiro':\n return path.join(projectRoot, '.kiro', 'hooks', 'memorix.hook.md');\n case 'codex':\n return path.join(projectRoot, '.codex', 'hooks.json');\n default:\n return path.join(projectRoot, '.memorix', 'hooks.json');\n }\n}\n\n/**\n * Get the global config file path for an agent.\n */\nfunction getGlobalConfigPath(agent: AgentName): string {\n const home = os.homedir();\n switch (agent) {\n case 'claude':\n case 'copilot':\n return path.join(home, '.claude', 'settings.json');\n case 'windsurf':\n return path.join(home, '.codeium', 'windsurf', 'hooks.json');\n case 'cursor':\n return path.join(home, '.cursor', 'hooks.json');\n default:\n return path.join(home, '.memorix', 'hooks.json');\n }\n}\n\n/**\n * Detect which agents are installed on the system.\n */\nexport async function detectInstalledAgents(): Promise<AgentName[]> {\n const agents: AgentName[] = [];\n const home = os.homedir();\n\n // Check for Claude Code\n const claudeDir = path.join(home, '.claude');\n try {\n await fs.access(claudeDir);\n agents.push('claude');\n } catch { /* not installed */ }\n\n // Check for Windsurf\n const windsurfDir = path.join(home, '.codeium', 'windsurf');\n try {\n await fs.access(windsurfDir);\n agents.push('windsurf');\n } catch { /* not installed */ }\n\n // Check for Cursor\n const cursorDir = path.join(home, '.cursor');\n try {\n await fs.access(cursorDir);\n agents.push('cursor');\n } catch { /* not installed */ }\n\n // Check for VS Code Copilot (if Claude Code is not detected)\n if (!agents.includes('claude')) {\n const vscodeDir = path.join(home, '.vscode');\n try {\n await fs.access(vscodeDir);\n agents.push('copilot');\n } catch { /* not installed */ }\n }\n\n // Check for Kiro\n const kiroConfig = path.join(home, '.kiro');\n try {\n await fs.access(kiroConfig);\n agents.push('kiro');\n } catch { /* not installed */ }\n\n // Check for Codex\n const codexDir = path.join(home, '.codex');\n try {\n await fs.access(codexDir);\n agents.push('codex');\n } catch { /* not installed */ }\n\n // Check for Antigravity (Google Gemini CLI)\n const antigravityDir = path.join(home, '.gemini', 'antigravity');\n try {\n await fs.access(antigravityDir);\n agents.push('antigravity');\n } catch { /* not installed */ }\n\n return agents;\n}\n\n/**\n * Install hooks for a specific agent.\n */\nexport async function installHooks(\n agent: AgentName,\n projectRoot: string,\n global = false,\n): Promise<AgentHookConfig> {\n const configPath = global\n ? getGlobalConfigPath(agent)\n : getProjectConfigPath(agent, projectRoot);\n\n let generated: Record<string, unknown> | string;\n\n switch (agent) {\n case 'claude':\n case 'copilot':\n generated = generateClaudeConfig();\n break;\n case 'windsurf':\n generated = generateWindsurfConfig();\n break;\n case 'cursor':\n generated = generateCursorConfig();\n break;\n case 'kiro':\n generated = generateKiroHookFile();\n break;\n default:\n generated = generateClaudeConfig(); // fallback\n }\n\n // Ensure directory exists\n await fs.mkdir(path.dirname(configPath), { recursive: true });\n\n if (agent === 'kiro') {\n // Kiro uses markdown files\n await fs.writeFile(configPath, generated as string, 'utf-8');\n } else {\n // JSON-based configs: merge with existing if present\n let existing: Record<string, unknown> = {};\n try {\n const content = await fs.readFile(configPath, 'utf-8');\n existing = JSON.parse(content);\n } catch { /* file doesn't exist yet */ }\n\n const merged = {\n ...existing,\n ...(generated as Record<string, unknown>),\n };\n\n await fs.writeFile(configPath, JSON.stringify(merged, null, 2), 'utf-8');\n }\n\n const events: Array<import('../types.js').HookEvent> = [];\n switch (agent) {\n case 'claude':\n case 'copilot':\n events.push('session_start', 'post_tool', 'user_prompt', 'pre_compact', 'session_end');\n break;\n case 'windsurf':\n events.push('post_edit', 'post_command', 'post_tool', 'user_prompt', 'post_response');\n break;\n case 'cursor':\n events.push('user_prompt', 'post_edit', 'session_end');\n break;\n case 'kiro':\n events.push('post_edit');\n break;\n }\n\n // Install agent rules alongside hooks\n await installAgentRules(agent, projectRoot);\n\n return {\n agent,\n configPath,\n events,\n generated: typeof generated === 'string' ? { content: generated } : generated,\n };\n}\n\n/**\n * Install memorix agent rules for a specific agent.\n * Rules instruct the agent to proactively use memorix for context continuity.\n */\nasync function installAgentRules(agent: AgentName, projectRoot: string): Promise<void> {\n const rulesContent = getAgentRulesContent();\n let rulesPath: string;\n\n switch (agent) {\n case 'windsurf':\n rulesPath = path.join(projectRoot, '.windsurf', 'rules', 'memorix.md');\n break;\n case 'cursor':\n rulesPath = path.join(projectRoot, '.cursor', 'rules', 'memorix.mdc');\n break;\n case 'claude':\n case 'copilot':\n rulesPath = path.join(projectRoot, '.github', 'copilot-instructions.md');\n break;\n case 'codex':\n rulesPath = path.join(projectRoot, 'AGENTS.md');\n break;\n case 'kiro':\n rulesPath = path.join(projectRoot, '.kiro', 'steering', 'memorix.md');\n break;\n default:\n // Antigravity and others\n rulesPath = path.join(projectRoot, '.agent', 'rules', 'memorix.md');\n break;\n }\n\n try {\n await fs.mkdir(path.dirname(rulesPath), { recursive: true });\n\n if (agent === 'codex') {\n // For Codex AGENTS.md, append rather than overwrite\n try {\n const existing = await fs.readFile(rulesPath, 'utf-8');\n if (existing.includes('Memorix')) {\n return; // Already contains memorix rules\n }\n // Append to existing AGENTS.md\n await fs.writeFile(rulesPath, existing + '\\n\\n' + rulesContent, 'utf-8');\n } catch {\n // File doesn't exist, create it\n await fs.writeFile(rulesPath, rulesContent, 'utf-8');\n }\n } else {\n // Only write if not already present\n try {\n await fs.access(rulesPath);\n // File exists — don't overwrite user customizations\n } catch {\n await fs.writeFile(rulesPath, rulesContent, 'utf-8');\n }\n }\n } catch { /* silent */ }\n}\n\n/**\n * Get the memorix agent rules content.\n */\nfunction getAgentRulesContent(): string {\n return `# Memorix — Automatic Memory Rules\n\nYou have access to Memorix memory tools. Follow these rules to maintain persistent context across sessions.\n\n## Session Start — Load Context\n\nAt the **beginning of every conversation**, before responding to the user:\n\n1. Call \\`memorix_search\\` with a query related to the user's first message or the current project\n2. If results are found, use \\`memorix_detail\\` to fetch the most relevant ones\n3. Reference relevant memories naturally in your response — the user should feel you \"remember\" them\n\nThis ensures you already know the project context without the user re-explaining.\n\n## During Session — Capture Important Context\n\n**Proactively** call \\`memorix_store\\` whenever any of the following happen:\n\n### Architecture & Decisions\n- Technology choice, framework selection, or design pattern adopted\n- Trade-off discussion with a clear conclusion\n- API design, database schema, or project structure decisions\n\n### Bug Fixes & Problem Solving\n- A bug is identified and resolved — store root cause + fix\n- Workaround applied for a known issue\n- Performance issue diagnosed and optimized\n\n### Gotchas & Pitfalls\n- Something unexpected or tricky is discovered\n- A common mistake is identified and corrected\n- Platform-specific behavior that caused issues\n\n### Configuration & Environment\n- Environment variables, port numbers, paths changed\n- Docker, nginx, Caddy, or reverse proxy config modified\n- Package dependencies added, removed, or version-pinned\n\n### Deployment & Operations\n- Server deployment steps (Docker, VPS, cloud)\n- DNS, SSL/TLS certificate, domain configuration\n- CI/CD pipeline setup or changes\n- Database migration or data transfer procedures\n- Server topology (ports, services, reverse proxy chain)\n- SSH keys, access credentials setup (store pattern, NOT secrets)\n\n### Project Milestones\n- Feature completed or shipped\n- Version released or published to npm/PyPI/etc.\n- Repository made public, README updated, PR submitted\n\nUse appropriate types: \\`decision\\`, \\`problem-solution\\`, \\`gotcha\\`, \\`what-changed\\`, \\`discovery\\`, \\`how-it-works\\`.\n\n## Session End — Store Summary\n\nWhen the conversation is ending or the user says goodbye:\n\n1. Call \\`memorix_store\\` with type \\`session-request\\` to record:\n - What was accomplished in this session\n - Current project state and any blockers\n - Pending tasks or next steps\n - Key files modified\n\nThis creates a \"handoff note\" for the next session (or for another AI agent).\n\n## Guidelines\n\n- **Don't store trivial information** (greetings, acknowledgments, simple file reads, ls/dir output)\n- **Do store anything you'd want to know if you lost all context**\n- **Do store anything a different AI agent would need to continue this work**\n- **Use concise titles** (~5-10 words) and structured facts\n- **Include file paths** in filesModified when relevant\n- **Include related concepts** for better searchability\n- **Prefer storing too much over too little** — the retention system will auto-decay stale memories\n`;\n}\n\n/**\n * Uninstall hooks for a specific agent.\n */\nexport async function uninstallHooks(\n agent: AgentName,\n projectRoot: string,\n global = false,\n): Promise<boolean> {\n const configPath = global\n ? getGlobalConfigPath(agent)\n : getProjectConfigPath(agent, projectRoot);\n\n try {\n if (agent === 'kiro') {\n await fs.unlink(configPath);\n } else {\n // For JSON configs, remove the hooks key\n const content = await fs.readFile(configPath, 'utf-8');\n const config = JSON.parse(content);\n delete config.hooks;\n\n if (Object.keys(config).length === 0) {\n await fs.unlink(configPath);\n } else {\n await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');\n }\n }\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check hook installation status for all agents.\n */\nexport async function getHookStatus(\n projectRoot: string,\n): Promise<Array<{ agent: AgentName; installed: boolean; configPath: string }>> {\n const results: Array<{ agent: AgentName; installed: boolean; configPath: string }> = [];\n const agents: AgentName[] = ['claude', 'copilot', 'windsurf', 'cursor', 'kiro', 'codex', 'antigravity'];\n\n for (const agent of agents) {\n const projectPath = getProjectConfigPath(agent, projectRoot);\n const globalPath = getGlobalConfigPath(agent);\n\n let installed = false;\n let usedPath = projectPath;\n\n try {\n await fs.access(projectPath);\n installed = true;\n } catch {\n try {\n await fs.access(globalPath);\n installed = true;\n usedPath = globalPath;\n } catch { /* not installed */ }\n }\n\n results.push({ agent, installed, configPath: usedPath });\n }\n\n return results;\n}\n","/**\n * Retention & Decay Engine\n *\n * Manages memory relevance over time using exponential decay.\n * Sources:\n * - mcp-memory-service: ExponentialDecayCalculator (importance × decay × access_boost)\n * - MemCP: Active → Archive → Purge lifecycle with immunity rules\n *\n * Relevance formula:\n * score = baseImportance × e^(-ageDays / retentionPeriod) × accessBoost × connectionBoost\n *\n * Immunity: observations with importance=critical, accessCount>=3, or tagged \"keep\"/\"pinned\"\n * are never auto-archived.\n */\n\nimport type { MemorixDocument } from '../types.js';\n\n// ── Importance → Retention Period mapping ────────────────────────────\n\nexport type ImportanceLevel = 'critical' | 'high' | 'medium' | 'low';\n\nconst RETENTION_DAYS: Record<ImportanceLevel, number> = {\n critical: 365,\n high: 180,\n medium: 90,\n low: 30,\n};\n\nconst BASE_IMPORTANCE: Record<ImportanceLevel, number> = {\n critical: 1.0,\n high: 0.8,\n medium: 0.5,\n low: 0.3,\n};\n\n// ── Observation Type → Default Importance ────────────────────────────\n\nconst TYPE_IMPORTANCE: Record<string, ImportanceLevel> = {\n gotcha: 'high',\n decision: 'high',\n 'trade-off': 'high',\n 'problem-solution': 'medium',\n 'how-it-works': 'medium',\n 'what-changed': 'medium',\n 'why-it-exists': 'medium',\n discovery: 'medium',\n 'session-request': 'low',\n};\n\n// ── Immunity ─────────────────────────────────────────────────────────\n\nconst PROTECTED_TAGS = new Set(['keep', 'important', 'pinned', 'critical']);\nconst MIN_ACCESS_FOR_IMMUNITY = 3;\n\n/**\n * Check if an observation is immune from archiving/decay.\n * Immune observations maintain a minimum relevance score.\n */\nexport function isImmune(doc: MemorixDocument): boolean {\n const importance = getImportanceLevel(doc);\n if (importance === 'critical' || importance === 'high') return true;\n if ((doc.accessCount ?? 0) >= MIN_ACCESS_FOR_IMMUNITY) return true;\n\n const concepts = doc.concepts?.split(', ').map((c) => c.toLowerCase()) ?? [];\n return concepts.some((c) => PROTECTED_TAGS.has(c));\n}\n\n// ── Relevance Scoring ────────────────────────────────────────────────\n\nexport interface RelevanceScore {\n observationId: number;\n totalScore: number;\n baseImportance: number;\n decayFactor: number;\n accessBoost: number;\n ageDays: number;\n isImmune: boolean;\n}\n\n/**\n * Get the importance level for an observation based on its type.\n */\nexport function getImportanceLevel(doc: MemorixDocument): ImportanceLevel {\n return TYPE_IMPORTANCE[doc.type] ?? 'medium';\n}\n\n/**\n * Calculate the relevance score for a single observation.\n *\n * Formula (from mcp-memory-service):\n * score = baseImportance × e^(-ageDays / retentionPeriod) × accessBoost\n *\n * Access boost (from mcp-memory-service):\n * 1 + 0.1 × accessCount (10% boost per access, capped at 2.0)\n */\nexport function calculateRelevance(\n doc: MemorixDocument,\n referenceTime?: Date,\n): RelevanceScore {\n const now = referenceTime ?? new Date();\n const importance = getImportanceLevel(doc);\n const base = BASE_IMPORTANCE[importance];\n const retention = RETENTION_DAYS[importance];\n\n // Age in days\n const createdAt = new Date(doc.createdAt);\n const ageDays = Math.max(0, (now.getTime() - createdAt.getTime()) / (1000 * 60 * 60 * 24));\n\n // Exponential decay\n const decayFactor = Math.exp(-ageDays / retention);\n\n // Access boost: 10% per access, capped at 2.0×\n const accessCount = doc.accessCount ?? 0;\n const accessBoost = Math.min(2.0, 1 + 0.1 * accessCount);\n\n let totalScore = base * decayFactor * accessBoost;\n\n // Immune observations get minimum 0.5 relevance\n const immune = isImmune(doc);\n if (immune) {\n totalScore = Math.max(totalScore, 0.5);\n }\n\n return {\n observationId: doc.observationId,\n totalScore,\n baseImportance: base,\n decayFactor,\n accessBoost,\n ageDays,\n isImmune: immune,\n };\n}\n\n/**\n * Score and rank observations by relevance.\n * Returns sorted (highest relevance first) with scores.\n */\nexport function rankByRelevance(\n docs: MemorixDocument[],\n referenceTime?: Date,\n): RelevanceScore[] {\n return docs\n .map((doc) => calculateRelevance(doc, referenceTime))\n .sort((a, b) => b.totalScore - a.totalScore);\n}\n\n// ── Retention Lifecycle ──────────────────────────────────────────────\n\nexport type RetentionZone = 'active' | 'stale' | 'archive-candidate';\n\n/**\n * Classify an observation into a retention zone.\n *\n * Lifecycle (from MemCP):\n * Active: recently accessed or high importance\n * Stale: not accessed, beyond 50% of retention period\n * Archive-candidate: not accessed, beyond 100% of retention period, not immune\n */\nexport function getRetentionZone(doc: MemorixDocument, referenceTime?: Date): RetentionZone {\n const now = referenceTime ?? new Date();\n const importance = getImportanceLevel(doc);\n const retention = RETENTION_DAYS[importance];\n\n const createdAt = new Date(doc.createdAt);\n const ageDays = (now.getTime() - createdAt.getTime()) / (1000 * 60 * 60 * 24);\n\n // Recently accessed = active regardless of age\n if (doc.lastAccessedAt) {\n const lastAccess = new Date(doc.lastAccessedAt);\n const daysSinceAccess = (now.getTime() - lastAccess.getTime()) / (1000 * 60 * 60 * 24);\n if (daysSinceAccess < 7) return 'active';\n }\n\n if (isImmune(doc)) return 'active';\n if (ageDays > retention) return 'archive-candidate';\n if (ageDays > retention * 0.5) return 'stale';\n return 'active';\n}\n\n/**\n * Get archive candidates from a list of observations.\n * Returns observations that are beyond their retention period and not immune.\n */\nexport function getArchiveCandidates(\n docs: MemorixDocument[],\n referenceTime?: Date,\n): MemorixDocument[] {\n return docs.filter((doc) => getRetentionZone(doc, referenceTime) === 'archive-candidate');\n}\n\n/**\n * Get retention summary statistics.\n */\nexport function getRetentionSummary(\n docs: MemorixDocument[],\n referenceTime?: Date,\n): { active: number; stale: number; archiveCandidates: number; immune: number } {\n let active = 0;\n let stale = 0;\n let archiveCandidates = 0;\n let immune = 0;\n\n for (const doc of docs) {\n const zone = getRetentionZone(doc, referenceTime);\n if (zone === 'active') active++;\n else if (zone === 'stale') stale++;\n else archiveCandidates++;\n if (isImmune(doc)) immune++;\n }\n\n return { active, stale, archiveCandidates, immune };\n}\n","/**\r\n * Skills Engine — Memory-Driven Project Skills\r\n *\r\n * Memorix's unique take on agent skills:\r\n * - Discovers existing SKILL.md files across all 7 agents\r\n * - Auto-generates project-specific skills from observation patterns\r\n * - Injects skill content directly into agent context (no file reading needed)\r\n *\r\n * Unlike generic skill marketplaces, these skills are derived from YOUR\r\n * project's actual history—decisions, gotchas, patterns, and solutions\r\n * that make this project unique.\r\n *\r\n * SKILL.md format (industry standard):\r\n * ---\r\n * description: Short description for tool use\r\n * ---\r\n * # Skill Title\r\n * Markdown instructions...\r\n */\r\n\r\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'node:fs';\r\nimport { join } from 'node:path';\r\nimport { homedir } from 'node:os';\r\nimport type { AgentTarget, SkillEntry } from '../types.js';\r\n\r\n// ============================================================\r\n// Types\r\n// ============================================================\r\n\r\n/** A skill with full content (for inject/generate) */\r\nexport interface SkillFull extends SkillEntry {\r\n content: string;\r\n /** Whether this was auto-generated from observations */\r\n generated: boolean;\r\n}\r\n\r\n/** Observation data for skill generation */\r\ninterface ObsData {\r\n id: number;\r\n entityName: string;\r\n type: string;\r\n title: string;\r\n narrative: string;\r\n facts?: string[];\r\n concepts?: string[];\r\n filesModified?: string[];\r\n createdAt?: string;\r\n}\r\n\r\n/** Entity cluster for skill generation */\r\ninterface EntityCluster {\r\n entity: string;\r\n observations: ObsData[];\r\n /** Types present in cluster */\r\n types: Set<string>;\r\n /** Score: higher = more skill-worthy */\r\n score: number;\r\n}\r\n\r\n// ============================================================\r\n// Skills Engine\r\n// ============================================================\r\n\r\n/** Skills directories per agent (same as workspace engine) */\r\nconst SKILLS_DIRS: Record<AgentTarget, string[]> = {\r\n codex: ['.codex/skills', '.agents/skills'],\r\n cursor: ['.cursor/skills', '.cursor/skills-cursor'],\r\n windsurf: ['.windsurf/skills'],\r\n 'claude-code': ['.claude/skills'],\r\n copilot: ['.github/skills', '.copilot/skills'],\r\n antigravity: ['.agent/skills', '.gemini/skills', '.gemini/antigravity/skills'],\r\n kiro: ['.kiro/skills'],\r\n};\r\n\r\n/** Types with high signal for skill generation */\r\nconst SKILL_WORTHY_TYPES = new Set([\r\n 'gotcha', 'decision', 'how-it-works', 'problem-solution', 'trade-off',\r\n]);\r\n\r\n/** Minimum observations needed per entity to generate a skill */\r\nconst MIN_OBS_FOR_SKILL = 3;\r\n\r\n/** Minimum score for skill generation */\r\nconst MIN_SCORE_FOR_SKILL = 5;\r\n\r\nexport class SkillsEngine {\r\n private skipGlobal: boolean;\r\n constructor(private projectRoot: string, options?: { skipGlobal?: boolean }) {\r\n this.skipGlobal = options?.skipGlobal ?? false;\r\n }\r\n\r\n // ============================================================\r\n // List: Discover all available skills\r\n // ============================================================\r\n\r\n /**\r\n * List all available skills from all agents + generated suggestions.\r\n */\r\n listSkills(): SkillFull[] {\r\n const skills: SkillFull[] = [];\r\n const seen = new Set<string>();\r\n const home = homedir();\r\n\r\n for (const [agent, dirs] of Object.entries(SKILLS_DIRS)) {\r\n for (const dir of dirs) {\r\n const paths = [join(this.projectRoot, dir)];\r\n if (!this.skipGlobal) {\r\n paths.push(join(home, dir));\r\n }\r\n\r\n for (const skillsRoot of paths) {\r\n if (!existsSync(skillsRoot)) continue;\r\n\r\n try {\r\n const entries = readdirSync(skillsRoot, { withFileTypes: true });\r\n for (const entry of entries) {\r\n if (!entry.isDirectory()) continue;\r\n const name = entry.name;\r\n if (seen.has(name)) continue;\r\n\r\n const skillMd = join(skillsRoot, name, 'SKILL.md');\r\n if (!existsSync(skillMd)) continue;\r\n\r\n try {\r\n const content = readFileSync(skillMd, 'utf-8');\r\n const description = this.parseDescription(content);\r\n\r\n skills.push({\r\n name,\r\n description,\r\n sourcePath: join(skillsRoot, name),\r\n sourceAgent: agent as AgentTarget,\r\n content,\r\n generated: false,\r\n });\r\n seen.add(name);\r\n } catch { /* skip unreadable */ }\r\n }\r\n } catch { /* skip unreadable dirs */ }\r\n }\r\n }\r\n }\r\n\r\n return skills;\r\n }\r\n\r\n // ============================================================\r\n // Generate: Create skills from observation patterns\r\n // ============================================================\r\n\r\n /**\r\n * Analyze observations and generate SKILL.md content for entities with\r\n * rich knowledge accumulation.\r\n */\r\n generateFromObservations(observations: ObsData[]): SkillFull[] {\r\n // 1. Cluster observations by entity\r\n const clusters = this.clusterByEntity(observations);\r\n\r\n // 2. Score each cluster for skill-worthiness\r\n for (const cluster of clusters.values()) {\r\n cluster.score = this.scoreCluster(cluster);\r\n }\r\n\r\n // 3. Generate skills for top clusters\r\n const results: SkillFull[] = [];\r\n const sortedClusters = [...clusters.values()]\r\n .filter(c => c.score >= MIN_SCORE_FOR_SKILL)\r\n .sort((a, b) => b.score - a.score)\r\n .slice(0, 10); // Max 10 auto-generated skills\r\n\r\n for (const cluster of sortedClusters) {\r\n const skill = this.clusterToSkill(cluster);\r\n if (skill) results.push(skill);\r\n }\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Write a generated skill to the target agent's skills directory.\r\n */\r\n writeSkill(skill: SkillFull, target: AgentTarget): string | null {\r\n const dirs = SKILLS_DIRS[target];\r\n if (!dirs || dirs.length === 0) return null;\r\n\r\n const targetDir = join(this.projectRoot, dirs[0], skill.name);\r\n\r\n try {\r\n mkdirSync(targetDir, { recursive: true });\r\n writeFileSync(join(targetDir, 'SKILL.md'), skill.content, 'utf-8');\r\n return join(dirs[0], skill.name, 'SKILL.md');\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n // ============================================================\r\n // Inject: Return skill content for direct agent consumption\r\n // ============================================================\r\n\r\n /**\r\n * Get full content of a skill by name (for direct injection).\r\n */\r\n injectSkill(name: string): SkillFull | null {\r\n const all = this.listSkills();\r\n return all.find(s => s.name.toLowerCase() === name.toLowerCase()) || null;\r\n }\r\n\r\n // ============================================================\r\n // Internal helpers\r\n // ============================================================\r\n\r\n private parseDescription(content: string): string {\r\n const match = content.match(/^---[\\s\\S]*?description:\\s*[\"']?(.+?)[\"']?\\s*$/m);\r\n return match ? match[1] : '';\r\n }\r\n\r\n private clusterByEntity(observations: ObsData[]): Map<string, EntityCluster> {\r\n const clusters = new Map<string, EntityCluster>();\r\n\r\n for (const obs of observations) {\r\n const entity = obs.entityName || 'unknown';\r\n let cluster = clusters.get(entity);\r\n if (!cluster) {\r\n cluster = { entity, observations: [], types: new Set(), score: 0 };\r\n clusters.set(entity, cluster);\r\n }\r\n cluster.observations.push(obs);\r\n cluster.types.add(obs.type);\r\n }\r\n\r\n return clusters;\r\n }\r\n\r\n private scoreCluster(cluster: EntityCluster): number {\r\n let score = 0;\r\n const obs = cluster.observations;\r\n\r\n // Base: need minimum observations\r\n if (obs.length < MIN_OBS_FOR_SKILL) return 0;\r\n\r\n // Must have at least one skill-worthy type (gotcha/decision/how-it-works/etc.)\r\n let hasSkillWorthyType = false;\r\n for (const type of cluster.types) {\r\n if (SKILL_WORTHY_TYPES.has(type)) {\r\n hasSkillWorthyType = true;\r\n break;\r\n }\r\n }\r\n if (!hasSkillWorthyType) return 0;\r\n\r\n // Volume bonus (1 point per obs, capped at 5)\r\n score += Math.min(obs.length, 5);\r\n\r\n // Type diversity bonus (3 points per unique skill-worthy type)\r\n for (const type of cluster.types) {\r\n if (SKILL_WORTHY_TYPES.has(type)) score += 3;\r\n }\r\n\r\n // Gotcha bonus (critical knowledge that MUST be preserved)\r\n const gotchas = obs.filter(o => o.type === 'gotcha').length;\r\n score += gotchas * 3;\r\n\r\n // Decision bonus (architecture choices that define patterns)\r\n const decisions = obs.filter(o => o.type === 'decision').length;\r\n score += decisions * 2;\r\n\r\n // Facts bonus (structured knowledge)\r\n const totalFacts = obs.reduce((sum, o) => sum + (o.facts?.length || 0), 0);\r\n score += Math.min(totalFacts, 5);\r\n\r\n // Files bonus (indicates real code involvement)\r\n const totalFiles = new Set(obs.flatMap(o => o.filesModified || [])).size;\r\n score += Math.min(totalFiles, 5);\r\n\r\n return score;\r\n }\r\n\r\n private clusterToSkill(cluster: EntityCluster): SkillFull | null {\r\n const { entity, observations } = cluster;\r\n const safeName = entity.replace(/[^a-zA-Z0-9_-]/g, '-').toLowerCase();\r\n\r\n // Group observations by type\r\n const gotchas = observations.filter(o => o.type === 'gotcha');\r\n const decisions = observations.filter(o => o.type === 'decision');\r\n const howItWorks = observations.filter(o => o.type === 'how-it-works');\r\n const problems = observations.filter(o => o.type === 'problem-solution');\r\n const tradeoffs = observations.filter(o => o.type === 'trade-off');\r\n const others = observations.filter(o =>\r\n !['gotcha', 'decision', 'how-it-works', 'problem-solution', 'trade-off'].includes(o.type),\r\n );\r\n\r\n // Collect all facts and concepts\r\n const allFacts = [...new Set(observations.flatMap(o => o.facts || []))];\r\n const allConcepts = [...new Set(observations.flatMap(o => o.concepts || []))];\r\n const allFiles = [...new Set(observations.flatMap(o => o.filesModified || []))];\r\n\r\n // Build SKILL.md content\r\n const lines: string[] = [];\r\n\r\n // Frontmatter\r\n const description = this.generateDescription(cluster);\r\n lines.push('---');\r\n lines.push(`description: ${description}`);\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // Title\r\n lines.push(`# ${entity}`);\r\n lines.push('');\r\n lines.push(`> Auto-generated from ${observations.length} project observations by Memorix.`);\r\n lines.push('> Adapt to your actual project context before relying on this skill.');\r\n lines.push('');\r\n\r\n // Key files\r\n if (allFiles.length > 0) {\r\n lines.push('## Key Files');\r\n lines.push('');\r\n for (const f of allFiles.slice(0, 15)) {\r\n lines.push(`- \\`${f}\\``);\r\n }\r\n lines.push('');\r\n }\r\n\r\n // Critical gotchas (most important — put first)\r\n if (gotchas.length > 0) {\r\n lines.push('## ⚠️ Critical Gotchas');\r\n lines.push('');\r\n for (const g of gotchas) {\r\n lines.push(`### ${g.title}`);\r\n if (g.narrative) lines.push('', g.narrative);\r\n if (g.facts && g.facts.length > 0) {\r\n lines.push('', ...g.facts.map(f => `- ${f}`));\r\n }\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Architecture decisions\r\n if (decisions.length > 0) {\r\n lines.push('## 🏗️ Architecture Decisions');\r\n lines.push('');\r\n for (const d of decisions) {\r\n lines.push(`### ${d.title}`);\r\n if (d.narrative) lines.push('', d.narrative);\r\n if (d.facts && d.facts.length > 0) {\r\n lines.push('', ...d.facts.map(f => `- ${f}`));\r\n }\r\n lines.push('');\r\n }\r\n }\r\n\r\n // How it works\r\n if (howItWorks.length > 0) {\r\n lines.push('## 📖 How It Works');\r\n lines.push('');\r\n for (const h of howItWorks) {\r\n lines.push(`### ${h.title}`);\r\n if (h.narrative) lines.push('', h.narrative);\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Common problems & solutions\r\n if (problems.length > 0) {\r\n lines.push('## 🔧 Common Problems & Solutions');\r\n lines.push('');\r\n for (const p of problems) {\r\n lines.push(`### ${p.title}`);\r\n if (p.narrative) lines.push('', p.narrative);\r\n if (p.facts && p.facts.length > 0) {\r\n lines.push('', ...p.facts.map(f => `- ${f}`));\r\n }\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Trade-offs\r\n if (tradeoffs.length > 0) {\r\n lines.push('## ⚖️ Trade-offs');\r\n lines.push('');\r\n for (const t of tradeoffs) {\r\n lines.push(`### ${t.title}`);\r\n if (t.narrative) lines.push('', t.narrative);\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Other notable observations\r\n if (others.length > 0) {\r\n lines.push('## 📝 Notes');\r\n lines.push('');\r\n for (const o of others.slice(0, 5)) {\r\n lines.push(`- **${o.title}**: ${o.narrative?.split('\\n')[0] || ''}`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n // Key concepts\r\n if (allConcepts.length > 0) {\r\n lines.push('## 🏷️ Related Concepts');\r\n lines.push('');\r\n lines.push(allConcepts.map(c => `\\`${c}\\``).join(', '));\r\n lines.push('');\r\n }\r\n\r\n // Quick facts summary\r\n if (allFacts.length > 0) {\r\n lines.push('## 📌 Quick Facts');\r\n lines.push('');\r\n for (const f of allFacts.slice(0, 15)) {\r\n lines.push(`- ${f}`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n const content = lines.join('\\n');\r\n\r\n return {\r\n name: safeName,\r\n description,\r\n sourcePath: '',\r\n sourceAgent: 'codex' as AgentTarget, // generated skills follow SKILL.md standard\r\n content,\r\n generated: true,\r\n };\r\n }\r\n\r\n private generateDescription(cluster: EntityCluster): string {\r\n const parts: string[] = [];\r\n const typeCounts: Record<string, number> = {};\r\n for (const obs of cluster.observations) {\r\n typeCounts[obs.type] = (typeCounts[obs.type] || 0) + 1;\r\n }\r\n\r\n if (typeCounts['gotcha']) parts.push(`${typeCounts['gotcha']} gotcha(s)`);\r\n if (typeCounts['decision']) parts.push(`${typeCounts['decision']} decision(s)`);\r\n if (typeCounts['how-it-works']) parts.push(`${typeCounts['how-it-works']} explanation(s)`);\r\n if (typeCounts['problem-solution']) parts.push(`${typeCounts['problem-solution']} fix(es)`);\r\n\r\n const summary = parts.length > 0 ? parts.join(', ') : `${cluster.observations.length} observations`;\r\n return `Project patterns for ${cluster.entity}: ${summary}`;\r\n }\r\n}\r\n","/**\r\n * Memorix Dashboard Server\r\n *\r\n * Lightweight HTTP server that serves:\r\n * - REST API endpoints for reading memorix data\r\n * - Static frontend files (SPA)\r\n *\r\n * Zero external dependencies — uses Node.js built-in http module.\r\n */\r\n\r\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\r\nimport { promises as fs } from 'node:fs';\r\nimport path from 'node:path';\r\nimport { exec } from 'node:child_process';\r\n\r\nimport { loadGraphJsonl, loadObservationsJson, saveObservationsJson, loadIdCounter, getBaseDataDir } from '../store/persistence.js';\r\n\r\n// MIME types for static file serving\r\nconst MIME_TYPES: Record<string, string> = {\r\n '.html': 'text/html; charset=utf-8',\r\n '.css': 'text/css; charset=utf-8',\r\n '.js': 'application/javascript; charset=utf-8',\r\n '.json': 'application/json; charset=utf-8',\r\n '.svg': 'image/svg+xml',\r\n '.png': 'image/png',\r\n '.ico': 'image/x-icon',\r\n};\r\n\r\n/**\r\n * Send a JSON response\r\n */\r\nfunction sendJson(res: ServerResponse, data: unknown, status = 200) {\r\n res.writeHead(status, {\r\n 'Content-Type': 'application/json; charset=utf-8',\r\n 'Access-Control-Allow-Origin': '*',\r\n });\r\n res.end(JSON.stringify(data));\r\n}\r\n\r\n/**\r\n * Send an error response\r\n */\r\nfunction sendError(res: ServerResponse, message: string, status = 500) {\r\n sendJson(res, { error: message }, status);\r\n}\r\n\r\n/**\r\n * Filter observations by projectId\r\n */\r\nfunction filterByProject<T extends { projectId?: string }>(items: T[], projectId: string): T[] {\r\n return items.filter(item => item.projectId === projectId);\r\n}\r\n\r\n/**\r\n * API route handlers\r\n */\r\nasync function handleApi(\r\n req: IncomingMessage,\r\n res: ServerResponse,\r\n dataDir: string,\r\n projectId: string,\r\n projectName: string,\r\n baseDir: string,\r\n) {\r\n const url = new URL(req.url || '/', `http://${req.headers.host}`);\r\n const apiPath = url.pathname.replace('/api', '');\r\n\r\n // Support ?project=xxx to switch view to another project\r\n const requestedProject = url.searchParams.get('project');\r\n let effectiveDataDir = dataDir;\r\n let effectiveProjectId = projectId;\r\n let effectiveProjectName = projectName;\r\n if (requestedProject && requestedProject !== projectId) {\r\n const sanitized = requestedProject.replace(/\\//g, '--').replace(/[<>:\"|?*\\\\]/g, '_');\r\n const candidateDir = path.join(baseDir, sanitized);\r\n try {\r\n await fs.access(candidateDir);\r\n effectiveDataDir = candidateDir;\r\n effectiveProjectId = requestedProject;\r\n effectiveProjectName = requestedProject.split('/').pop() || requestedProject;\r\n } catch {\r\n // requested project dir doesn't exist, fall through to default\r\n }\r\n }\r\n\r\n try {\r\n switch (apiPath) {\r\n case '/projects': {\r\n // List all project directories\r\n try {\r\n const entries = await fs.readdir(baseDir, { withFileTypes: true });\r\n const projects = entries\r\n .filter((e: { isDirectory: () => boolean; name: string }) =>\r\n e.isDirectory() && e.name.includes('--')) // Only git-based projects (owner--repo)\r\n .map((e: { name: string }) => {\r\n const dirName = e.name;\r\n const id = dirName.replace(/--/g, '/');\r\n return {\r\n id,\r\n name: id.split('/').pop() || id,\r\n dirName,\r\n isCurrent: id === projectId,\r\n };\r\n });\r\n sendJson(res, projects);\r\n } catch {\r\n sendJson(res, []);\r\n }\r\n break;\r\n }\r\n\r\n case '/project': {\r\n sendJson(res, { id: effectiveProjectId, name: effectiveProjectName });\r\n break;\r\n }\r\n\r\n case '/graph': {\r\n const graph = await loadGraphJsonl(effectiveDataDir);\r\n sendJson(res, graph);\r\n break;\r\n }\r\n\r\n case '/observations': {\r\n const allObs = await loadObservationsJson(effectiveDataDir);\r\n const observations = filterByProject(allObs as Array<{ projectId?: string }>, effectiveProjectId);\r\n sendJson(res, observations);\r\n break;\r\n }\r\n\r\n case '/stats': {\r\n const graph = await loadGraphJsonl(effectiveDataDir);\r\n const allObs = await loadObservationsJson(effectiveDataDir);\r\n const observations = filterByProject(allObs as Array<{ projectId?: string; type?: string; id?: number; createdAt?: string; title?: string; entityName?: string }>, effectiveProjectId);\r\n const nextId = await loadIdCounter(effectiveDataDir);\r\n\r\n // Type counts\r\n const typeCounts: Record<string, number> = {};\r\n for (const obs of observations) {\r\n const t = obs.type || 'unknown';\r\n typeCounts[t] = (typeCounts[t] || 0) + 1;\r\n }\r\n\r\n // Recent observations (last 10)\r\n const sorted = [...observations]\r\n .sort((a, b) => (b.id || 0) - (a.id || 0))\r\n .slice(0, 10);\r\n\r\n // Embedding provider status\r\n let embeddingStatus = { enabled: false, provider: '', dimensions: 0 };\r\n try {\r\n const { isEmbeddingEnabled } = await import('../store/orama-store.js');\r\n const { getEmbeddingProvider } = await import('../embedding/provider.js');\r\n const provider = await getEmbeddingProvider();\r\n embeddingStatus = {\r\n enabled: isEmbeddingEnabled(),\r\n provider: provider?.name || '',\r\n dimensions: provider?.dimensions || 0,\r\n };\r\n } catch { /* embedding module not available */ }\r\n\r\n sendJson(res, {\r\n entities: graph.entities.length,\r\n relations: graph.relations.length,\r\n observations: observations.length,\r\n nextId,\r\n typeCounts,\r\n recentObservations: sorted,\r\n embedding: embeddingStatus,\r\n });\r\n break;\r\n }\r\n\r\n case '/retention': {\r\n const allObs = await loadObservationsJson(effectiveDataDir) as Array<{\r\n id?: number;\r\n title?: string;\r\n type?: string;\r\n importance?: number;\r\n accessCount?: number;\r\n lastAccessedAt?: string;\r\n createdAt?: string;\r\n entityName?: string;\r\n projectId?: string;\r\n }>;\r\n const observations = filterByProject(allObs, effectiveProjectId);\r\n\r\n const now = Date.now();\r\n const scored = observations.map((obs) => {\r\n const age = now - new Date(obs.createdAt || now).getTime();\r\n const ageHours = age / (1000 * 60 * 60);\r\n const importance = obs.importance ?? 5;\r\n const accessCount = obs.accessCount ?? 0;\r\n\r\n // Exponential decay: score = importance * e^(-λt) + access_bonus\r\n const lambda = 0.01;\r\n const decayScore = importance * Math.exp(-lambda * ageHours);\r\n const accessBonus = Math.min(accessCount * 0.5, 3);\r\n const score = Math.min(decayScore + accessBonus, 10);\r\n\r\n // Immune if importance >= 8 or type is 'gotcha' or 'decision'\r\n const isImmune = importance >= 8 || obs.type === 'gotcha' || obs.type === 'decision';\r\n\r\n return {\r\n id: obs.id,\r\n title: obs.title,\r\n type: obs.type,\r\n entityName: obs.entityName,\r\n score: Math.round(score * 100) / 100,\r\n isImmune,\r\n ageHours: Math.round(ageHours * 10) / 10,\r\n accessCount,\r\n };\r\n });\r\n\r\n // Sort by score descending\r\n scored.sort((a, b) => b.score - a.score);\r\n\r\n const activeCount = scored.filter((s) => s.score >= 3).length;\r\n const staleCount = scored.filter((s) => s.score < 3 && s.score >= 1).length;\r\n const archiveCount = scored.filter((s) => s.score < 1).length;\r\n const immuneCount = scored.filter((s) => s.isImmune).length;\r\n\r\n sendJson(res, {\r\n summary: { active: activeCount, stale: staleCount, archive: archiveCount, immune: immuneCount },\r\n items: scored,\r\n });\r\n break;\r\n }\r\n\r\n default: {\r\n // Handle dynamic routes\r\n const deleteMatch = apiPath.match(/^\\/observations\\/(\\d+)$/);\r\n if (deleteMatch && req.method === 'DELETE') {\r\n const obsId = parseInt(deleteMatch[1], 10);\r\n const allObs = await loadObservationsJson(effectiveDataDir) as Array<{ id?: number;[k: string]: unknown }>;\r\n const idx = allObs.findIndex(o => o.id === obsId);\r\n if (idx === -1) {\r\n sendError(res, 'Observation not found', 404);\r\n } else {\r\n allObs.splice(idx, 1);\r\n await saveObservationsJson(effectiveDataDir, allObs);\r\n sendJson(res, { ok: true, deleted: obsId });\r\n }\r\n break;\r\n }\r\n\r\n if (apiPath === '/export') {\r\n const graph = await loadGraphJsonl(effectiveDataDir);\r\n const allObs = await loadObservationsJson(effectiveDataDir);\r\n const observations = filterByProject(allObs as Array<{ projectId?: string }>, effectiveProjectId);\r\n const nextId = await loadIdCounter(effectiveDataDir);\r\n const exportData = {\r\n project: { id: effectiveProjectId, name: effectiveProjectName },\r\n exportedAt: new Date().toISOString(),\r\n graph,\r\n observations,\r\n nextId,\r\n };\r\n res.writeHead(200, {\r\n 'Content-Type': 'application/json',\r\n 'Content-Disposition': `attachment; filename=\"memorix-${effectiveProjectId.replace(/\\//g, '-')}-export.json\"`,\r\n });\r\n res.end(JSON.stringify(exportData, null, 2));\r\n break;\r\n }\r\n\r\n sendError(res, 'Not found', 404);\r\n }\r\n }\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Unknown error';\r\n sendError(res, message);\r\n }\r\n}\r\n\r\n/**\r\n * Serve static files from the dashboard/static directory\r\n */\r\nasync function serveStatic(req: IncomingMessage, res: ServerResponse, staticDir: string) {\r\n let urlPath = new URL(req.url || '/', `http://${req.headers.host}`).pathname;\r\n\r\n // SPA: serve index.html for all non-file routes\r\n if (urlPath === '/' || !urlPath.includes('.')) {\r\n urlPath = '/index.html';\r\n }\r\n\r\n const filePath = path.join(staticDir, urlPath);\r\n\r\n // Security: prevent directory traversal\r\n if (!filePath.startsWith(staticDir)) {\r\n sendError(res, 'Forbidden', 403);\r\n return;\r\n }\r\n\r\n try {\r\n const data = await fs.readFile(filePath);\r\n const ext = path.extname(filePath);\r\n res.writeHead(200, {\r\n 'Content-Type': MIME_TYPES[ext] || 'application/octet-stream',\r\n 'Cache-Control': 'no-cache',\r\n });\r\n res.end(data);\r\n } catch {\r\n // Fallback to index.html for SPA routing\r\n try {\r\n const indexData = await fs.readFile(path.join(staticDir, 'index.html'));\r\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\r\n res.end(indexData);\r\n } catch {\r\n sendError(res, 'Not found', 404);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Start the dashboard server\r\n */\r\n\r\n/** Cross-platform open URL in default browser */\r\nfunction openBrowser(url: string) {\r\n const cmd =\r\n process.platform === 'win32' ? `start \"\" \"${url}\"` :\r\n process.platform === 'darwin' ? `open \"${url}\"` :\r\n `xdg-open \"${url}\"`;\r\n exec(cmd, () => { /* ignore errors */ });\r\n}\r\n\r\nexport async function startDashboard(\r\n dataDir: string,\r\n port: number,\r\n staticDir: string,\r\n projectId: string,\r\n projectName: string,\r\n autoOpen = true,\r\n): Promise<void> {\r\n const resolvedStaticDir = staticDir;\r\n // Derive baseDir from dataDir (parent directory of project-specific dir)\r\n const baseDir = getBaseDataDir();\r\n\r\n const server = createServer(async (req, res) => {\r\n const url = req.url || '/';\r\n\r\n if (url.startsWith('/api/')) {\r\n await handleApi(req, res, dataDir, projectId, projectName, baseDir);\r\n } else {\r\n await serveStatic(req, res, resolvedStaticDir);\r\n }\r\n });\r\n\r\n return new Promise((resolve, reject) => {\r\n server.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EADDRINUSE') {\r\n console.error(`Port ${port} is already in use. Try: memorix dashboard --port ${port + 1}`);\r\n reject(err);\r\n } else {\r\n reject(err);\r\n }\r\n });\r\n\r\n server.listen(port, () => {\r\n const url = `http://localhost:${port}`;\r\n console.error(`\\n Memorix Dashboard`);\r\n console.error(` ───────────────────────`);\r\n console.error(` Project: ${projectName} (${projectId})`);\r\n console.error(` Local: ${url}`);\r\n console.error(` Data dir: ${dataDir}`);\r\n console.error(`\\n Press Ctrl+C to stop\\n`);\r\n\r\n // Auto-open browser\r\n if (autoOpen) openBrowser(url);\r\n\r\n resolve();\r\n });\r\n });\r\n}\r\n","/**\n * Memorix MCP Server\n *\n * Registers all MCP tools and handles the server lifecycle.\n *\n * Tool sources:\n * - memorix_store / memorix_search / memorix_detail / memorix_timeline:\n * Memorix extensions using claude-mem's 3-layer Progressive Disclosure\n * - create_entities / create_relations / add_observations / delete_entities /\n * delete_observations / delete_relations / search_nodes / open_nodes / read_graph:\n * MCP Official Memory Server compatible interface (P1)\n *\n * Extensibility:\n * - New tools can be registered via server.registerTool()\n * - Rules sync tools will be added in P2\n * - New agent format adapters plug in without changing this file\n */\n\nimport { watch } from 'node:fs';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { KnowledgeGraphManager } from './memory/graph.js';\nimport { storeObservation, initObservations, reindexObservations } from './memory/observations.js';\nimport { resetDb } from './store/orama-store.js';\nimport { createAutoRelations } from './memory/auto-relations.js';\nimport { extractEntities } from './memory/entity-extractor.js';\nimport { compactSearch, compactTimeline, compactDetail } from './compact/engine.js';\nimport { detectProject } from './project/detector.js';\nimport { getProjectDataDir } from './store/persistence.js';\nimport type { ObservationType, RuleSource, AgentTarget, MCPServerEntry } from './types.js';\nimport { RulesSyncer } from './rules/syncer.js';\nimport { WorkspaceSyncEngine } from './workspace/engine.js';\n\n/** Valid observation types for input validation */\nconst OBSERVATION_TYPES: [string, ...string[]] = [\n 'session-request',\n 'gotcha',\n 'problem-solution',\n 'how-it-works',\n 'what-changed',\n 'discovery',\n 'why-it-exists',\n 'decision',\n 'trade-off',\n];\n\n/**\n * Create and configure the Memorix MCP Server.\n */\nexport async function createMemorixServer(cwd?: string): Promise<{\n server: McpServer;\n graphManager: KnowledgeGraphManager;\n projectId: string;\n}> {\n // Detect current project\n const project = detectProject(cwd);\n\n // Migrate legacy global data to project-specific directory (one-time, silent)\n try {\n const { migrateGlobalData } = await import('./store/persistence.js');\n const migrated = await migrateGlobalData(project.id);\n if (migrated) {\n console.error(`[memorix] Migrated legacy data to project directory: ${project.id}`);\n }\n } catch { /* migration is optional */ }\n\n const projectDir = await getProjectDataDir(project.id);\n\n // Initialize components\n const graphManager = new KnowledgeGraphManager(projectDir);\n await graphManager.init();\n await initObservations(projectDir);\n\n // Reindex existing observations into Orama\n const reindexed = await reindexObservations();\n if (reindexed > 0) {\n console.error(`[memorix] Reindexed ${reindexed} observations for project: ${project.id}`);\n }\n\n console.error(`[memorix] Project: ${project.id} (${project.name})`);\n console.error(`[memorix] Data dir: ${projectDir}`);\n\n // Auto-install hooks for newly detected agents (incremental, silent, non-blocking)\n try {\n const { getHookStatus, installHooks, detectInstalledAgents } = await import('./hooks/installers/index.js');\n const workDir = cwd ?? process.cwd();\n const statuses = await getHookStatus(workDir);\n const installedAgents = new Set(statuses.filter((s) => s.installed).map((s) => s.agent));\n const detectedAgents = await detectInstalledAgents();\n\n // Install hooks for each detected agent that isn't already installed\n for (const agent of detectedAgents) {\n if (installedAgents.has(agent)) continue; // already installed\n try {\n const config = await installHooks(agent, workDir);\n console.error(`[memorix] Auto-installed hooks for ${agent} → ${config.configPath}`);\n } catch { /* skip */ }\n }\n } catch { /* hooks install is optional */ }\n\n // Sync advisory: compute once per session, show on first memorix_search\n let syncAdvisoryShown = false;\n let syncAdvisory: string | null = null;\n try {\n const engine = new WorkspaceSyncEngine(project.rootPath);\n const scan = await engine.scan();\n const lines: string[] = [];\n\n // Count what's available from other agents\n const totalMCP = Object.values(scan.mcpConfigs).reduce((sum, arr) => sum + arr.length, 0);\n const totalSkills = scan.skills.length;\n const totalRules = scan.rulesCount;\n const totalWorkflows = scan.workflows.length;\n\n if (totalMCP > 0 || totalSkills > 0 || totalRules > 0 || totalWorkflows > 0) {\n lines.push('', '---', '🔄 **Cross-Agent Sync Available**');\n\n // Detail MCP servers per agent\n for (const [agent, servers] of Object.entries(scan.mcpConfigs)) {\n const list = servers as MCPServerEntry[];\n if (list.length > 0) {\n lines.push(`- **${agent}** MCP: ${list.map(s => s.name).join(', ')}`);\n }\n }\n\n // Detail skills per agent\n if (totalSkills > 0) {\n const byAgent = new Map<string, string[]>();\n for (const sk of scan.skills) {\n const arr = byAgent.get(sk.sourceAgent) || [];\n arr.push(sk.name);\n byAgent.set(sk.sourceAgent, arr);\n }\n for (const [agent, names] of byAgent) {\n lines.push(`- **${agent}** skills: ${names.join(', ')}`);\n }\n }\n if (scan.skillConflicts.length > 0) lines.push(` ⚠️ ${scan.skillConflicts.length} name conflict(s)`);\n if (totalRules > 0) lines.push(`- **${totalRules} rule(s)** found`);\n if (totalWorkflows > 0) lines.push(`- **${totalWorkflows} workflow(s)** found`);\n\n lines.push('');\n lines.push('⚠️ IMPORTANT INSTRUCTIONS FOR AI AGENT:');\n lines.push('1. Tell the user what configs/skills are available from other agents (list them).');\n lines.push('2. Ask which ones they want to sync.');\n lines.push('3. DO NOT manually copy files or run shell commands to sync.');\n lines.push('4. ONLY use `memorix_workspace_sync action=\"apply\" target=\"<agent>\"` to sync all,');\n lines.push(' or add `items=[\"name1\",\"name2\"]` to sync specific items selectively.');\n syncAdvisory = lines.join('\\n');\n }\n console.error(`[memorix] Sync advisory: ${syncAdvisory ? 'available' : 'nothing to sync'}`);\n } catch {\n // Sync scan is optional, don't block startup\n }\n\n // Watch for external writes (e.g., from hook processes) and hot-reload\n const observationsFile = projectDir + '/observations.json';\n let reloadDebounce: ReturnType<typeof setTimeout> | null = null;\n try {\n watch(observationsFile, () => {\n // Debounce: wait 500ms after last change before reloading\n if (reloadDebounce) clearTimeout(reloadDebounce);\n reloadDebounce = setTimeout(async () => {\n try {\n await resetDb(); // Clear Orama before re-inserting\n await initObservations(projectDir);\n const count = await reindexObservations();\n if (count > 0) {\n console.error(`[memorix] Hot-reloaded ${count} observations (external write detected)`);\n }\n } catch {\n // Silent — don't crash the server\n }\n }, 500);\n });\n console.error(`[memorix] Watching for external writes (hooks hot-reload enabled)`);\n } catch {\n console.error(`[memorix] Warning: could not watch observations file for hot-reload`);\n }\n\n // Create MCP server\n const server = new McpServer({\n name: 'memorix',\n version: '0.1.0',\n });\n\n // ================================================================\n // Memorix Extended Tools (3-layer Progressive Disclosure)\n // ================================================================\n\n /**\n * memorix_store — Store a new observation\n *\n * Primary write API. Agents call this to persist knowledge.\n * Auto-assigns ID, counts tokens, indexes for search.\n */\n server.registerTool(\n 'memorix_store',\n {\n title: 'Store Memory',\n description:\n 'Store a new observation/memory. Automatically indexed for search. ' +\n 'Use type to classify: gotcha (🔴 critical pitfall), decision (🟤 architecture choice), ' +\n 'problem-solution (🟡 bug fix), how-it-works (🔵 explanation), what-changed (🟢 change), ' +\n 'discovery (🟣 insight), why-it-exists (🟠 rationale), trade-off (⚖️ compromise), ' +\n 'session-request (🎯 original goal).',\n inputSchema: {\n entityName: z.string().describe('The entity this observation belongs to (e.g., \"auth-module\", \"port-config\")'),\n type: z.enum(OBSERVATION_TYPES).describe('Observation type for classification'),\n title: z.string().describe('Short descriptive title (~5-10 words)'),\n narrative: z.string().describe('Full description of the observation'),\n facts: z.array(z.string()).optional().describe('Structured facts (e.g., \"Default timeout: 60s\")'),\n filesModified: z.array(z.string()).optional().describe('Files involved'),\n concepts: z.array(z.string()).optional().describe('Related concepts/keywords'),\n },\n },\n async ({ entityName, type, title, narrative, facts, filesModified, concepts }) => {\n // Ensure entity exists in knowledge graph\n await graphManager.createEntities([\n { name: entityName, entityType: 'auto', observations: [] },\n ]);\n\n // Store the observation\n const obs = await storeObservation({\n entityName,\n type: type as ObservationType,\n title,\n narrative,\n facts,\n filesModified,\n concepts,\n projectId: project.id,\n });\n\n // Add a reference to the entity's observations\n await graphManager.addObservations([\n { entityName, contents: [`[#${obs.id}] ${title}`] },\n ]);\n\n // Implicit memory: auto-create relations from entity extraction\n const extracted = extractEntities([title, narrative, ...(facts ?? [])].join(' '));\n const autoRelCount = await createAutoRelations(obs, extracted, graphManager);\n\n // Build enrichment summary\n const enrichmentParts: string[] = [];\n const autoFiles = obs.filesModified.filter((f) => !(filesModified ?? []).includes(f));\n const autoConcepts = obs.concepts.filter((c) => !(concepts ?? []).includes(c));\n if (autoFiles.length > 0) enrichmentParts.push(`+${autoFiles.length} files extracted`);\n if (autoConcepts.length > 0) enrichmentParts.push(`+${autoConcepts.length} concepts enriched`);\n if (autoRelCount > 0) enrichmentParts.push(`+${autoRelCount} relations auto-created`);\n if (obs.hasCausalLanguage) enrichmentParts.push('causal language detected');\n const enrichment = enrichmentParts.length > 0 ? `\\nAuto-enriched: ${enrichmentParts.join(', ')}` : '';\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `✅ Stored observation #${obs.id} \"${title}\" (~${obs.tokens} tokens)\\nEntity: ${entityName} | Type: ${type} | Project: ${project.id}${enrichment}`,\n },\n ],\n };\n },\n );\n\n /**\n * memorix_search — Layer 1: Compact index search\n *\n * Returns a lightweight table of matching observations.\n * ~50-100 tokens per result. Agent scans this to decide what to fetch.\n */\n server.registerTool(\n 'memorix_search',\n {\n title: 'Search Memory',\n description:\n 'Search project memory. Returns a compact index (~50-100 tokens/result). ' +\n 'Use memorix_detail to fetch full content for specific IDs. ' +\n 'Use memorix_timeline to see chronological context.',\n inputSchema: {\n query: z.string().describe('Search query (natural language or keywords)'),\n limit: z.number().optional().describe('Max results (default: 20)'),\n type: z.enum(OBSERVATION_TYPES).optional().describe('Filter by observation type'),\n maxTokens: z.number().optional().describe('Token budget — trim results to fit (0 = unlimited)'),\n scope: z.enum(['project', 'global']).optional().describe(\n 'Search scope: \"project\" (default) only searches current project, \"global\" searches all projects',\n ),\n },\n },\n async ({ query, limit, type, maxTokens, scope }) => {\n const result = await compactSearch({\n query,\n limit,\n type: type as ObservationType | undefined,\n maxTokens,\n // Default to current project scope; 'global' removes the project filter\n projectId: scope === 'global' ? undefined : project.id,\n });\n\n // Append sync advisory on first search of the session\n let text = result.formatted;\n if (!syncAdvisoryShown && syncAdvisory) {\n text += syncAdvisory;\n syncAdvisoryShown = true;\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text,\n },\n ],\n };\n },\n );\n\n /**\n * memorix_timeline — Layer 2: Chronological context\n *\n * Shows observations before and after a specific anchor.\n * Helps agents understand the temporal context of an observation.\n */\n server.registerTool(\n 'memorix_timeline',\n {\n title: 'Memory Timeline',\n description:\n 'Get chronological context around a specific observation. ' +\n 'Shows what happened before and after the anchor observation.',\n inputSchema: {\n anchorId: z.number().describe('Observation ID to center the timeline on'),\n depthBefore: z.number().optional().describe('Number of observations before (default: 3)'),\n depthAfter: z.number().optional().describe('Number of observations after (default: 3)'),\n },\n },\n async ({ anchorId, depthBefore, depthAfter }) => {\n const result = await compactTimeline(\n anchorId,\n undefined,\n depthBefore,\n depthAfter,\n );\n\n return {\n content: [\n {\n type: 'text' as const,\n text: result.formatted,\n },\n ],\n };\n },\n );\n\n /**\n * memorix_detail — Layer 3: Full observation details\n *\n * Fetch complete observation content by IDs.\n * Only call after filtering via memorix_search / memorix_timeline.\n * ~500-1000 tokens per observation.\n */\n server.registerTool(\n 'memorix_detail',\n {\n title: 'Memory Details',\n description:\n 'Fetch full observation details by IDs (~500-1000 tokens each). ' +\n 'Always use memorix_search first to find relevant IDs, then fetch only what you need.',\n inputSchema: {\n ids: z.array(z.number()).describe('Observation IDs to fetch (from memorix_search results)'),\n },\n },\n async ({ ids }) => {\n const result = await compactDetail(ids);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: result.documents.length > 0\n ? result.formatted\n : `No observations found for IDs: ${ids.join(', ')}`,\n },\n ],\n };\n },\n );\n\n // ================================================================\n // Memorix Retention & Decay Tools (inspired by mcp-memory-service + MemCP)\n // ================================================================\n\n /**\n * memorix_retention — Memory retention status\n *\n * Shows which observations are active, stale, or candidates for archiving.\n * Uses exponential decay scoring from mcp-memory-service.\n */\n server.registerTool(\n 'memorix_retention',\n {\n title: 'Memory Retention Status',\n description:\n 'Show memory retention status: active/stale/archive-candidate counts, ' +\n 'immune observations, and top stale candidates. ' +\n 'Uses exponential decay scoring based on importance, age, and access patterns.',\n inputSchema: {},\n },\n async () => {\n const { getRetentionSummary, getArchiveCandidates, rankByRelevance } = await import('./memory/retention.js');\n const { search } = await import('@orama/orama');\n\n // Get all observations for this project\n const database = await (await import('./store/orama-store.js')).getDb();\n const allResults = await search(database, {\n term: '',\n where: {},\n limit: 10000,\n });\n const docs = allResults.hits.map((h) => h.document as unknown as import('./types.js').MemorixDocument);\n\n if (docs.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No observations found for this project.' }],\n };\n }\n\n const summary = getRetentionSummary(docs);\n const candidates = getArchiveCandidates(docs);\n const ranked = rankByRelevance(docs);\n\n // Format output\n const lines: string[] = [\n `## Memory Retention Status`,\n ``,\n `| Zone | Count |`,\n `|------|-------|`,\n `| Active | ${summary.active} |`,\n `| Stale | ${summary.stale} |`,\n `| Archive Candidates | ${summary.archiveCandidates} |`,\n `| Immune | ${summary.immune} |`,\n `| **Total** | **${docs.length}** |`,\n ``,\n ];\n\n if (candidates.length > 0) {\n lines.push(`### Archive Candidates (${candidates.length})`);\n lines.push(`| ID | Title | Age (days) | Access |`);\n lines.push(`|----|-------|-----------|--------|`);\n for (const c of candidates.slice(0, 10)) {\n const ageDays = Math.round(\n (Date.now() - new Date(c.createdAt).getTime()) / (1000 * 60 * 60 * 24),\n );\n lines.push(`| ${c.observationId} | ${c.title} | ${ageDays}d | ${c.accessCount ?? 0}× |`);\n }\n lines.push('');\n }\n\n // Top 5 most relevant\n lines.push(`### Top 5 Most Relevant`);\n lines.push(`| ID | Title | Score | Decay | Access Boost |`);\n lines.push(`|----|-------|-------|-------|-------------|`);\n for (const r of ranked.slice(0, 5)) {\n const doc = docs.find((d) => d.observationId === r.observationId);\n lines.push(\n `| ${r.observationId} | ${doc?.title ?? '?'} | ${r.totalScore.toFixed(3)} | ${r.decayFactor.toFixed(3)} | ${r.accessBoost.toFixed(1)}× |`,\n );\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n },\n );\n\n // ================================================================\n // MCP Official Memory Server Compatible Tools\n // ================================================================\n\n /** create_entities — MCP Official compatible */\n server.registerTool(\n 'create_entities',\n {\n title: 'Create Entities',\n description: 'Create multiple new entities in the knowledge graph',\n inputSchema: {\n entities: z.array(z.object({\n name: z.string().describe('The name of the entity'),\n entityType: z.string().describe('The type of the entity'),\n observations: z.array(z.string()).describe('Initial observations'),\n })),\n },\n },\n async ({ entities }) => {\n const result = await graphManager.createEntities(entities);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n\n /** create_relations — MCP Official compatible, enhanced with typed relation suggestions */\n server.registerTool(\n 'create_relations',\n {\n title: 'Create Relations',\n description:\n 'Create multiple new relations between entities in the knowledge graph. Relations should be in active voice. ' +\n 'Recommended relation types (from mcp-memory-service): causes, fixes, supports, opposes, contradicts, ' +\n 'depends_on, implements, extends, replaces, documents',\n inputSchema: {\n relations: z.array(z.object({\n from: z.string().describe('Source entity name'),\n to: z.string().describe('Target entity name'),\n relationType: z.string().describe('Type of relation (e.g., causes, fixes, supports, depends_on, implements)'),\n })),\n },\n },\n async ({ relations }) => {\n const result = await graphManager.createRelations(relations);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n\n /** add_observations — MCP Official compatible */\n server.registerTool(\n 'add_observations',\n {\n title: 'Add Observations',\n description: 'Add new observations to existing entities in the knowledge graph',\n inputSchema: {\n observations: z.array(z.object({\n entityName: z.string().describe('Entity name to add observations to'),\n contents: z.array(z.string()).describe('Observation contents to add'),\n })),\n },\n },\n async ({ observations }) => {\n const result = await graphManager.addObservations(observations);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n\n /** delete_entities — MCP Official compatible */\n server.registerTool(\n 'delete_entities',\n {\n title: 'Delete Entities',\n description: 'Delete multiple entities and their associated relations from the knowledge graph',\n inputSchema: {\n entityNames: z.array(z.string()).describe('Entity names to delete'),\n },\n },\n async ({ entityNames }) => {\n await graphManager.deleteEntities(entityNames);\n return {\n content: [{ type: 'text' as const, text: 'Entities deleted successfully' }],\n };\n },\n );\n\n /** delete_observations — MCP Official compatible */\n server.registerTool(\n 'delete_observations',\n {\n title: 'Delete Observations',\n description: 'Delete specific observations from entities in the knowledge graph',\n inputSchema: {\n deletions: z.array(z.object({\n entityName: z.string().describe('Entity containing the observations'),\n observations: z.array(z.string()).describe('Observations to delete'),\n })),\n },\n },\n async ({ deletions }) => {\n await graphManager.deleteObservations(deletions);\n return {\n content: [{ type: 'text' as const, text: 'Observations deleted successfully' }],\n };\n },\n );\n\n /** delete_relations — MCP Official compatible */\n server.registerTool(\n 'delete_relations',\n {\n title: 'Delete Relations',\n description: 'Delete multiple relations from the knowledge graph',\n inputSchema: {\n relations: z.array(z.object({\n from: z.string(),\n to: z.string(),\n relationType: z.string(),\n })),\n },\n },\n async ({ relations }) => {\n await graphManager.deleteRelations(relations);\n return {\n content: [{ type: 'text' as const, text: 'Relations deleted successfully' }],\n };\n },\n );\n\n /** read_graph — MCP Official compatible */\n server.registerTool(\n 'read_graph',\n {\n title: 'Read Graph',\n description: 'Read the entire knowledge graph',\n inputSchema: {},\n },\n async () => {\n const graph = await graphManager.readGraph();\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(graph, null, 2) }],\n };\n },\n );\n\n /** search_nodes — MCP Official compatible (basic string search) */\n server.registerTool(\n 'search_nodes',\n {\n title: 'Search Nodes',\n description: 'Search for nodes in the knowledge graph based on a query',\n inputSchema: {\n query: z.string().describe('Search query to match against entity names, types, and observations'),\n },\n },\n async ({ query }) => {\n const graph = await graphManager.searchNodes(query);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(graph, null, 2) }],\n };\n },\n );\n\n /** open_nodes — MCP Official compatible */\n server.registerTool(\n 'open_nodes',\n {\n title: 'Open Nodes',\n description: 'Open specific nodes in the knowledge graph by their names',\n inputSchema: {\n names: z.array(z.string()).describe('Entity names to retrieve'),\n },\n },\n async ({ names }) => {\n const graph = await graphManager.openNodes(names);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(graph, null, 2) }],\n };\n },\n );\n\n // ============================================================\n // Rules Sync Tool (P2 — Memorix differentiator)\n // ============================================================\n\n const RULE_SOURCES: [string, ...string[]] = ['cursor', 'claude-code', 'codex', 'windsurf', 'antigravity', 'copilot'];\n\n /** memorix_rules_sync — scan, dedup, and generate rules across agents */\n server.registerTool(\n 'memorix_rules_sync',\n {\n title: 'Rules Sync',\n description:\n 'Scan project for agent rule files (Cursor, Claude Code, Codex, Windsurf, Antigravity, Copilot), ' +\n 'deduplicate, detect conflicts, and optionally generate rules for a target agent format. ' +\n 'Without target: returns sync status report. With target: generates converted rule files.',\n inputSchema: {\n action: z.enum(['status', 'generate']).describe('Action: \"status\" for report, \"generate\" to produce target files'),\n target: z.enum(RULE_SOURCES).optional().describe('Target agent format for generation (required when action=generate)'),\n },\n },\n async ({ action, target }) => {\n const syncer = new RulesSyncer(project.rootPath);\n\n if (action === 'status') {\n const status = await syncer.syncStatus();\n const lines = [\n `## Rules Sync Status`,\n ``,\n `**Sources found:** ${status.sources.join(', ') || 'none'}`,\n `**Total rules:** ${status.totalRules}`,\n `**Unique rules:** ${status.uniqueRules}`,\n `**Conflicts:** ${status.conflicts.length}`,\n ];\n\n if (status.conflicts.length > 0) {\n lines.push('', '### Conflicts');\n for (const c of status.conflicts) {\n lines.push(`- **${c.ruleA.source}** \\`${c.ruleA.id}\\` vs **${c.ruleB.source}** \\`${c.ruleB.id}\\`: ${c.reason}`);\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n }\n\n // action === 'generate'\n if (!target) {\n return {\n content: [{ type: 'text' as const, text: 'Error: target is required for generate action' }],\n isError: true,\n };\n }\n\n const rules = await syncer.scanRules();\n const deduped = syncer.deduplicateRules(rules);\n const files = syncer.generateForTarget(deduped, target as RuleSource);\n\n const lines = [\n `## Generated ${files.length} file(s) for ${target}`,\n '',\n ];\n for (const f of files) {\n lines.push(`### \\`${f.filePath}\\``, '```', f.content, '```', '');\n }\n lines.push('> Use these contents to create the rule files in your project.');\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n },\n );\n\n // ============================================================\n // Workspace Sync Tool (P3 — Cross-Agent Workspace Bridge)\n // ============================================================\n\n const AGENT_TARGETS: [string, ...string[]] = ['windsurf', 'cursor', 'claude-code', 'codex', 'copilot', 'antigravity'];\n\n /** memorix_workspace_sync — migrate entire workspace config across agents */\n server.registerTool(\n 'memorix_workspace_sync',\n {\n title: 'Workspace Sync',\n description:\n 'Migrate your entire workspace environment between AI agents. ' +\n 'Syncs MCP server configs, workflows, rules, and skills. ' +\n 'Action \"scan\": detect all workspace configs. ' +\n 'Action \"migrate\": generate configs for target agent (preview only). ' +\n 'Action \"apply\": migrate AND write configs to disk with backup/rollback.',\n inputSchema: {\n action: z.enum(['scan', 'migrate', 'apply']).describe('Action: \"scan\" to detect configs, \"migrate\" to preview, \"apply\" to write to disk'),\n target: z.enum(AGENT_TARGETS).optional().describe('Target agent for migration (required for migrate)'),\n items: z.array(z.string()).optional().describe('Selective sync: list specific MCP server or skill names to sync (e.g. [\"figma-remote-mcp-server\", \"create-subagent\"]). Omit to sync all.'),\n },\n },\n async ({ action, target, items }) => {\n const engine = new WorkspaceSyncEngine(project.rootPath);\n\n if (action === 'scan') {\n const scan = await engine.scan();\n const lines = [\n `## Workspace Scan Report`,\n '',\n `### MCP Server Configs`,\n ];\n\n for (const [agent, servers] of Object.entries(scan.mcpConfigs)) {\n if ((servers as MCPServerEntry[]).length > 0) {\n lines.push(`- **${agent}**: ${(servers as MCPServerEntry[]).length} server(s) — ${(servers as MCPServerEntry[]).map((s: MCPServerEntry) => s.name).join(', ')}`);\n }\n }\n\n lines.push('', `### Workflows`);\n if (scan.workflows.length > 0) {\n for (const wf of scan.workflows) {\n lines.push(`- **${wf.name}** (${wf.source}): ${wf.description || '(no description)'}`);\n }\n } else {\n lines.push('- No workflows found');\n }\n\n lines.push('', `### Rules`);\n lines.push(`- ${scan.rulesCount} rule(s) detected across all agents`);\n\n lines.push('', `### Skills`);\n if (scan.skills.length > 0) {\n for (const sk of scan.skills) {\n lines.push(`- **${sk.name}** (${sk.sourceAgent}): ${sk.description || '(no description)'}`);\n }\n } else {\n lines.push('- No skills found');\n }\n\n if (scan.skillConflicts.length > 0) {\n lines.push('', `### ⚠️ Skill Name Conflicts`);\n for (const c of scan.skillConflicts) {\n lines.push(`- **${c.name}**: kept from ${c.kept.sourceAgent}, duplicate in ${c.skipped.sourceAgent}`);\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n }\n\n // action === 'migrate' or 'apply' — both need target\n if (!target) {\n return {\n content: [{ type: 'text' as const, text: 'Error: target is required for migrate/apply action' }],\n isError: true,\n };\n }\n\n if (action === 'apply') {\n const applyResult = await engine.apply(target as AgentTarget, items);\n return {\n content: [{ type: 'text' as const, text: applyResult.migrationSummary }],\n ...(applyResult.success ? {} : { isError: true }),\n };\n }\n\n // action === 'migrate' (preview only)\n const result = await engine.migrate(target as AgentTarget, items);\n const lines = [\n `## Workspace Migration → ${target}`,\n '',\n ];\n\n if (result.mcpServers.generated.length > 0) {\n lines.push('### MCP Config');\n for (const f of result.mcpServers.generated) {\n lines.push(`#### \\`${f.filePath}\\``, '```', f.content, '```', '');\n }\n }\n\n if (result.workflows.generated.length > 0) {\n lines.push('### Workflows');\n for (const f of result.workflows.generated) {\n lines.push(`#### \\`${f.filePath}\\``, '```', f.content, '```', '');\n }\n }\n\n if (result.rules.generated > 0) {\n lines.push(`### Rules`, `- ${result.rules.generated} rule file(s) generated`);\n }\n\n if (result.skills.scanned.length > 0) {\n lines.push('### Skills', `- ${result.skills.scanned.length} skill(s) found, ready to copy:`);\n for (const sk of result.skills.scanned) {\n lines.push(` - **${sk.name}** (from ${sk.sourceAgent})`);\n }\n }\n\n lines.push('', '> Review the generated configs above. Use action \"apply\" to write them to disk.');\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n },\n );\n\n // ============================================================\n // memorix_skills — Memory-driven project skills\n // ============================================================\n\n server.registerTool(\n 'memorix_skills',\n {\n title: 'Project Skills',\n description:\n 'Memory-driven project skills. ' +\n 'Action \"list\": show all available skills from all agents. ' +\n 'Action \"generate\": auto-generate project-specific skills from observation patterns (gotchas, decisions, how-it-works). ' +\n 'Action \"inject\": return a specific skill\\'s full content for direct use. ' +\n 'Generated skills follow the SKILL.md standard and can be synced across agents.',\n inputSchema: {\n action: z.enum(['list', 'generate', 'inject']).describe('Action: \"list\" to discover skills, \"generate\" to create from memory, \"inject\" to get skill content'),\n name: z.string().optional().describe('Skill name (required for \"inject\")'),\n target: z.enum(AGENT_TARGETS).optional().describe('Target agent to write generated skills to (optional for \"generate\")'),\n write: z.boolean().optional().describe('Whether to write generated skills to disk (default: false, preview only)'),\n },\n },\n async ({ action, name, target, write }) => {\n const { SkillsEngine } = await import('./skills/engine.js');\n const engine = new SkillsEngine(project.rootPath);\n\n if (action === 'list') {\n const skills = engine.listSkills();\n if (skills.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No skills found in any agent directory.\\n\\nSkills are discovered from:\\n- `.cursor/skills/*/SKILL.md`\\n- `.agents/skills/*/SKILL.md`\\n- `.agent/skills/*/SKILL.md`\\n- `.windsurf/skills/*/SKILL.md`\\n- etc.\\n\\nUse action \"generate\" to auto-create skills from your project observations.' }],\n };\n }\n\n const lines = [\n `## Available Skills (${skills.length})`,\n '',\n ];\n for (const sk of skills) {\n lines.push(`- **${sk.name}** (${sk.sourceAgent}): ${sk.description || '(no description)'}`);\n }\n lines.push('', '> Use `action: \"inject\", name: \"<skill-name>\"` to get full skill content.');\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n }\n\n if (action === 'inject') {\n if (!name) {\n return {\n content: [{ type: 'text' as const, text: 'Error: `name` is required for inject action. Use `action: \"list\"` first to see available skills.' }],\n isError: true,\n };\n }\n\n const skill = engine.injectSkill(name);\n if (!skill) {\n return {\n content: [{ type: 'text' as const, text: `Skill \"${name}\" not found. Use \\`action: \"list\"\\` to see available skills.` }],\n isError: true,\n };\n }\n\n return {\n content: [{ type: 'text' as const, text: `## Skill: ${skill.name}\\n**Source**: ${skill.sourceAgent}\\n**Path**: ${skill.sourcePath}\\n\\n---\\n\\n${skill.content}` }],\n };\n }\n\n // action === 'generate'\n const { loadObservationsJson } = await import('./store/persistence.js');\n const allObs = await loadObservationsJson(projectDir) as Array<{\n id?: number; entityName?: string; type?: string; title?: string;\n narrative?: string; facts?: string[]; concepts?: string[];\n filesModified?: string[]; createdAt?: string;\n }>;\n\n const obsData = allObs.map(o => ({\n id: o.id || 0,\n entityName: o.entityName || 'unknown',\n type: o.type || 'discovery',\n title: o.title || '',\n narrative: o.narrative || '',\n facts: o.facts,\n concepts: o.concepts,\n filesModified: o.filesModified,\n createdAt: o.createdAt,\n }));\n\n const generated = engine.generateFromObservations(obsData);\n\n if (generated.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No skill-worthy patterns found yet.\\n\\nSkills are auto-generated when entities accumulate enough observations (3+), especially gotchas, decisions, and how-it-works notes.\\n\\nKeep using memorix_store to build up project knowledge!' }],\n };\n }\n\n const lines = [\n `## Generated Skills (${generated.length})`,\n '',\n 'Based on observation patterns in your project memory:',\n '',\n ];\n\n for (const sk of generated) {\n lines.push(`### ${sk.name}`);\n lines.push(`- **Description**: ${sk.description}`);\n lines.push(`- **Observations**: ${sk.content.split('\\n').length} lines of knowledge`);\n\n if (write && target) {\n const path = engine.writeSkill(sk, target as AgentTarget);\n if (path) {\n lines.push(`- ✅ **Written**: \\`${path}\\``);\n } else {\n lines.push(`- ❌ Failed to write`);\n }\n }\n lines.push('');\n }\n\n if (!write) {\n lines.push('> Preview only. Add `write: true, target: \"<agent>\"` to save skills to disk.');\n }\n\n // Show first generated skill as preview\n if (generated.length > 0) {\n lines.push('', '---', '### Preview: ' + generated[0].name, '', '```markdown', generated[0].content, '```');\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n },\n );\n\n // ============================================================\n // memorix_dashboard — Launch the web dashboard\n // ============================================================\n\n let dashboardRunning = false;\n\n server.registerTool(\n 'memorix_dashboard',\n {\n title: 'Launch Dashboard',\n description:\n 'Launch the Memorix Web Dashboard in the browser. ' +\n 'Shows knowledge graph, observations, retention scores, and project stats in a visual interface.',\n inputSchema: {\n port: z.number().optional().describe('Port to run the dashboard on (default: 3210)'),\n },\n },\n async ({ port: dashboardPort }) => {\n const portNum = (dashboardPort as number) || 3210;\n const url = `http://localhost:${portNum}`;\n\n if (dashboardRunning) {\n const { exec } = await import('node:child_process');\n const cmd =\n process.platform === 'win32' ? `start \"\" \"${url}\"` :\n process.platform === 'darwin' ? `open \"${url}\"` :\n `xdg-open \"${url}\"`;\n exec(cmd, () => { });\n return {\n content: [{ type: 'text' as const, text: `Dashboard is already running at ${url}. Opened in browser.` }],\n };\n }\n\n try {\n const pathMod = await import('node:path');\n const fsMod = await import('node:fs');\n const { fileURLToPath } = await import('node:url');\n const { startDashboard } = await import('./dashboard/server.js');\n\n // Try multiple strategies to find the static files directory\n // When running from CLI (dist/cli/index.js), __dirname = dist/cli/, need to go up\n const candidates = [\n pathMod.default.join(__dirname, '..', 'dashboard', 'static'),\n pathMod.default.join(__dirname, 'dashboard', 'static'),\n pathMod.default.join(pathMod.default.dirname(fileURLToPath(import.meta.url)), '..', 'dashboard', 'static'),\n pathMod.default.join(pathMod.default.dirname(fileURLToPath(import.meta.url)), 'dashboard', 'static'),\n ];\n\n // Log all candidates for debugging\n for (const [i, c] of candidates.entries()) {\n const hasIndex = fsMod.existsSync(pathMod.default.join(c, 'index.html'));\n console.error(`[memorix] candidate[${i}]: ${c} (has index.html: ${hasIndex})`);\n }\n\n let staticDir = candidates[0];\n for (const c of candidates) {\n if (fsMod.existsSync(pathMod.default.join(c, 'index.html'))) {\n staticDir = c;\n break;\n }\n }\n console.error(`[memorix] Dashboard staticDir: ${staticDir}`);\n\n // Start in background (non-blocking), disable auto-open (we'll open it ourselves)\n startDashboard(projectDir, portNum, staticDir, project.id, project.name, false)\n .then(() => { dashboardRunning = true; })\n .catch((err) => { console.error('[memorix] Dashboard error:', err); dashboardRunning = false; });\n\n // Wait for the server to start, then open browser\n await new Promise(resolve => setTimeout(resolve, 800));\n dashboardRunning = true;\n\n // Open browser from MCP side\n const { exec: execCmd } = await import('node:child_process');\n const openCmd =\n process.platform === 'win32' ? `start \"\" \"${url}\"` :\n process.platform === 'darwin' ? `open \"${url}\"` :\n `xdg-open \"${url}\"`;\n execCmd(openCmd, () => { });\n\n return {\n content: [{\n type: 'text' as const,\n text: [\n `Memorix Dashboard started!`,\n ``,\n `URL: ${url}`,\n `Project: ${project.name} (${project.id})`,\n `Static: ${staticDir}`,\n ``,\n `The dashboard has been opened in your default browser.`,\n `It shows your knowledge graph, observations, retention scores, and project stats.`,\n ].join('\\n'),\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text' as const, text: `Failed to start dashboard: ${err instanceof Error ? err.message : String(err)}` }],\n };\n }\n },\n );\n\n return { server, graphManager, projectId: project.id };\n}\n","/**\n * memorix serve — Start MCP Server on stdio\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'serve',\n description: 'Start Memorix MCP Server on stdio transport',\n },\n args: {\n cwd: {\n type: 'string',\n description: 'Project working directory (defaults to process.cwd())',\n required: false,\n },\n },\n run: async ({ args }) => {\n const { StdioServerTransport } = await import(\n '@modelcontextprotocol/sdk/server/stdio.js'\n );\n const { createMemorixServer } = await import('../../server.js');\n const { execSync } = await import('node:child_process');\n\n // Priority: explicit --cwd arg > INIT_CWD (npm lifecycle) > process.cwd()\n let projectRoot = args.cwd || process.env.INIT_CWD || process.cwd();\n\n // Verify git is available at the projectRoot; if not, try the script's\n // own directory (useful when memorix runs from a global npm install\n // but the user's project is at a known location).\n try {\n execSync('git rev-parse --show-toplevel', {\n cwd: projectRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n } catch {\n // cwd is not inside a git repo — try the script directory\n const scriptDir = new URL('.', import.meta.url).pathname.replace(/^\\/([A-Z]:)/, '$1');\n try {\n const gitRoot = execSync('git rev-parse --show-toplevel', {\n cwd: scriptDir,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n if (gitRoot) {\n projectRoot = gitRoot;\n console.error(`[memorix] CWD has no git, using script dir: ${projectRoot}`);\n }\n } catch {\n // Neither has git — fall through with original projectRoot\n }\n }\n\n const { server, projectId } = await createMemorixServer(projectRoot);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n console.error(`[memorix] MCP Server running on stdio (project: ${projectId})`);\n console.error(`[memorix] Project root: ${projectRoot}`);\n },\n});\n","/**\n * memorix status — Show project info + rules sync status\n */\n\nimport { defineCommand } from 'citty';\nimport * as p from '@clack/prompts';\n\nexport default defineCommand({\n meta: {\n name: 'status',\n description: 'Show project info and rules sync status',\n },\n run: async () => {\n const { detectProject } = await import('../../project/detector.js');\n const { RulesSyncer } = await import('../../rules/syncer.js');\n const { getProjectDataDir } = await import('../../store/persistence.js');\n\n p.intro('memorix status');\n\n const project = detectProject();\n const dataDir = await getProjectDataDir(project.id);\n const syncer = new RulesSyncer(project.rootPath);\n const status = await syncer.syncStatus();\n\n p.note(\n [\n `Name: ${project.name}`,\n `ID: ${project.id}`,\n `Root: ${project.rootPath}`,\n `Git remote: ${project.gitRemote || 'none'}`,\n `Data dir: ${dataDir}`,\n ].join('\\n'),\n 'Project',\n );\n\n p.note(\n [\n `Sources: ${status.sources.join(', ') || 'none detected'}`,\n `Total rules: ${status.totalRules}`,\n `Unique rules: ${status.uniqueRules}`,\n `Conflicts: ${status.conflicts.length}`,\n ].join('\\n'),\n 'Rules Sync',\n );\n\n if (status.conflicts.length > 0) {\n p.log.warn('Conflicts detected:');\n for (const c of status.conflicts) {\n p.log.warn(` ${c.ruleA.source}:${c.ruleA.id} vs ${c.ruleB.source}:${c.ruleB.id}`);\n p.log.warn(` → ${c.reason}`);\n }\n }\n\n if (status.totalRules === 0) {\n p.log.info('No rule files found. Create .cursorrules, CLAUDE.md, or .windsurfrules to get started.');\n }\n\n p.outro('Done');\n },\n});\n","/**\n * memorix sync — Interactive cross-agent rule sync\n *\n * Uses @clack/prompts for a beautiful interactive wizard.\n */\n\nimport { defineCommand } from 'citty';\nimport * as p from '@clack/prompts';\nimport type { RuleSource } from '../../types.js';\n\nconst SOURCE_LABELS: Record<string, string> = {\n cursor: 'Cursor (.cursor/rules/*.mdc, .cursorrules)',\n 'claude-code': 'Claude Code (CLAUDE.md, .claude/rules/*.md)',\n codex: 'Codex (SKILL.md, AGENTS.md)',\n windsurf: 'Windsurf (.windsurfrules, .windsurf/rules/*.md)',\n antigravity: 'Antigravity (.agent/rules/*.md, GEMINI.md)',\n kiro: 'Kiro (.kiro/steering/*.md, AGENTS.md)',\n};\n\nexport default defineCommand({\n meta: {\n name: 'sync',\n description: 'Interactive cross-agent rule synchronization',\n },\n args: {\n target: {\n type: 'string',\n description: 'Target agent format (cursor, claude-code, codex, windsurf, antigravity, kiro)',\n required: false,\n },\n dry: {\n type: 'boolean',\n description: 'Dry run — show what would be generated without writing files',\n default: false,\n },\n },\n run: async ({ args }) => {\n const { detectProject } = await import('../../project/detector.js');\n const { RulesSyncer } = await import('../../rules/syncer.js');\n const { promises: fs } = await import('node:fs');\n const path = await import('node:path');\n\n p.intro('memorix sync');\n\n // Detect project\n const project = detectProject();\n p.log.info(`Project: ${project.name} (${project.id})`);\n\n // Scan rules\n const syncer = new RulesSyncer(project.rootPath);\n const spin = p.spinner();\n spin.start('Scanning rule files...');\n const rules = await syncer.scanRules();\n spin.stop(`Found ${rules.length} rule(s)`);\n\n if (rules.length === 0) {\n p.log.warn('No rule files found in this project.');\n p.log.info('Create .cursorrules, CLAUDE.md, or .windsurfrules to get started.');\n p.outro('Nothing to sync');\n return;\n }\n\n // Show sources\n const sources = [...new Set(rules.map(r => r.source))];\n p.log.info(`Sources: ${sources.map(s => SOURCE_LABELS[s] || s).join(', ')}`);\n\n // Dedup\n const deduped = syncer.deduplicateRules(rules);\n if (deduped.length < rules.length) {\n p.log.info(`Deduplicated: ${rules.length} → ${deduped.length} unique rule(s)`);\n }\n\n // Conflicts\n const conflicts = syncer.detectConflicts(deduped);\n if (conflicts.length > 0) {\n p.log.warn(`⚠ ${conflicts.length} conflict(s) detected:`);\n for (const c of conflicts) {\n p.log.warn(` ${c.ruleA.source} vs ${c.ruleB.source}: ${c.reason}`);\n }\n }\n\n // Select target\n let target = args.target as RuleSource | undefined;\n\n if (!target) {\n const available = ['cursor', 'claude-code', 'codex', 'windsurf', 'antigravity', 'kiro'].filter(\n t => !sources.includes(t as RuleSource),\n );\n\n if (available.length === 0) {\n // All formats already present, let user pick any\n available.push('cursor', 'claude-code', 'codex', 'windsurf', 'antigravity', 'kiro');\n }\n\n const selected = await p.select({\n message: 'Generate rules for which agent?',\n options: available.map(t => ({\n value: t,\n label: SOURCE_LABELS[t] || t,\n })),\n });\n\n if (p.isCancel(selected)) {\n p.cancel('Sync cancelled');\n process.exit(0);\n }\n\n target = selected as RuleSource;\n }\n\n // Generate\n spin.start(`Generating ${target} rules...`);\n const files = syncer.generateForTarget(deduped, target);\n spin.stop(`Generated ${files.length} file(s)`);\n\n // Show preview\n for (const file of files) {\n p.note(file.content, file.filePath);\n }\n\n // Write or dry run\n if (args.dry) {\n p.log.info('Dry run — no files written');\n p.outro('Done (dry run)');\n return;\n }\n\n const confirm = await p.confirm({\n message: `Write ${files.length} file(s) to project?`,\n });\n\n if (p.isCancel(confirm) || !confirm) {\n p.cancel('Sync cancelled');\n process.exit(0);\n }\n\n for (const file of files) {\n const fullPath = path.join(project.rootPath, file.filePath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n await fs.writeFile(fullPath, file.content, 'utf-8');\n p.log.success(`Written: ${file.filePath}`);\n }\n\n p.outro(`Synced ${files.length} rule(s) to ${target} format`);\n },\n});\n","/**\n * Hook Normalizer\n *\n * Converts agent-specific stdin JSON into a unified NormalizedHookInput.\n * Each agent has a different event naming convention and payload structure,\n * but they all communicate via stdin/stdout JSON.\n */\n\nimport type { AgentName, HookEvent, NormalizedHookInput } from './types.js';\n\n/**\n * Map agent-specific event names → normalized event names.\n */\nconst EVENT_MAP: Record<string, HookEvent> = {\n // Identity mappings — already-normalized event names\n // This allows direct payloads like { event: 'session_start' } to work\n session_start: 'session_start',\n user_prompt: 'user_prompt',\n post_edit: 'post_edit',\n post_command: 'post_command',\n post_tool: 'post_tool',\n pre_compact: 'pre_compact',\n session_end: 'session_end',\n post_response: 'post_response',\n\n // Claude Code / VS Code Copilot\n SessionStart: 'session_start',\n UserPromptSubmit: 'user_prompt',\n PreToolUse: 'post_tool', // we handle pre as post for memory purposes\n PostToolUse: 'post_tool',\n PreCompact: 'pre_compact',\n Stop: 'session_end',\n\n // Windsurf\n pre_user_prompt: 'user_prompt',\n post_write_code: 'post_edit',\n post_read_code: 'post_tool',\n post_run_command: 'post_command',\n pre_mcp_tool_use: 'post_tool',\n post_mcp_tool_use: 'post_tool',\n post_cascade_response: 'post_response',\n\n // Cursor\n beforeSubmitPrompt: 'user_prompt',\n beforeShellExecution: 'post_command',\n beforeMCPExecution: 'post_tool',\n afterFileEdit: 'post_edit',\n stop: 'session_end',\n};\n\n/**\n * Detect which agent sent this hook event based on payload structure.\n */\nfunction detectAgent(payload: Record<string, unknown>): AgentName {\n // Windsurf uses agent_action_name\n if ('agent_action_name' in payload) return 'windsurf';\n\n // Cursor uses hook_event_name (lowercase) + conversation_id\n if ('hook_event_name' in payload && 'conversation_id' in payload) return 'cursor';\n\n // Claude Code / VS Code Copilot use hookEventName (camelCase)\n if ('hookEventName' in payload) {\n // VS Code Copilot has transcript_path; Claude Code also has it\n // They use the same format, so we distinguish by sessionId pattern if needed\n return 'copilot'; // treat as copilot (same format as claude)\n }\n\n // Kiro uses event_type\n if ('event_type' in payload) return 'kiro';\n\n // Codex\n if ('hook_type' in payload) return 'codex';\n\n return 'claude'; // default fallback\n}\n\n/**\n * Extract the raw event name string from agent-specific payload.\n */\nfunction extractEventName(payload: Record<string, unknown>, agent: AgentName): string {\n switch (agent) {\n case 'windsurf':\n return (payload.agent_action_name as string) ?? '';\n case 'cursor':\n return (payload.hook_event_name as string) ?? '';\n case 'copilot':\n case 'claude':\n return (payload.hookEventName as string) ?? '';\n case 'kiro':\n return (payload.event_type as string) ?? '';\n case 'codex':\n return (payload.hook_type as string) ?? '';\n default:\n return '';\n }\n}\n\n/**\n * Normalize a Claude Code / VS Code Copilot payload.\n */\nfunction normalizeClaude(payload: Record<string, unknown>, event: HookEvent): Partial<NormalizedHookInput> {\n const result: Partial<NormalizedHookInput> = {\n sessionId: (payload.sessionId as string) ?? '',\n cwd: (payload.cwd as string) ?? '',\n transcriptPath: payload.transcript_path as string | undefined,\n };\n\n // PostToolUse with write tool → post_edit\n const toolName = (payload.tool_name as string) ?? '';\n if (toolName) {\n result.toolName = toolName;\n result.toolInput = payload.tool_input as Record<string, unknown> | undefined;\n result.toolResult = payload.tool_result as string | undefined;\n\n // Detect file edits\n if (toolName === 'write' || toolName === 'edit' || toolName === 'multi_edit') {\n const input = payload.tool_input as Record<string, unknown> | undefined;\n result.filePath = (input?.file_path as string) ?? (input?.filePath as string);\n }\n }\n\n // UserPromptSubmit\n if (event === 'user_prompt') {\n result.userPrompt = (payload.prompt as string) ?? '';\n }\n\n return result;\n}\n\n/**\n * Normalize a Windsurf payload.\n */\nfunction normalizeWindsurf(payload: Record<string, unknown>, event: HookEvent): Partial<NormalizedHookInput> {\n const toolInfo = (payload.tool_info as Record<string, unknown>) ?? {};\n const result: Partial<NormalizedHookInput> = {\n sessionId: (payload.trajectory_id as string) ?? '',\n cwd: '',\n };\n\n switch (event) {\n case 'post_edit':\n result.filePath = toolInfo.file_path as string | undefined;\n if (Array.isArray(toolInfo.edits)) {\n result.edits = (toolInfo.edits as Array<Record<string, string>>).map((e) => ({\n oldString: e.old_string ?? '',\n newString: e.new_string ?? '',\n }));\n }\n break;\n case 'post_command':\n result.command = toolInfo.command_line as string | undefined;\n result.cwd = (toolInfo.cwd as string) ?? '';\n break;\n case 'post_tool':\n result.toolName = toolInfo.mcp_tool_name as string | undefined;\n result.toolInput = toolInfo.mcp_tool_arguments as Record<string, unknown> | undefined;\n result.toolResult = toolInfo.mcp_result as string | undefined;\n break;\n case 'user_prompt':\n result.userPrompt = toolInfo.user_prompt as string | undefined;\n break;\n case 'post_response':\n result.aiResponse = toolInfo.response as string | undefined;\n break;\n }\n\n return result;\n}\n\n/**\n * Normalize a Cursor payload.\n */\nfunction normalizeCursor(payload: Record<string, unknown>, event: HookEvent): Partial<NormalizedHookInput> {\n const result: Partial<NormalizedHookInput> = {\n sessionId: (payload.conversation_id as string) ?? '',\n cwd: (payload.cwd as string) ?? '',\n };\n\n const roots = payload.workspace_roots as string[] | undefined;\n if (roots?.length && !result.cwd) {\n result.cwd = roots[0];\n }\n\n switch (event) {\n case 'user_prompt':\n result.userPrompt = (payload.prompt as string) ?? '';\n break;\n case 'post_command':\n result.command = (payload.command as string) ?? '';\n break;\n case 'post_edit':\n result.filePath = (payload.file_path as string) ?? '';\n break;\n }\n\n return result;\n}\n\n/**\n * Main normalizer: convert any agent's stdin payload → NormalizedHookInput.\n */\nexport function normalizeHookInput(payload: Record<string, unknown>): NormalizedHookInput {\n // Support direct/standard payloads: { event: 'session_start', cwd: '...' }\n // This is used by MCP server internals, CLI, and testing scenarios.\n const directEvent = typeof payload.event === 'string' ? EVENT_MAP[payload.event] : undefined;\n\n const agent = detectAgent(payload);\n const rawEventName = extractEventName(payload, agent);\n const event: HookEvent = directEvent ?? EVENT_MAP[rawEventName] ?? 'post_tool';\n const timestamp = (payload.timestamp as string) ?? new Date().toISOString();\n\n let agentSpecific: Partial<NormalizedHookInput> = {};\n switch (agent) {\n case 'claude':\n case 'copilot':\n agentSpecific = normalizeClaude(payload, event);\n break;\n case 'windsurf':\n agentSpecific = normalizeWindsurf(payload, event);\n break;\n case 'cursor':\n agentSpecific = normalizeCursor(payload, event);\n break;\n default:\n agentSpecific = { sessionId: '', cwd: '' };\n }\n\n return {\n event,\n agent,\n timestamp,\n sessionId: agentSpecific.sessionId ?? '',\n cwd: agentSpecific.cwd ?? '',\n raw: payload,\n ...agentSpecific,\n };\n}\n","/**\n * Pattern Detector\n *\n * Analyzes text content to detect patterns worth remembering.\n * Inspired by mcp-memory-service's Smart Auto-Capture,\n * but works across all agents via the unified hooks system.\n */\n\nimport type { DetectedPattern, PatternType } from './types.js';\n\n/** Minimum content length to consider for pattern detection */\nconst MIN_CONTENT_LENGTH = 100;\n\n/** Pattern definitions with multilingual keywords */\nconst PATTERNS: Array<{\n type: PatternType;\n keywords: RegExp[];\n minLength: number;\n baseConfidence: number;\n}> = [\n {\n type: 'decision',\n keywords: [\n /\\b(decided|chose|will use|settled on|going with|picked|selected)\\b/i,\n /(决定|选择了|采用|确定用|最终选了)/,\n /\\b(architecture|approach|strategy|pattern|framework)\\b/i,\n ],\n minLength: 100,\n baseConfidence: 0.8,\n },\n {\n type: 'error',\n keywords: [\n /\\b(error|bug|fix(ed)?|resolv(ed|ing)|crash|fail(ed|ure)?|broken)\\b/i,\n /(错误|修复|报错|崩溃|失败|异常|解决了)/,\n /\\b(workaround|hotfix|patch|regression|stack\\s*trace)\\b/i,\n ],\n minLength: 100,\n baseConfidence: 0.75,\n },\n {\n type: 'gotcha',\n keywords: [\n /\\b(gotcha|pitfall|trap|caveat|watch out|careful|beware|warning)\\b/i,\n /(坑|注意|陷阱|小心|踩坑|坑点)/,\n /\\b(don'?t|never|avoid|must not|不要|千万别|切记)\\b/i,\n ],\n minLength: 80,\n baseConfidence: 0.85,\n },\n {\n type: 'configuration',\n keywords: [\n /\\b(config(ured?|uration)?|setting|environment|\\.env)\\b/i,\n /(配置|环境变量|端口配置|设置项|安装配置)/,\n /\\b(gradle|webpack|vite|tsconfig|package\\.json|docker|nginx)\\b/i,\n /\\b(port\\s*[:=]|listen\\s+\\d|bind\\s+\\d|DATABASE_URL|API_KEY)\\b/i,\n ],\n minLength: 80,\n baseConfidence: 0.7,\n },\n {\n type: 'learning',\n keywords: [\n /\\b(learn(ed)?|discover(ed)?|realiz(ed)?|turns?\\s*out|found\\s*out|TIL)\\b/i,\n /(学到|发现|原来|才知道|了解到)/,\n /\\b(insight|understanding|clarif(ied|ication))\\b/i,\n ],\n minLength: 150,\n baseConfidence: 0.65,\n },\n {\n type: 'implementation',\n keywords: [\n /\\b(implement(ed)?|creat(ed|ing)|built|added|integrat(ed|ing))\\b/i,\n /(实现了|创建了|添加了|集成了|完成了)/,\n /\\b(refactor(ed)?|migrat(ed|ing)|upgrad(ed|ing))\\b/i,\n ],\n minLength: 200,\n baseConfidence: 0.5,\n },\n {\n type: 'deployment',\n keywords: [\n /\\b(deploy(ed|ing|ment)?|ship(ped|ping)?|releas(ed|ing)|publish(ed|ing)?)\\b/i,\n /(部署|发布|上线|迁移|运维)/,\n /\\b(docker|compose|container|kubernetes|k8s|helm)\\b/i,\n /\\b(VPS|server|host(ing)?|cloud|AWS|Azure|GCP|Cloudflare)\\b/i,\n /\\b(nginx|caddy|apache|reverse.?proxy|load.?balanc)\\b/i,\n /\\b(SSL|TLS|cert(ificate)?|HTTPS|Let'?s?.?Encrypt|ACME)\\b/i,\n /\\b(DNS|domain|A.?record|CNAME|nameserver|Cloudflare)\\b/i,\n /\\b(CI\\/CD|pipeline|GitHub.?Actions|Jenkins|GitLab.?CI)\\b/i,\n /\\b(scp|rsync|ssh|sftp|systemd|systemctl|service)\\b/i,\n /(服务器|域名|证书|反向代理|负载均衡|镜像|容器)/,\n ],\n minLength: 80,\n baseConfidence: 0.75,\n },\n ];\n\n/**\n * Detect patterns in text content.\n * Returns matched patterns sorted by confidence (highest first).\n */\nexport function detectPatterns(content: string): DetectedPattern[] {\n if (!content || content.length < MIN_CONTENT_LENGTH) {\n return [];\n }\n\n const results: DetectedPattern[] = [];\n\n for (const pattern of PATTERNS) {\n if (content.length < pattern.minLength) continue;\n\n const matchedKeywords: string[] = [];\n let matchCount = 0;\n\n for (const regex of pattern.keywords) {\n const matches = content.match(new RegExp(regex.source, regex.flags + 'g'));\n if (matches) {\n matchCount += matches.length;\n matchedKeywords.push(...matches.map((m) => m.trim()));\n }\n }\n\n if (matchCount > 0) {\n // Confidence increases with more keyword matches (up to 1.0)\n const confidence = Math.min(1.0, pattern.baseConfidence + matchCount * 0.05);\n results.push({\n type: pattern.type,\n confidence,\n matchedKeywords: [...new Set(matchedKeywords)].slice(0, 5),\n });\n }\n }\n\n // Sort by confidence descending\n results.sort((a, b) => b.confidence - a.confidence);\n\n return results;\n}\n\n/**\n * Get the best (highest confidence) pattern from content.\n * Returns null if no pattern is detected or confidence is too low.\n */\nexport function detectBestPattern(\n content: string,\n minConfidence = 0.5,\n): DetectedPattern | null {\n const patterns = detectPatterns(content);\n if (patterns.length === 0) return null;\n if (patterns[0].confidence < minConfidence) return null;\n return patterns[0];\n}\n\n/**\n * Map pattern type → Memorix observation type.\n */\nexport function patternToObservationType(\n pattern: PatternType,\n): string {\n const map: Record<PatternType, string> = {\n decision: 'decision',\n error: 'problem-solution',\n gotcha: 'gotcha',\n configuration: 'what-changed',\n learning: 'discovery',\n implementation: 'what-changed',\n deployment: 'what-changed',\n };\n return map[pattern] ?? 'discovery';\n}\n","/**\n * Hook Handler\n *\n * Unified entry point for all agent hooks.\n * Reads stdin JSON, normalizes it, detects patterns, and auto-stores memories.\n * Outputs JSON to stdout to control agent behavior (e.g., inject context).\n */\n\nimport type { ObservationType } from '../types.js';\nimport { normalizeHookInput } from './normalizer.js';\nimport { detectBestPattern, patternToObservationType } from './pattern-detector.js';\nimport type { HookEvent, HookOutput, NormalizedHookInput } from './types.js';\n\n/** Cooldown tracker: eventType → lastTimestamp */\nconst cooldowns = new Map<string, number>();\n\n/** Cooldown duration in ms (30 seconds) */\nconst COOLDOWN_MS = 30_000;\n\n/** Minimum content length for auto-store */\nconst MIN_STORE_LENGTH = 100;\n\n/** Lower threshold for code edits (file context adds value) */\nconst MIN_EDIT_LENGTH = 30;\n\n/** Trivial commands to skip (diagnostics, navigation, etc.) */\nconst NOISE_COMMANDS = [\n /^(ls|dir|cd|pwd|echo|cat|type|head|tail|wc|find|which|where|whoami)\\b/i,\n /^(Get-Content|Test-Path|Get-Item|Get-ChildItem|Set-Location|Write-Host)\\b/i,\n /^(Start-Sleep|Select-String|Select-Object|Format-Table|Measure-Object)\\b/i,\n /^(mkdir|rm|cp|mv|touch|chmod|chown)\\b/i,\n /^(node -[ep]|python -c)\\b/i,\n];\n\n/** Max content length (truncate beyond this) */\nconst MAX_CONTENT_LENGTH = 4000;\n\n/**\n * Check if an event is in cooldown.\n */\nfunction isInCooldown(eventKey: string): boolean {\n const last = cooldowns.get(eventKey);\n if (!last) return false;\n return Date.now() - last < COOLDOWN_MS;\n}\n\n/**\n * Mark an event as triggered (start cooldown).\n */\nfunction markTriggered(eventKey: string): void {\n cooldowns.set(eventKey, Date.now());\n}\n\n/**\n * Build content string from the normalized input for pattern detection.\n */\nfunction extractContent(input: NormalizedHookInput): string {\n const parts: string[] = [];\n\n if (input.userPrompt) parts.push(input.userPrompt);\n if (input.aiResponse) parts.push(input.aiResponse);\n if (input.toolResult) parts.push(input.toolResult);\n if (input.commandOutput) parts.push(input.commandOutput);\n if (input.command) parts.push(`Command: ${input.command}`);\n if (input.filePath) parts.push(`File: ${input.filePath}`);\n if (input.edits) {\n for (const edit of input.edits) {\n parts.push(`Edit: ${edit.oldString} → ${edit.newString}`);\n }\n }\n\n return parts.join('\\n').slice(0, MAX_CONTENT_LENGTH);\n}\n\n/**\n * Derive an entity name from the hook input.\n */\nfunction deriveEntityName(input: NormalizedHookInput): string {\n // From file path: extract filename without extension\n if (input.filePath) {\n const parts = input.filePath.replace(/\\\\/g, '/').split('/');\n const filename = parts[parts.length - 1];\n return filename.replace(/\\.[^.]+$/, '');\n }\n\n // From tool name\n if (input.toolName) return input.toolName;\n\n // From command: extract first word\n if (input.command) {\n const firstWord = input.command.split(/\\s+/)[0];\n return firstWord.replace(/[^a-zA-Z0-9-_]/g, '');\n }\n\n return 'session';\n}\n\n/**\n * Generate a concise title from the content and pattern.\n */\nfunction generateTitle(input: NormalizedHookInput, patternType: string): string {\n const maxLen = 60;\n\n if (input.filePath) {\n const filename = input.filePath.replace(/\\\\/g, '/').split('/').pop() ?? '';\n const verb =\n patternType === 'problem-solution'\n ? 'Fixed issue in'\n : patternType === 'what-changed'\n ? 'Changed'\n : 'Updated';\n return `${verb} ${filename}`.slice(0, maxLen);\n }\n\n if (input.command) {\n return `Ran: ${input.command}`.slice(0, maxLen);\n }\n\n if (input.userPrompt) {\n return input.userPrompt.slice(0, maxLen);\n }\n\n return `Session activity (${patternType})`;\n}\n\n/**\n * Build a memorix_store-compatible observation payload.\n */\nfunction buildObservation(input: NormalizedHookInput, content: string) {\n const pattern = detectBestPattern(content);\n const obsType = (pattern ? patternToObservationType(pattern.type) : 'discovery') as ObservationType;\n\n return {\n entityName: deriveEntityName(input),\n type: obsType,\n title: generateTitle(input, obsType),\n narrative: content.slice(0, 2000),\n facts: [\n `Agent: ${input.agent}`,\n `Session: ${input.sessionId}`,\n ...(input.filePath ? [`File: ${input.filePath}`] : []),\n ...(input.command ? [`Command: ${input.command}`] : []),\n ],\n concepts: pattern?.matchedKeywords ?? [],\n filesModified: input.filePath ? [input.filePath] : [],\n };\n}\n\n/**\n * Handle a hook event.\n *\n * Returns:\n * - observation payload if content should be stored (caller persists it)\n * - null if nothing to store\n * - HookOutput for stdout response to agent\n */\nexport async function handleHookEvent(input: NormalizedHookInput): Promise<{\n observation: ReturnType<typeof buildObservation> | null;\n output: HookOutput;\n}> {\n const defaultOutput: HookOutput = { continue: true };\n\n // Skip memorix's own MCP calls to avoid recursion\n if (input.toolName === 'memorix_store' || input.toolName === 'memorix_search') {\n return { observation: null, output: defaultOutput };\n }\n\n // Event-specific handling\n switch (input.event) {\n case 'session_start': {\n // Search relevant memories and inject via systemMessage\n let contextSummary = '';\n try {\n const { detectProject } = await import('../project/detector.js');\n const { getProjectDataDir, loadObservationsJson } = await import('../store/persistence.js');\n\n const project = await detectProject(input.cwd || process.cwd());\n const dataDir = await getProjectDataDir(project.id);\n const allObs = await loadObservationsJson(dataDir) as Array<{\n type?: string;\n title?: string;\n narrative?: string;\n facts?: string[];\n timestamp?: string;\n importance?: number;\n }>;\n\n if (allObs.length > 0) {\n // Priority types: gotcha > decision > problem-solution > trade-off > discovery > others\n const PRIORITY_ORDER: Record<string, number> = {\n 'gotcha': 6,\n 'decision': 5,\n 'problem-solution': 4,\n 'trade-off': 3,\n 'discovery': 2,\n 'how-it-works': 1,\n };\n\n // Filter out low-quality auto-generated observations\n // These are hook-generated template titles that don't carry specific knowledge\n const LOW_QUALITY_PATTERNS = [\n /^Session activity/i,\n /^Updated \\S+\\.\\w+$/i, // \"Updated foo.ts\" — too generic\n /^Created \\S+\\.\\w+$/i, // \"Created bar.js\"\n /^Deleted \\S+\\.\\w+$/i,\n /^Modified \\S+\\.\\w+$/i,\n ];\n const isLowQuality = (title: string) =>\n LOW_QUALITY_PATTERNS.some(p => p.test(title));\n\n // Score: priority × quality × recency\n const scored = allObs\n .map((obs, i) => {\n const title = obs.title ?? '';\n const hasFacts = (obs.facts?.length ?? 0) > 0;\n const hasSubstance = title.length > 20 || hasFacts;\n const quality = isLowQuality(title) ? 0.1 : hasSubstance ? 1.0 : 0.5;\n\n return {\n obs,\n priority: PRIORITY_ORDER[obs.type ?? ''] ?? 0,\n quality,\n recency: i, // higher index = more recent\n };\n })\n .sort((a, b) => {\n // Weighted score: priority × quality first, then recency\n const scoreA = a.priority * a.quality;\n const scoreB = b.priority * b.quality;\n if (scoreB !== scoreA) return scoreB - scoreA;\n return b.recency - a.recency;\n });\n\n // Take top 5 most valuable items, budget ~600 tokens\n const top = scored.slice(0, 5);\n const TYPE_EMOJI: Record<string, string> = {\n 'gotcha': '🔴', 'decision': '🟤', 'problem-solution': '🟡',\n 'trade-off': '⚖️', 'discovery': '🟣', 'how-it-works': '🔵',\n 'what-changed': '🟢', 'why-it-exists': '🟠', 'session-request': '🎯',\n };\n\n const lines = top.map(({ obs }) => {\n const emoji = TYPE_EMOJI[obs.type ?? ''] ?? '📌';\n const title = obs.title ?? '(untitled)';\n // Include first fact if available for extra context\n const fact = obs.facts?.[0] ? ` — ${obs.facts[0]}` : '';\n return `${emoji} ${title}${fact}`;\n });\n\n contextSummary = `\\n\\nRecent project memories (${project.name}):\\n${lines.join('\\n')}`;\n }\n } catch {\n // Silent fail — hooks must never break the agent\n }\n\n return {\n observation: null,\n output: {\n continue: true,\n systemMessage:\n `Memorix is active. Your memories from previous sessions are available via memorix_search.${contextSummary}`,\n },\n };\n }\n\n case 'pre_compact':\n // Context is about to be compressed — save what we can\n return {\n observation: buildObservation(input, extractContent(input)),\n output: defaultOutput,\n };\n\n case 'session_end':\n // Always record session end (no cooldown)\n return {\n observation: buildObservation(input, extractContent(input)),\n output: defaultOutput,\n };\n\n case 'post_edit': {\n // Code edits: lower threshold, always worth recording if pattern matches\n const editKey = `post_edit:${input.filePath ?? 'general'}`;\n if (isInCooldown(editKey)) {\n return { observation: null, output: defaultOutput };\n }\n\n const editContent = extractContent(input);\n if (editContent.length < MIN_EDIT_LENGTH) {\n return { observation: null, output: defaultOutput };\n }\n\n const editPattern = detectBestPattern(editContent, 0.6);\n if (!editPattern) {\n return { observation: null, output: defaultOutput };\n }\n\n markTriggered(editKey);\n return {\n observation: buildObservation(input, editContent),\n output: defaultOutput,\n };\n }\n\n case 'post_command': {\n // Filter noise commands\n if (input.command && NOISE_COMMANDS.some((r) => r.test(input.command!))) {\n return { observation: null, output: defaultOutput };\n }\n\n const cmdKey = `post_command:${input.command ?? 'general'}`;\n if (isInCooldown(cmdKey)) {\n return { observation: null, output: defaultOutput };\n }\n\n // Use commandOutput for pattern detection if available, else command\n const cmdContent = input.commandOutput || extractContent(input);\n if (cmdContent.length < MIN_STORE_LENGTH) {\n return { observation: null, output: defaultOutput };\n }\n\n // Pattern detection — store as discovery if no pattern but content is substantial\n detectBestPattern(cmdContent);\n\n markTriggered(cmdKey);\n return {\n observation: buildObservation(input, cmdContent),\n output: defaultOutput,\n };\n }\n\n case 'post_tool': {\n // Tools: still require pattern (avoid memorix's own tool noise)\n const toolKey = `post_tool:${input.toolName ?? 'general'}`;\n if (isInCooldown(toolKey)) {\n return { observation: null, output: defaultOutput };\n }\n\n const toolContent = extractContent(input);\n if (toolContent.length < MIN_STORE_LENGTH) {\n return { observation: null, output: defaultOutput };\n }\n\n const toolPattern = detectBestPattern(toolContent);\n if (!toolPattern) {\n return { observation: null, output: defaultOutput };\n }\n\n markTriggered(toolKey);\n return {\n observation: buildObservation(input, toolContent),\n output: defaultOutput,\n };\n }\n\n case 'post_response':\n case 'user_prompt': {\n // User prompts & AI responses: store more aggressively (safety net)\n const promptKey = `${input.event}:${input.sessionId ?? 'general'}`;\n if (isInCooldown(promptKey)) {\n return { observation: null, output: defaultOutput };\n }\n\n const content = extractContent(input);\n if (content.length < MIN_STORE_LENGTH) {\n return { observation: null, output: defaultOutput };\n }\n\n // Always store — pattern detection is used for classification only\n detectBestPattern(content);\n\n markTriggered(promptKey);\n return {\n observation: buildObservation(input, content),\n output: defaultOutput,\n };\n }\n\n default:\n return { observation: null, output: defaultOutput };\n }\n}\n\n/**\n * Main entry point: read stdin, process, write stdout.\n * Called by the CLI: `memorix hook`\n */\nexport async function runHook(): Promise<void> {\n // Read stdin\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n const rawInput = Buffer.concat(chunks).toString('utf-8').trim();\n\n if (!rawInput) {\n // No input — output default continue\n process.stdout.write(JSON.stringify({ continue: true }));\n return;\n }\n\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(rawInput);\n } catch {\n process.stdout.write(JSON.stringify({ continue: true }));\n return;\n }\n\n // Normalize\n const input = normalizeHookInput(payload);\n\n // Handle\n const { observation, output } = await handleHookEvent(input);\n\n // Store observation if any\n if (observation) {\n try {\n // Dynamic import to avoid circular deps and keep hook handler lightweight\n const { storeObservation, initObservations } = await import('../memory/observations.js');\n const { detectProject } = await import('../project/detector.js');\n const { getProjectDataDir } = await import('../store/persistence.js');\n\n const project = await detectProject(input.cwd || process.cwd());\n const dataDir = await getProjectDataDir(project.id);\n\n // Initialize observations manager (idempotent if already initialized)\n await initObservations(dataDir);\n\n await storeObservation({ ...observation, projectId: project.id });\n } catch {\n // Silent fail — hooks must never break the agent\n }\n }\n\n // Output response to agent\n process.stdout.write(JSON.stringify(output));\n}\n","/**\n * CLI Command: memorix hook\n *\n * Entry point called by agent hooks via stdin/stdout.\n * Reads agent's JSON from stdin, normalizes, auto-stores, outputs response.\n *\n * Usage (called by agent hook configs, not by users directly):\n * memorix hook\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'hook',\n description: 'Handle agent hook event (called by agent hook configs)',\n },\n run: async () => {\n const { runHook } = await import('../../hooks/handler.js');\n await runHook();\n },\n});\n","/**\n * CLI Command: memorix hooks install\n *\n * Auto-detect installed agents and install hook configurations.\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'install',\n description: 'Install automatic memory hooks for agents',\n },\n args: {\n agent: {\n type: 'string',\n description: 'Target agent (claude|copilot|windsurf|cursor|kiro|codex). Auto-detects if omitted.',\n required: false,\n },\n global: {\n type: 'boolean',\n description: 'Install globally instead of per-project',\n required: false,\n },\n },\n run: async ({ args }) => {\n const { detectInstalledAgents, installHooks } = await import('../../hooks/installers/index.js');\n const cwd = process.cwd();\n\n let agents: string[];\n if (args.agent) {\n agents = [args.agent];\n } else {\n agents = await detectInstalledAgents();\n if (agents.length === 0) {\n console.log('No supported agents detected. Use --agent to specify one.');\n return;\n }\n console.log(`Detected agents: ${agents.join(', ')}`);\n }\n\n for (const agent of agents) {\n try {\n const config = await installHooks(\n agent as import('../../hooks/types.js').AgentName,\n cwd,\n args.global ?? false,\n );\n console.log(`✅ ${agent}: hooks installed → ${config.configPath}`);\n console.log(` Events: ${config.events.join(', ')}`);\n } catch (err) {\n console.error(`❌ ${agent}: failed — ${err}`);\n }\n }\n\n console.log('\\nMemory hooks are now active. Restart your agent to apply.');\n },\n});\n","/**\n * CLI Command: memorix hooks uninstall\n *\n * Remove hook configurations for agents.\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'uninstall',\n description: 'Remove automatic memory hooks for agents',\n },\n args: {\n agent: {\n type: 'string',\n description: 'Target agent (claude|copilot|windsurf|cursor|kiro|codex)',\n required: false,\n },\n global: {\n type: 'boolean',\n description: 'Uninstall global hooks',\n required: false,\n },\n },\n run: async ({ args }) => {\n const { detectInstalledAgents, uninstallHooks } = await import('../../hooks/installers/index.js');\n const cwd = process.cwd();\n\n let agents: string[];\n if (args.agent) {\n agents = [args.agent];\n } else {\n agents = await detectInstalledAgents();\n }\n\n for (const agent of agents) {\n const ok = await uninstallHooks(\n agent as import('../../hooks/types.js').AgentName,\n cwd,\n args.global ?? false,\n );\n if (ok) {\n console.log(`✅ ${agent}: hooks removed`);\n } else {\n console.log(`⚠️ ${agent}: no hooks found`);\n }\n }\n },\n});\n","/**\n * CLI Command: memorix hooks status\n *\n * Show hook installation status for all agents.\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'status',\n description: 'Show hook installation status for all agents',\n },\n run: async () => {\n const { getHookStatus } = await import('../../hooks/installers/index.js');\n const cwd = process.cwd();\n\n const statuses = await getHookStatus(cwd);\n\n console.log('\\nMemorix Hooks Status');\n console.log('═'.repeat(50));\n\n for (const { agent, installed, configPath } of statuses) {\n const icon = installed ? '✅' : '⬚';\n const label = agent.charAt(0).toUpperCase() + agent.slice(1);\n console.log(`${icon} ${label.padEnd(12)} ${installed ? configPath : '(not installed)'}`);\n }\n\n console.log('\\nRun `memorix hooks install` to set up hooks for detected agents.');\n },\n});\n","/**\n * CLI Command: memorix hooks\n *\n * Manage hook installations across agents.\n *\n * Usage:\n * memorix hooks install [--agent <name>] [--global]\n * memorix hooks uninstall [--agent <name>] [--global]\n * memorix hooks status\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'hooks',\n description: 'Manage automatic memory hooks for agents',\n },\n subCommands: {\n install: () => import('./hooks-install.js').then((m) => m.default),\n uninstall: () => import('./hooks-uninstall.js').then((m) => m.default),\n status: () => import('./hooks-status.js').then((m) => m.default),\n },\n run() {\n // Default: show help\n },\n});\n","/**\r\n * memorix dashboard — Launch the Memorix Web Dashboard\r\n */\r\n\r\nimport { defineCommand } from 'citty';\r\nimport { fileURLToPath } from 'node:url';\r\nimport path from 'node:path';\r\n\r\nexport default defineCommand({\r\n meta: {\r\n name: 'dashboard',\r\n description: 'Launch the Memorix Web Dashboard',\r\n },\r\n args: {\r\n port: {\r\n type: 'string',\r\n description: 'Port to run the dashboard on (default: 3210)',\r\n default: '3210',\r\n },\r\n },\r\n run: async ({ args }) => {\r\n const { detectProject } = await import('../../project/detector.js');\r\n const { getProjectDataDir } = await import('../../store/persistence.js');\r\n const { startDashboard } = await import('../../dashboard/server.js');\r\n\r\n const project = detectProject();\r\n const dataDir = await getProjectDataDir(project.id);\r\n const port = parseInt(args.port as string, 10) || 3210;\r\n\r\n // Resolve static directory relative to the compiled CLI entry point\r\n // CLI is at dist/cli/index.js → static files are at dist/dashboard/static\r\n const cliDir = path.dirname(fileURLToPath(import.meta.url));\r\n const staticDir = path.join(cliDir, '..', 'dashboard', 'static');\r\n\r\n await startDashboard(dataDir, port, staticDir, project.id, project.name);\r\n\r\n // Keep alive\r\n await new Promise(() => { });\r\n },\r\n});\r\n","/**\r\n * CLI Command: memorix cleanup\r\n *\r\n * Identifies and removes low-quality auto-generated observations.\r\n * Inspired by Mem0's memory consolidation and Graphiti's temporal pruning.\r\n *\r\n * Usage:\r\n * memorix cleanup — Interactive: preview & confirm deletion\r\n * memorix cleanup --dry — Preview only, no deletions\r\n * memorix cleanup --force — Delete without confirmation\r\n */\r\n\r\nimport { defineCommand } from 'citty';\r\nimport { detectProject } from '../../project/detector.js';\r\nimport { getProjectDataDir, loadObservationsJson, saveObservationsJson } from '../../store/persistence.js';\r\n\r\n/** Patterns that indicate auto-generated, low-value observations */\r\nconst LOW_QUALITY_PATTERNS = [\r\n /^Session activity/i,\r\n /^Updated \\S+\\.\\w+$/i,\r\n /^Created \\S+\\.\\w+$/i,\r\n /^Deleted \\S+\\.\\w+$/i,\r\n /^Modified \\S+\\.\\w+$/i,\r\n /^Ran command:/i,\r\n /^Read file:/i,\r\n];\r\n\r\n/** Check if an observation title matches low-quality patterns */\r\nfunction isLowQuality(title: string): boolean {\r\n return LOW_QUALITY_PATTERNS.some(p => p.test(title.trim()));\r\n}\r\n\r\nexport default defineCommand({\r\n meta: {\r\n name: 'cleanup',\r\n description: 'Remove low-quality auto-generated observations',\r\n },\r\n args: {\r\n dry: {\r\n type: 'boolean',\r\n description: 'Preview only — do not delete anything',\r\n default: false,\r\n },\r\n force: {\r\n type: 'boolean',\r\n description: 'Delete without confirmation',\r\n default: false,\r\n },\r\n },\r\n async run({ args }) {\r\n const project = detectProject();\r\n\r\n if (project.id === '__invalid__') {\r\n console.error('❌ Not in a valid project directory.');\r\n process.exit(1);\r\n }\r\n\r\n console.log(`\\n📦 Project: ${project.name} (${project.id})\\n`);\r\n\r\n const dataDir = await getProjectDataDir(project.id);\r\n const allObs = await loadObservationsJson(dataDir) as Array<{\r\n id?: number;\r\n type?: string;\r\n title?: string;\r\n narrative?: string;\r\n entityName?: string;\r\n facts?: string[];\r\n timestamp?: string;\r\n }>;\r\n\r\n if (allObs.length === 0) {\r\n console.log('✅ No observations found — nothing to clean up.');\r\n return;\r\n }\r\n\r\n // Categorize\r\n const lowQuality = allObs.filter(o => isLowQuality(o.title ?? ''));\r\n const highQuality = allObs.filter(o => !isLowQuality(o.title ?? ''));\r\n\r\n // Also find duplicates (same title + type + entity)\r\n const seen = new Set<string>();\r\n const duplicates: typeof allObs = [];\r\n const unique: typeof allObs = [];\r\n for (const obs of highQuality) {\r\n const key = `${obs.type}|${obs.title}|${obs.entityName}`;\r\n if (seen.has(key)) {\r\n duplicates.push(obs);\r\n } else {\r\n seen.add(key);\r\n unique.push(obs);\r\n }\r\n }\r\n\r\n const toRemove = [...lowQuality, ...duplicates];\r\n\r\n console.log(`📊 Analysis:`);\r\n console.log(` Total observations: ${allObs.length}`);\r\n console.log(` 🟢 High quality: ${unique.length}`);\r\n console.log(` 🔴 Low quality: ${lowQuality.length}`);\r\n console.log(` 🟡 Duplicates: ${duplicates.length}`);\r\n console.log(` 🗑️ To remove: ${toRemove.length}`);\r\n console.log();\r\n\r\n if (toRemove.length === 0) {\r\n console.log('✅ All observations are high quality — nothing to clean up!');\r\n return;\r\n }\r\n\r\n // Preview\r\n console.log('🔍 Examples of items to remove:');\r\n toRemove.slice(0, 10).forEach(o => {\r\n const tag = isLowQuality(o.title ?? '') ? '(low-quality)' : '(duplicate)';\r\n console.log(` ${tag} #${o.id ?? '?'} \"${o.title}\" [${o.type}]`);\r\n });\r\n if (toRemove.length > 10) {\r\n console.log(` ... and ${toRemove.length - 10} more`);\r\n }\r\n console.log();\r\n\r\n if (args.dry) {\r\n console.log('🔒 Dry run — no changes made.');\r\n return;\r\n }\r\n\r\n if (!args.force) {\r\n // Simple confirmation via stdin\r\n const readline = await import('node:readline');\r\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\r\n const answer = await new Promise<string>(resolve => {\r\n rl.question(`⚠️ Delete ${toRemove.length} observations? (y/N) `, resolve);\r\n });\r\n rl.close();\r\n\r\n if (answer.trim().toLowerCase() !== 'y') {\r\n console.log('❌ Cancelled.');\r\n return;\r\n }\r\n }\r\n\r\n // Remove\r\n const removeIds = new Set(toRemove.map(o => JSON.stringify(o)));\r\n const remaining = allObs.filter(o => !removeIds.has(JSON.stringify(o)));\r\n\r\n await saveObservationsJson(dataDir, remaining);\r\n\r\n console.log(`✅ Removed ${toRemove.length} observations. ${remaining.length} remaining.`);\r\n },\r\n});\r\n","/**\n * Memorix CLI\n *\n * Command-line interface for Memorix management.\n * Built with: citty (1.1K stars, zero-deps) + @clack/prompts (7.4K stars)\n *\n * Commands:\n * memorix serve — Start MCP Server on stdio\n * memorix status — Show project info + rules sync status\n * memorix sync — Interactive cross-agent rule sync\n */\n\nimport { defineCommand, runMain } from 'citty';\nimport { createRequire } from 'node:module';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../../package.json') as { version: string };\n\n// ============================================================\n// Main command\n// ============================================================\n\nconst main = defineCommand({\n meta: {\n name: 'memorix',\n version: pkg.version,\n description: 'Cross-Agent Memory Bridge — Universal memory layer for AI coding agents via MCP',\n },\n subCommands: {\n serve: () => import('./commands/serve.js').then(m => m.default),\n status: () => import('./commands/status.js').then(m => m.default),\n sync: () => import('./commands/sync.js').then(m => m.default),\n hook: () => import('./commands/hook.js').then(m => m.default),\n hooks: () => import('./commands/hooks.js').then(m => m.default),\n dashboard: () => import('./commands/dashboard.js').then(m => m.default),\n cleanup: () => import('./commands/cleanup.js').then(m => m.default),\n },\n run() {\n // Default: show help (citty handles this automatically)\n },\n});\n\nrunMain(main);\n"],"mappings":"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","names":["path","projectDir","observations","nextId","projectDir","observations","cache","MAX_CACHE_SIZE","FastEmbedProvider","TransformersProvider","p","provider","getObservationCount","count","basename","os","path","id","name","basename","matter","matter","matter","matter","matter","p","matter","fs","path","p","init_windsurf","homedir","join","init_cursor","homedir","join","init_codex","homedir","join","init_claude_code","homedir","join","existsSync","init_copilot","homedir","join","init_antigravity","homedir","join","init_kiro","matter","existsSync","readFileSync","existsSync","mkdirSync","join","homedir","init_engine","init_windsurf","init_cursor","init_codex","init_claude_code","init_copilot","init_antigravity","init_kiro","path","fs","path","os","existsSync","readFileSync","writeFileSync","mkdirSync","readdirSync","join","homedir","init_engine","observations","p","fs","path","observations","nextId","isEmbeddingEnabled","getEmbeddingProvider","provider","isImmune","resolve","server_exports","migrateGlobalData","projectDir","getHookStatus","installHooks","detectInstalledAgents","count","getRetentionSummary","getArchiveCandidates","rankByRelevance","search","observations","lines","SkillsEngine","loadObservationsJson","path","exec","fileURLToPath","startDashboard","resolve","init_server","init_engine","createMemorixServer","execSync","defineCommand","detectProject","RulesSyncer","getProjectDataDir","defineCommand","p","detectProject","RulesSyncer","fs","path","confirm","detectProject","getProjectDataDir","loadObservationsJson","LOW_QUALITY_PATTERNS","isLowQuality","p","storeObservation","initObservations","defineCommand","runHook","defineCommand","detectInstalledAgents","installHooks","defineCommand","detectInstalledAgents","uninstallHooks","defineCommand","getHookStatus","defineCommand","defineCommand","fileURLToPath","path","detectProject","getProjectDataDir","startDashboard","defineCommand","p","resolve","defineCommand","createRequire","require"]}
1
+ {"version":3,"sources":["../../node_modules/tsup/assets/esm_shims.js","../../src/store/persistence.ts","../../src/memory/graph.ts","../../src/types.ts","../../src/embedding/fastembed-provider.ts","../../src/embedding/transformers-provider.ts","../../src/embedding/provider.ts","../../src/store/orama-store.ts","../../src/compact/token-budget.ts","../../src/memory/entity-extractor.ts","../../src/memory/observations.ts","../../src/memory/auto-relations.ts","../../src/compact/index-format.ts","../../src/compact/engine.ts","../../src/project/detector.ts","../../src/rules/utils.ts","../../src/rules/adapters/cursor.ts","../../src/rules/adapters/claude-code.ts","../../src/rules/adapters/codex.ts","../../src/rules/adapters/windsurf.ts","../../src/rules/adapters/antigravity.ts","../../src/rules/adapters/copilot.ts","../../src/rules/adapters/kiro.ts","../../src/rules/syncer.ts","../../src/workspace/mcp-adapters/windsurf.ts","../../src/workspace/mcp-adapters/cursor.ts","../../src/workspace/mcp-adapters/codex.ts","../../src/workspace/mcp-adapters/claude-code.ts","../../src/workspace/mcp-adapters/copilot.ts","../../src/workspace/mcp-adapters/antigravity.ts","../../src/workspace/mcp-adapters/kiro.ts","../../src/workspace/workflow-sync.ts","../../src/workspace/sanitizer.ts","../../src/workspace/applier.ts","../../src/workspace/engine.ts","../../src/hooks/installers/index.ts","../../src/memory/retention.ts","../../src/skills/engine.ts","../../src/dashboard/server.ts","../../src/server.ts","../../src/cli/commands/serve.ts","../../src/cli/commands/status.ts","../../src/cli/commands/sync.ts","../../src/hooks/normalizer.ts","../../src/hooks/pattern-detector.ts","../../src/hooks/handler.ts","../../src/cli/commands/hook.ts","../../src/cli/commands/hooks-install.ts","../../src/cli/commands/hooks-uninstall.ts","../../src/cli/commands/hooks-status.ts","../../src/cli/commands/hooks.ts","../../src/cli/commands/dashboard.ts","../../src/cli/commands/cleanup.ts","../../src/cli/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Persistence Layer\n *\n * Saves and restores the Orama database to/from disk.\n * Source: @orama/plugin-data-persistence (official Orama plugin)\n *\n * Data is stored in a single global directory shared across all agents:\n * ~/.memorix/data/ (all files: observations.json, graph.jsonl, counter.json)\n */\n\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\n\n/** Default base data directory */\nconst DEFAULT_DATA_DIR = path.join(os.homedir(), '.memorix', 'data');\n\n/**\n * Sanitize a projectId for use as a directory name.\n * Replaces `/` with `--`, removes other unsafe chars.\n */\nfunction sanitizeProjectId(projectId: string): string {\n return projectId.replace(/\\//g, '--').replace(/[<>:\"|?*\\\\]/g, '_');\n}\n\n/**\n * Get the project-specific data directory for Memorix storage.\n * Each project gets its own subdirectory under ~/.memorix/data/\n *\n * Example: projectId \"AVIDS2/memorix\" → ~/.memorix/data/AVIDS2--memorix/\n *\n * @param projectId - Git-based project identifier (e.g. \"user/repo\")\n */\nexport async function getProjectDataDir(projectId: string, baseDir?: string): Promise<string> {\n // Reject sentinel IDs to prevent garbage directories\n if (projectId === '__invalid__') {\n throw new Error('Cannot create data directory for invalid project');\n }\n const base = baseDir ?? DEFAULT_DATA_DIR;\n const dirName = sanitizeProjectId(projectId);\n const dataDir = path.join(base, dirName);\n await fs.mkdir(dataDir, { recursive: true });\n return dataDir;\n}\n\n/**\n * Get the base data directory (parent of all project dirs).\n */\nexport function getBaseDataDir(baseDir?: string): string {\n return baseDir ?? DEFAULT_DATA_DIR;\n}\n\n/**\n * List all project data directories.\n * Used for cross-project (global) search.\n */\nexport async function listProjectDirs(baseDir?: string): Promise<string[]> {\n const base = baseDir ?? DEFAULT_DATA_DIR;\n try {\n const entries = await fs.readdir(base, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => path.join(base, e.name));\n } catch {\n return [];\n }\n}\n\n/**\n * Migrate legacy global data to project-specific directory.\n * If observations.json exists directly in the base data dir (old format),\n * move it into the correct project subdirectory.\n */\nexport async function migrateGlobalData(projectId: string, baseDir?: string): Promise<boolean> {\n const base = baseDir ?? DEFAULT_DATA_DIR;\n const globalObsPath = path.join(base, 'observations.json');\n const migratedObsPath = path.join(base, 'observations.json.migrated');\n\n // Check if global data exists (either live or already-migrated backup)\n let sourceObsPath: string | null = null;\n try {\n await fs.access(globalObsPath);\n sourceObsPath = globalObsPath;\n } catch {\n // Check for .migrated backup that wasn't fully merged\n try {\n await fs.access(migratedObsPath);\n sourceObsPath = migratedObsPath;\n } catch {\n return false; // No global data to migrate\n }\n }\n\n // Read the source (global) observations\n let globalObs: unknown[] = [];\n try {\n const data = await fs.readFile(sourceObsPath, 'utf-8');\n globalObs = JSON.parse(data);\n if (!Array.isArray(globalObs) || globalObs.length === 0) return false;\n } catch {\n return false;\n }\n\n // Read existing project observations (may have been partially written)\n const projectDir = await getProjectDataDir(projectId, baseDir);\n const projectObsPath = path.join(projectDir, 'observations.json');\n let projectObs: unknown[] = [];\n try {\n const data = await fs.readFile(projectObsPath, 'utf-8');\n projectObs = JSON.parse(data);\n if (!Array.isArray(projectObs)) projectObs = [];\n } catch { /* no existing data */ }\n\n // If project already has >= global data, skip (already migrated properly)\n if (projectObs.length >= globalObs.length) {\n return false;\n }\n\n // Merge: global data + project data, deduplicate by ID\n const existingIds = new Set(projectObs.map((o: any) => o.id));\n const merged = [...projectObs];\n for (const obs of globalObs) {\n if (!existingIds.has((obs as any).id)) {\n merged.push(obs);\n }\n }\n\n // Sort by ID\n merged.sort((a: any, b: any) => (a.id ?? 0) - (b.id ?? 0));\n\n // Normalize projectId for all migrated records to the current project\n for (const obs of merged) {\n (obs as any).projectId = projectId;\n }\n\n // Write merged observations\n await fs.writeFile(projectObsPath, JSON.stringify(merged, null, 2), 'utf-8');\n\n // Copy graph and counter if they exist\n for (const file of ['graph.jsonl', 'counter.json']) {\n const src = path.join(base, file);\n const srcMigrated = path.join(base, file + '.migrated');\n const dst = path.join(projectDir, file);\n // Try live file first, then .migrated backup\n for (const source of [src, srcMigrated]) {\n try {\n await fs.access(source);\n await fs.copyFile(source, dst);\n break;\n } catch { /* try next */ }\n }\n }\n\n // Find max ID for counter\n const maxId = merged.reduce((max: number, o: any) => Math.max(max, o.id ?? 0), 0);\n await fs.writeFile(\n path.join(projectDir, 'counter.json'),\n JSON.stringify({ nextId: maxId + 1 }),\n 'utf-8',\n );\n\n // Rename source files to .migrated (if not already)\n for (const file of ['observations.json', 'graph.jsonl', 'counter.json']) {\n const src = path.join(base, file);\n try {\n await fs.access(src);\n await fs.rename(src, src + '.migrated');\n } catch { /* already migrated or doesn't exist */ }\n }\n\n return true;\n}\n\n/**\n * Get the file path for the Orama database file.\n */\nexport function getDbFilePath(projectDir: string): string {\n return path.join(projectDir, 'memorix.msp');\n}\n\n/**\n * Get the file path for the knowledge graph JSONL file.\n * (MCP-compatible format, same as official Memory Server)\n */\nexport function getGraphFilePath(projectDir: string): string {\n return path.join(projectDir, 'graph.jsonl');\n}\n\n/**\n * Check if a database file exists for the given project.\n */\nexport async function hasExistingData(projectDir: string): Promise<boolean> {\n try {\n await fs.access(getDbFilePath(projectDir));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Save the knowledge graph in JSONL format (MCP-compatible).\n * Each line is a JSON object with type: \"entity\" or \"relation\".\n *\n * Format adopted from MCP Official Memory Server.\n */\nexport async function saveGraphJsonl(\n projectDir: string,\n entities: Array<{ name: string; entityType: string; observations: string[] }>,\n relations: Array<{ from: string; to: string; relationType: string }>,\n): Promise<void> {\n const lines = [\n ...entities.map((e) =>\n JSON.stringify({ type: 'entity', name: e.name, entityType: e.entityType, observations: e.observations }),\n ),\n ...relations.map((r) =>\n JSON.stringify({ type: 'relation', from: r.from, to: r.to, relationType: r.relationType }),\n ),\n ];\n await fs.writeFile(getGraphFilePath(projectDir), lines.join('\\n'), 'utf-8');\n}\n\n/**\n * Load the knowledge graph from JSONL format.\n */\nexport async function loadGraphJsonl(\n projectDir: string,\n): Promise<{\n entities: Array<{ name: string; entityType: string; observations: string[] }>;\n relations: Array<{ from: string; to: string; relationType: string }>;\n}> {\n const filePath = getGraphFilePath(projectDir);\n try {\n const data = await fs.readFile(filePath, 'utf-8');\n const lines = data.split('\\n').filter((line) => line.trim() !== '');\n return lines.reduce(\n (graph, line) => {\n const item = JSON.parse(line);\n if (item.type === 'entity') {\n graph.entities.push({\n name: item.name,\n entityType: item.entityType,\n observations: item.observations,\n });\n }\n if (item.type === 'relation') {\n graph.relations.push({\n from: item.from,\n to: item.to,\n relationType: item.relationType,\n });\n }\n return graph;\n },\n {\n entities: [] as Array<{ name: string; entityType: string; observations: string[] }>,\n relations: [] as Array<{ from: string; to: string; relationType: string }>\n },\n );\n } catch (error) {\n if (error instanceof Error && 'code' in error && (error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { entities: [], relations: [] };\n }\n throw error;\n }\n}\n\n/**\n * Save observation data as JSON (for Orama restore).\n */\nexport async function saveObservationsJson(\n projectDir: string,\n observations: unknown[],\n): Promise<void> {\n const filePath = path.join(projectDir, 'observations.json');\n await fs.writeFile(filePath, JSON.stringify(observations, null, 2), 'utf-8');\n}\n\n/**\n * Load observation data from JSON.\n */\nexport async function loadObservationsJson(projectDir: string): Promise<unknown[]> {\n const filePath = path.join(projectDir, 'observations.json');\n try {\n const data = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(data);\n } catch (error) {\n if (error instanceof Error && 'code' in error && (error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n}\n\n/**\n * Save the next observation ID counter.\n */\nexport async function saveIdCounter(projectDir: string, nextId: number): Promise<void> {\n const filePath = path.join(projectDir, 'counter.json');\n await fs.writeFile(filePath, JSON.stringify({ nextId }), 'utf-8');\n}\n\n/**\n * Load the next observation ID counter.\n */\nexport async function loadIdCounter(projectDir: string): Promise<number> {\n const filePath = path.join(projectDir, 'counter.json');\n try {\n const data = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(data).nextId ?? 1;\n } catch {\n return 1;\n }\n}\n","/**\n * Knowledge Graph Manager\n *\n * Manages the Entity-Relation knowledge graph.\n * Source: MCP Official Memory Server v0.6.3 (complete rewrite with same API).\n *\n * Key differences from official implementation:\n * - Uses per-project JSONL files (official uses single file)\n * - Async initialization with persistence layer\n * - Project-scoped operations\n */\n\nimport type { Entity, Relation, KnowledgeGraph } from '../types.js';\nimport { saveGraphJsonl, loadGraphJsonl } from '../store/persistence.js';\n\nexport class KnowledgeGraphManager {\n private entities: Entity[] = [];\n private relations: Relation[] = [];\n private projectDir: string;\n private initialized = false;\n\n constructor(projectDir: string) {\n this.projectDir = projectDir;\n }\n\n /** Load graph from disk on first access */\n async init(): Promise<void> {\n if (this.initialized) return;\n const data = await loadGraphJsonl(this.projectDir);\n this.entities = data.entities;\n this.relations = data.relations;\n this.initialized = true;\n }\n\n /** Persist current state to disk */\n private async save(): Promise<void> {\n await saveGraphJsonl(this.projectDir, this.entities, this.relations);\n }\n\n /** Create new entities (skip duplicates by name) */\n async createEntities(entities: Entity[]): Promise<Entity[]> {\n await this.init();\n const newEntities = entities.filter(\n (e) => !this.entities.some((existing) => existing.name === e.name),\n );\n this.entities.push(...newEntities);\n await this.save();\n return newEntities;\n }\n\n /** Create new relations (skip duplicates) */\n async createRelations(relations: Relation[]): Promise<Relation[]> {\n await this.init();\n const newRelations = relations.filter(\n (r) =>\n !this.relations.some(\n (existing) =>\n existing.from === r.from &&\n existing.to === r.to &&\n existing.relationType === r.relationType,\n ),\n );\n this.relations.push(...newRelations);\n await this.save();\n return newRelations;\n }\n\n /** Add observations to existing entities */\n async addObservations(\n observations: { entityName: string; contents: string[] }[],\n ): Promise<{ entityName: string; addedObservations: string[] }[]> {\n await this.init();\n const results = observations.map((o) => {\n const entity = this.entities.find((e) => e.name === o.entityName);\n if (!entity) {\n throw new Error(`Entity with name ${o.entityName} not found`);\n }\n const newObs = o.contents.filter((c) => !entity.observations.includes(c));\n entity.observations.push(...newObs);\n return { entityName: o.entityName, addedObservations: newObs };\n });\n await this.save();\n return results;\n }\n\n /** Delete entities and their associated relations */\n async deleteEntities(entityNames: string[]): Promise<void> {\n await this.init();\n this.entities = this.entities.filter((e) => !entityNames.includes(e.name));\n this.relations = this.relations.filter(\n (r) => !entityNames.includes(r.from) && !entityNames.includes(r.to),\n );\n await this.save();\n }\n\n /** Delete specific observations from entities */\n async deleteObservations(\n deletions: { entityName: string; observations: string[] }[],\n ): Promise<void> {\n await this.init();\n for (const d of deletions) {\n const entity = this.entities.find((e) => e.name === d.entityName);\n if (entity) {\n entity.observations = entity.observations.filter(\n (o) => !d.observations.includes(o),\n );\n }\n }\n await this.save();\n }\n\n /** Delete specific relations */\n async deleteRelations(relations: Relation[]): Promise<void> {\n await this.init();\n this.relations = this.relations.filter(\n (r) =>\n !relations.some(\n (del) =>\n r.from === del.from &&\n r.to === del.to &&\n r.relationType === del.relationType,\n ),\n );\n await this.save();\n }\n\n /** Read the entire graph */\n async readGraph(): Promise<KnowledgeGraph> {\n await this.init();\n return { entities: this.entities, relations: this.relations };\n }\n\n /** Search nodes by query string (upgraded from official's basic includes) */\n async searchNodes(query: string): Promise<KnowledgeGraph> {\n await this.init();\n const lowerQuery = query.toLowerCase();\n\n const filteredEntities = this.entities.filter(\n (e) =>\n e.name.toLowerCase().includes(lowerQuery) ||\n e.entityType.toLowerCase().includes(lowerQuery) ||\n e.observations.some((o) => o.toLowerCase().includes(lowerQuery)),\n );\n\n const filteredNames = new Set(filteredEntities.map((e) => e.name));\n\n const filteredRelations = this.relations.filter(\n (r) => filteredNames.has(r.from) && filteredNames.has(r.to),\n );\n\n return { entities: filteredEntities, relations: filteredRelations };\n }\n\n /** Open specific nodes by name */\n async openNodes(names: string[]): Promise<KnowledgeGraph> {\n await this.init();\n\n const filteredEntities = this.entities.filter((e) => names.includes(e.name));\n const filteredNames = new Set(filteredEntities.map((e) => e.name));\n\n const filteredRelations = this.relations.filter(\n (r) => filteredNames.has(r.from) && filteredNames.has(r.to),\n );\n\n return { entities: filteredEntities, relations: filteredRelations };\n }\n}\n","/**\n * Memorix Core Types\n *\n * Data model sources:\n * - Entity/Relation/KnowledgeGraph: MCP Official Memory Server (v0.6.3)\n * - Observation/ObservationType: claude-mem Progressive Disclosure\n * - UnifiedRule/RuleSource: Memorix original (rules sync)\n *\n * Designed for extensibility: new agent formats (Kiro, Copilot, Antigravity)\n * can be added by extending RuleSource and adding format adapters.\n */\n\n// ============================================================\n// Knowledge Graph (adopted from MCP Official Memory Server)\n// ============================================================\n\n/** A node in the knowledge graph representing a concept, component, or config */\nexport interface Entity {\n name: string;\n entityType: string;\n observations: string[];\n}\n\n/** A directed edge between two entities */\nexport interface Relation {\n from: string;\n to: string;\n relationType: string;\n}\n\n/** The complete knowledge graph */\nexport interface KnowledgeGraph {\n entities: Entity[];\n relations: Relation[];\n}\n\n// ============================================================\n// Observation (adopted from claude-mem Progressive Disclosure)\n// ============================================================\n\n/**\n * Observation type classification using claude-mem's icon-based legend system.\n *\n * Icon mapping:\n * 🎯 session-request — User's original goal\n * 🔴 gotcha — Critical pitfall / trap\n * 🟡 problem-solution — Bug fix or workaround\n * 🔵 how-it-works — Technical explanation\n * 🟢 what-changed — Code/architecture change\n * 🟣 discovery — New learning or insight\n * 🟠 why-it-exists — Design rationale\n * 🟤 decision — Architecture decision\n * ⚖️ trade-off — Deliberate compromise\n */\nexport type ObservationType =\n | 'session-request'\n | 'gotcha'\n | 'problem-solution'\n | 'how-it-works'\n | 'what-changed'\n | 'discovery'\n | 'why-it-exists'\n | 'decision'\n | 'trade-off';\n\n/** Map from ObservationType to display icon */\nexport const OBSERVATION_ICONS: Record<ObservationType, string> = {\n 'session-request': '🎯',\n 'gotcha': '🔴',\n 'problem-solution': '🟡',\n 'how-it-works': '🔵',\n 'what-changed': '🟢',\n 'discovery': '🟣',\n 'why-it-exists': '🟠',\n 'decision': '🟤',\n 'trade-off': '⚖️',\n};\n\n/** A rich observation record attached to an entity */\nexport interface Observation {\n id: number;\n entityName: string;\n type: ObservationType;\n title: string;\n narrative: string;\n facts: string[];\n filesModified: string[];\n concepts: string[];\n tokens: number;\n createdAt: string;\n projectId: string;\n /** Whether the observation contains causal language (because, due to, etc.) */\n hasCausalLanguage?: boolean;\n}\n\n// ============================================================\n// Compact Engine (adopted from claude-mem 3-layer workflow)\n// ============================================================\n\n/** L1 index entry — lightweight, ~50-100 tokens per result */\nexport interface IndexEntry {\n id: number;\n time: string;\n type: ObservationType;\n icon: string;\n title: string;\n tokens: number;\n}\n\n/** L2 timeline context — observations around an anchor */\nexport interface TimelineContext {\n anchorId: number;\n anchorEntry: IndexEntry | null;\n before: IndexEntry[];\n after: IndexEntry[];\n}\n\n/** Search options for the compact engine */\nexport interface SearchOptions {\n query: string;\n limit?: number;\n type?: ObservationType;\n projectId?: string;\n since?: string;\n until?: string;\n /** Token budget — trim results to fit within this many tokens (0 = unlimited) */\n maxTokens?: number;\n}\n\n// ============================================================\n// Orama Document Schema\n// ============================================================\n\n/** The document shape stored in Orama */\nexport interface MemorixDocument {\n id: string;\n observationId: number;\n entityName: string;\n type: string;\n title: string;\n narrative: string;\n facts: string;\n filesModified: string;\n concepts: string;\n tokens: number;\n createdAt: string;\n projectId: string;\n /** Number of times this observation was returned in search results */\n accessCount: number;\n /** ISO timestamp of last access via search/detail */\n lastAccessedAt: string;\n}\n\n// ============================================================\n// Rules System (Memorix original — extensible for new agents)\n// ============================================================\n\n/**\n * Supported agent/IDE rule sources.\n * All 7 major AI IDEs are supported.\n */\nexport type RuleSource =\n | 'cursor'\n | 'claude-code'\n | 'codex'\n | 'windsurf'\n | 'antigravity'\n | 'copilot'\n | 'kiro'\n | 'memorix';\n\n/** A parsed rule in the unified intermediate representation */\nexport interface UnifiedRule {\n id: string;\n content: string;\n description?: string;\n source: RuleSource;\n scope: 'global' | 'project' | 'path-specific';\n paths?: string[];\n alwaysApply?: boolean;\n priority: number;\n hash: string;\n}\n\n/**\n * Format adapter interface — implement this for each agent/IDE.\n * Adding a new agent (e.g., Kiro) only requires implementing this interface.\n */\nexport interface RuleFormatAdapter {\n /** Unique identifier for this agent format */\n readonly source: RuleSource;\n\n /** File paths/globs this adapter can parse */\n readonly filePatterns: string[];\n\n /** Parse rule files into unified representation */\n parse(filePath: string, content: string): UnifiedRule[];\n\n /** Generate rule file content from unified representation */\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[];\n}\n\n// ============================================================\n// Project Identity\n// ============================================================\n\nexport interface ProjectInfo {\n id: string;\n name: string;\n gitRemote?: string;\n rootPath: string;\n}\n\n// ============================================================\n// Memorix Server Configuration\n// ============================================================\n\nexport interface MemorixConfig {\n dataDir: string;\n projectId: string;\n projectName: string;\n enableEmbeddings: boolean;\n enableRulesSync: boolean;\n watchRuleFiles: boolean;\n}\n\nexport const DEFAULT_CONFIG: Partial<MemorixConfig> = {\n enableEmbeddings: false,\n enableRulesSync: false,\n watchRuleFiles: false,\n};\n\n// ============================================================\n// Workspace Sync — Cross-Agent workspace migration\n// ============================================================\n\n/** Supported agent targets for workspace sync */\nexport type AgentTarget = 'windsurf' | 'cursor' | 'claude-code' | 'codex' | 'copilot' | 'antigravity' | 'kiro';\n\n/** A unified MCP server entry across all agent config formats */\nexport interface MCPServerEntry {\n name: string;\n /** Command for stdio transport */\n command: string;\n /** Args for stdio transport */\n args: string[];\n /** Environment variables */\n env?: Record<string, string> | null;\n /** URL for HTTP/SSE transport (Codex uses `url`, Windsurf uses `serverUrl`) */\n url?: string;\n /** HTTP headers (Windsurf uses `headers` for HTTP transport) */\n headers?: Record<string, string>;\n /** Whether this server is disabled */\n disabled?: boolean;\n}\n\n/** Unified workflow entry */\nexport interface WorkflowEntry {\n name: string;\n description: string;\n content: string;\n source: AgentTarget;\n filePath: string;\n}\n\n/** A skill folder discovered from an agent's skills directory */\nexport interface SkillEntry {\n name: string;\n description: string;\n sourcePath: string;\n sourceAgent: AgentTarget;\n}\n\n/** Conflict when two agents have a skill with the same folder name */\nexport interface SkillConflict {\n name: string;\n kept: SkillEntry;\n skipped: SkillEntry;\n}\n\n/** Result of a workspace sync operation */\nexport interface WorkspaceSyncResult {\n mcpServers: {\n scanned: MCPServerEntry[];\n generated: { filePath: string; content: string }[];\n };\n workflows: {\n scanned: WorkflowEntry[];\n generated: { filePath: string; content: string }[];\n };\n rules: {\n scanned: number;\n generated: number;\n };\n skills: {\n scanned: SkillEntry[];\n conflicts: SkillConflict[];\n copied: string[];\n skipped: string[];\n };\n}\n\n/** MCP config format adapter interface */\nexport interface MCPConfigAdapter {\n readonly source: AgentTarget;\n /** Parse MCP server entries from a config file */\n parse(content: string): MCPServerEntry[];\n /** Generate config file content from MCP server entries */\n generate(servers: MCPServerEntry[]): string;\n /** Get the default config file path for this agent */\n getConfigPath(projectRoot?: string): string;\n}\n","/**\n * FastEmbed Provider\n *\n * Local ONNX-based embedding using fastembed (Qdrant).\n * Model: BAAI/bge-small-en-v1.5 (384 dimensions, ~30MB)\n *\n * This is an optional dependency — if fastembed is not installed,\n * the provider module gracefully falls back to fulltext-only search.\n */\n\nimport type { EmbeddingProvider } from './provider.js';\n\n// Simple in-memory cache to avoid recomputing embeddings\nconst cache = new Map<string, number[]>();\nconst MAX_CACHE_SIZE = 5000;\n\nexport class FastEmbedProvider implements EmbeddingProvider {\n readonly name = 'fastembed-bge-small';\n readonly dimensions = 384;\n\n private model: { embed: (docs: string[], batchSize?: number) => AsyncGenerator<number[][]>; queryEmbed: (query: string) => Promise<number[]> };\n\n private constructor(model: FastEmbedProvider['model']) {\n this.model = model;\n }\n\n /**\n * Initialize the FastEmbed provider.\n * Downloads model on first use (~30MB), cached locally after.\n */\n static async create(): Promise<FastEmbedProvider> {\n // Dynamic import — throws if fastembed is not installed\n const { EmbeddingModel, FlagEmbedding } = await import('fastembed');\n const model = await FlagEmbedding.init({\n model: EmbeddingModel.BGESmallENV15,\n });\n return new FastEmbedProvider(model);\n }\n\n async embed(text: string): Promise<number[]> {\n // Check cache first\n const cached = cache.get(text);\n if (cached) return cached;\n\n const raw = await this.model.queryEmbed(text);\n // Ensure plain number[] (fastembed may return Float32Array)\n const result = Array.from(raw) as number[];\n if (result.length !== this.dimensions) {\n throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);\n }\n this.cacheSet(text, result);\n return result;\n }\n\n async embedBatch(texts: string[]): Promise<number[][]> {\n const results: number[][] = new Array(texts.length);\n const uncachedIndices: number[] = [];\n const uncachedTexts: string[] = [];\n\n // Check cache for each text\n for (let i = 0; i < texts.length; i++) {\n const cached = cache.get(texts[i]);\n if (cached) {\n results[i] = cached;\n } else {\n uncachedIndices.push(i);\n uncachedTexts.push(texts[i]);\n }\n }\n\n // Batch embed uncached texts\n if (uncachedTexts.length > 0) {\n let batchIdx = 0;\n for await (const batch of this.model.embed(uncachedTexts, 64)) {\n for (const vec of batch) {\n const originalIdx = uncachedIndices[batchIdx];\n const plain = Array.from(vec) as number[];\n results[originalIdx] = plain;\n this.cacheSet(uncachedTexts[batchIdx], plain);\n batchIdx++;\n }\n }\n }\n\n return results;\n }\n\n private cacheSet(key: string, value: number[]): void {\n // Evict oldest entries if cache is full\n if (cache.size >= MAX_CACHE_SIZE) {\n const firstKey = cache.keys().next().value;\n if (firstKey !== undefined) cache.delete(firstKey);\n }\n cache.set(key, value);\n }\n}\n","/**\r\n * Transformers.js Provider\r\n *\r\n * Pure JavaScript embedding using @huggingface/transformers (HuggingFace).\r\n * Model: Xenova/all-MiniLM-L6-v2 (384 dimensions, ~22MB quantized)\r\n *\r\n * Key advantages over fastembed:\r\n * - No native ONNX binding required (pure JS / WASM)\r\n * - Works out-of-the-box on Windows, macOS, Linux\r\n * - Supports quantized models (q8, q4) for smaller footprint\r\n *\r\n * This is an optional dependency — if @huggingface/transformers is not\r\n * installed, the provider module gracefully falls back to the next option.\r\n *\r\n * Inspired by Mem0's multi-provider embedding architecture.\r\n */\r\n\r\nimport type { EmbeddingProvider } from './provider.js';\r\n\r\n// In-memory LRU cache\r\nconst cache = new Map<string, number[]>();\r\nconst MAX_CACHE_SIZE = 5000;\r\n\r\nexport class TransformersProvider implements EmbeddingProvider {\r\n readonly name = 'transformers-minilm';\r\n readonly dimensions = 384;\r\n\r\n private extractor: any; // Pipeline instance\r\n\r\n private constructor(extractor: any) {\r\n this.extractor = extractor;\r\n }\r\n\r\n /**\r\n * Initialize the Transformers.js provider.\r\n * Downloads model on first use (~22MB quantized), cached locally after.\r\n */\r\n static async create(): Promise<TransformersProvider> {\r\n // Dynamic import — throws if @huggingface/transformers is not installed\r\n const { pipeline } = await import('@huggingface/transformers');\r\n const extractor = await pipeline(\r\n 'feature-extraction',\r\n 'Xenova/all-MiniLM-L6-v2',\r\n { dtype: 'q8' }, // Quantized for small footprint\r\n );\r\n return new TransformersProvider(extractor);\r\n }\r\n\r\n async embed(text: string): Promise<number[]> {\r\n // Check cache first\r\n const cached = cache.get(text);\r\n if (cached) return cached;\r\n\r\n const output = await this.extractor(text, {\r\n pooling: 'mean',\r\n normalize: true,\r\n });\r\n\r\n // output.tolist() returns [[...384 floats]]\r\n const result: number[] = Array.from(output.tolist()[0]);\r\n if (result.length !== this.dimensions) {\r\n throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);\r\n }\r\n\r\n this.cacheSet(text, result);\r\n return result;\r\n }\r\n\r\n async embedBatch(texts: string[]): Promise<number[][]> {\r\n const results: number[][] = new Array(texts.length);\r\n const uncachedIndices: number[] = [];\r\n const uncachedTexts: string[] = [];\r\n\r\n // Check cache for each text\r\n for (let i = 0; i < texts.length; i++) {\r\n const cached = cache.get(texts[i]);\r\n if (cached) {\r\n results[i] = cached;\r\n } else {\r\n uncachedIndices.push(i);\r\n uncachedTexts.push(texts[i]);\r\n }\r\n }\r\n\r\n // Batch embed uncached texts\r\n if (uncachedTexts.length > 0) {\r\n const output = await this.extractor(uncachedTexts, {\r\n pooling: 'mean',\r\n normalize: true,\r\n });\r\n const allVecs: number[][] = output.tolist();\r\n\r\n for (let i = 0; i < allVecs.length; i++) {\r\n const vec = Array.from(allVecs[i]) as number[];\r\n const originalIdx = uncachedIndices[i];\r\n results[originalIdx] = vec;\r\n this.cacheSet(uncachedTexts[i], vec);\r\n }\r\n }\r\n\r\n return results;\r\n }\r\n\r\n private cacheSet(key: string, value: number[]): void {\r\n if (cache.size >= MAX_CACHE_SIZE) {\r\n const firstKey = cache.keys().next().value;\r\n if (firstKey !== undefined) cache.delete(firstKey);\r\n }\r\n cache.set(key, value);\r\n }\r\n}\r\n","/**\n * Embedding Provider — Abstraction Layer\n *\n * Extensible embedding interface. Supports graceful degradation:\n * - fastembed installed → local ONNX inference (384-dim bge-small)\n * - @huggingface/transformers → pure JS WASM inference (384-dim MiniLM)\n * - nothing installed → null provider, search falls back to BM25\n *\n * Architecture inspired by Mem0's multi-provider embedding design.\n * Adding a new embedding backend only requires implementing EmbeddingProvider.\n */\n\nexport interface EmbeddingProvider {\n /** Provider name for logging/cache keys */\n readonly name: string;\n /** Vector dimensions (e.g., 384 for bge-small) */\n readonly dimensions: number;\n /** Generate embedding for a single text */\n embed(text: string): Promise<number[]>;\n /** Generate embeddings for multiple texts (batch) */\n embedBatch(texts: string[]): Promise<number[][]>;\n}\n\n/** Singleton provider instance (null = not available) */\nlet provider: EmbeddingProvider | null = null;\nlet initPromise: Promise<EmbeddingProvider | null> | null = null;\n\n/**\n * Get the embedding provider. Returns null if none available.\n * Lazy-initialized on first call. Concurrent callers share the same Promise.\n *\n * Provider priority:\n * 1. fastembed (fastest, but requires native ONNX binding)\n * 2. @huggingface/transformers (pure JS, best cross-platform compatibility)\n * 3. null → fulltext search only (BM25)\n */\nexport async function getEmbeddingProvider(): Promise<EmbeddingProvider | null> {\n if (initPromise) return initPromise;\n\n initPromise = (async () => {\n // Try fastembed first (local ONNX, fastest)\n try {\n const { FastEmbedProvider } = await import('./fastembed-provider.js');\n provider = await FastEmbedProvider.create();\n console.error(`[memorix] Embedding provider: ${provider!.name} (${provider!.dimensions}d)`);\n return provider;\n } catch {\n // fastembed not installed — try next\n }\n\n // Try @huggingface/transformers (pure JS, no native deps)\n try {\n const { TransformersProvider } = await import('./transformers-provider.js');\n provider = await TransformersProvider.create();\n console.error(`[memorix] Embedding provider: ${provider!.name} (${provider!.dimensions}d)`);\n return provider;\n } catch {\n // transformers not installed — degrade to fulltext\n }\n\n console.error('[memorix] No embedding provider available — using fulltext search only');\n return null;\n })();\n\n return initPromise;\n}\n\n/**\n * Check if vector search is available.\n */\nexport async function isVectorSearchAvailable(): Promise<boolean> {\n const p = await getEmbeddingProvider();\n return p !== null;\n}\n\n/**\n * Reset provider (for testing).\n */\nexport function resetProvider(): void {\n provider = null;\n initPromise = null;\n}\n","/**\n * Orama Store\n *\n * Full-text + vector + hybrid search engine backed by Orama.\n * Source: @orama/orama (10.1K stars, <2KB, pure JS, zero deps)\n *\n * Schema designed to store Observations with all searchable fields.\n * Vector search (embeddings) will be added in P1 phase.\n */\n\nimport { create, insert, search, remove, count, type AnyOrama } from '@orama/orama';\nimport type { MemorixDocument, SearchOptions, IndexEntry } from '../types.js';\nimport { OBSERVATION_ICONS, type ObservationType } from '../types.js';\nimport { getEmbeddingProvider, type EmbeddingProvider } from '../embedding/provider.js';\n\nlet db: AnyOrama | null = null;\nlet embeddingEnabled = false;\n\n/**\n * Initialize or return the Orama database instance.\n * Schema conditionally includes vector field based on embedding provider.\n * Graceful degradation: no provider → fulltext only, provider → hybrid.\n */\nexport async function getDb(): Promise<AnyOrama> {\n if (db) return db;\n\n // Check if embedding provider is available\n const provider = await getEmbeddingProvider();\n embeddingEnabled = provider !== null;\n\n const baseSchema = {\n id: 'string' as const,\n observationId: 'number' as const,\n entityName: 'string' as const,\n type: 'string' as const,\n title: 'string' as const,\n narrative: 'string' as const,\n facts: 'string' as const,\n filesModified: 'string' as const,\n concepts: 'string' as const,\n tokens: 'number' as const,\n createdAt: 'string' as const,\n projectId: 'string' as const,\n accessCount: 'number' as const,\n lastAccessedAt: 'string' as const,\n };\n\n const schema = embeddingEnabled\n ? { ...baseSchema, embedding: 'vector[384]' as const }\n : baseSchema;\n\n db = await create({ schema });\n\n return db;\n}\n\n/**\n * Reset the database instance (useful for testing).\n */\nexport async function resetDb(): Promise<void> {\n db = null;\n embeddingEnabled = false;\n}\n\n/**\n * Check if embedding/vector search is active.\n */\nexport function isEmbeddingEnabled(): boolean {\n return embeddingEnabled;\n}\n\n/**\n * Generate embedding for text content using the available provider.\n * Returns null if no provider is available.\n */\nexport async function generateEmbedding(text: string): Promise<number[] | null> {\n const provider = await getEmbeddingProvider();\n if (!provider) return null;\n return provider.embed(text);\n}\n\n/**\n * Insert an observation document into the store.\n */\nexport async function insertObservation(doc: MemorixDocument): Promise<void> {\n const database = await getDb();\n await insert(database, doc);\n}\n\n/**\n * Remove an observation document by its Orama internal ID.\n */\nexport async function removeObservation(oramaId: string): Promise<void> {\n const database = await getDb();\n await remove(database, oramaId);\n}\n\n/**\n * Search observations using Orama full-text search.\n * Returns L1 IndexEntry array (compact, ~50-100 tokens per result).\n *\n * Progressive Disclosure Layer 1 — adopted from claude-mem.\n */\nexport async function searchObservations(options: SearchOptions): Promise<IndexEntry[]> {\n const database = await getDb();\n\n const filters: Record<string, unknown> = {};\n if (options.projectId) {\n filters['projectId'] = options.projectId;\n }\n if (options.type) {\n filters['type'] = options.type;\n }\n\n // Determine search mode: hybrid (with vector) or fulltext (default)\n let searchParams: Record<string, unknown> = {\n term: options.query,\n limit: options.limit ?? 20,\n ...(Object.keys(filters).length > 0 ? { where: filters } : {}),\n };\n\n // If embedding provider is available and we have a query, use hybrid search\n if (embeddingEnabled && options.query && options.query.trim().length > 0) {\n try {\n const provider = await getEmbeddingProvider();\n if (provider) {\n const queryVector = await provider.embed(options.query);\n searchParams = {\n ...searchParams,\n mode: 'hybrid',\n vector: {\n value: queryVector,\n property: 'embedding',\n },\n similarity: 0.7,\n };\n }\n } catch {\n // Fallback to fulltext if embedding fails\n }\n }\n\n const results = await search(database, searchParams);\n\n let entries = results.hits.map((hit) => {\n const doc = hit.document as unknown as MemorixDocument;\n const obsType = doc.type as ObservationType;\n return {\n id: doc.observationId,\n time: formatTime(doc.createdAt),\n type: obsType,\n icon: OBSERVATION_ICONS[obsType] ?? '❓',\n title: doc.title,\n tokens: doc.tokens,\n };\n });\n\n // Apply token budget if specified (inspired by MemCP)\n if (options.maxTokens && options.maxTokens > 0) {\n entries = applyTokenBudget(entries, options.maxTokens);\n }\n\n // Record access for returned results (inspired by mcp-memory-service)\n const hitIds = results.hits.map((h) => (h.document as unknown as MemorixDocument).id);\n recordAccessBatch(hitIds).catch(() => {});\n\n return entries;\n}\n\n/**\n * Get full observation documents by their observation IDs.\n *\n * Progressive Disclosure Layer 3 — adopted from claude-mem.\n */\nexport async function getObservationsByIds(\n ids: number[],\n projectId?: string,\n): Promise<MemorixDocument[]> {\n const database = await getDb();\n\n // Search for each ID individually and collect results\n const results: MemorixDocument[] = [];\n\n for (const id of ids) {\n const searchResult = await search(database, {\n term: '',\n where: {\n observationId: { eq: id },\n ...(projectId ? { projectId } : {}),\n },\n limit: 1,\n });\n\n if (searchResult.hits.length > 0) {\n results.push(searchResult.hits[0].document as unknown as MemorixDocument);\n }\n }\n\n return results;\n}\n\n/**\n * Get observations around an anchor for timeline context.\n *\n * Progressive Disclosure Layer 2 — adopted from claude-mem.\n */\nexport async function getTimeline(\n anchorId: number,\n projectId?: string,\n depthBefore = 3,\n depthAfter = 3,\n): Promise<{ before: IndexEntry[]; anchor: IndexEntry | null; after: IndexEntry[] }> {\n const database = await getDb();\n\n // Get all observations sorted by time (no projectId filter — shared across agents)\n const searchParams: { term: string; where?: Record<string, unknown>; limit: number } = {\n term: '',\n limit: 1000,\n };\n if (projectId) {\n searchParams.where = { projectId };\n }\n const allResults = await search(database, searchParams);\n\n const docs = allResults.hits\n .map((h) => h.document as unknown as MemorixDocument)\n .sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n\n const anchorIndex = docs.findIndex((d) => d.observationId === anchorId);\n if (anchorIndex === -1) {\n return { before: [], anchor: null, after: [] };\n }\n\n const toIndexEntry = (doc: MemorixDocument): IndexEntry => {\n const obsType = doc.type as ObservationType;\n return {\n id: doc.observationId,\n time: formatTime(doc.createdAt),\n type: obsType,\n icon: OBSERVATION_ICONS[obsType] ?? '❓',\n title: doc.title,\n tokens: doc.tokens,\n };\n };\n\n const before = docs\n .slice(Math.max(0, anchorIndex - depthBefore), anchorIndex)\n .map(toIndexEntry);\n\n const after = docs\n .slice(anchorIndex + 1, anchorIndex + 1 + depthAfter)\n .map(toIndexEntry);\n\n return {\n before,\n anchor: toIndexEntry(docs[anchorIndex]),\n after,\n };\n}\n\n/**\n * Record access for observations returned in search results.\n * Increments accessCount and updates lastAccessedAt.\n * Inspired by mcp-memory-service's record_access() pattern.\n */\nasync function recordAccessBatch(oramaIds: string[]): Promise<void> {\n const database = await getDb();\n const now = new Date().toISOString();\n\n for (const id of oramaIds) {\n try {\n // Fetch current doc\n const result = await search(database, {\n term: '',\n where: { id },\n limit: 1,\n });\n if (result.hits.length === 0) continue;\n const doc = result.hits[0].document as unknown as MemorixDocument;\n\n // Remove and re-insert with updated access metadata\n await remove(database, id);\n await insert(database, {\n ...doc,\n accessCount: (doc.accessCount ?? 0) + 1,\n lastAccessedAt: now,\n });\n } catch {\n // Best-effort — don't break search if access tracking fails\n }\n }\n}\n\n/**\n * Trim search results to fit within a token budget.\n * Inspired by MemCP's _apply_token_budget() pattern.\n */\nfunction applyTokenBudget(entries: IndexEntry[], maxTokens: number): IndexEntry[] {\n const budgeted: IndexEntry[] = [];\n let tokensUsed = 0;\n\n for (const entry of entries) {\n if (tokensUsed + entry.tokens > maxTokens && budgeted.length > 0) {\n break;\n }\n budgeted.push(entry);\n tokensUsed += entry.tokens;\n }\n\n return budgeted;\n}\n\n/**\n * Get total observation count, optionally filtered by project.\n */\nexport async function getObservationCount(projectId?: string): Promise<number> {\n const database = await getDb();\n if (!projectId) {\n return await count(database);\n }\n const results = await search(database, {\n term: '',\n where: { projectId },\n limit: 0,\n });\n return results.count;\n}\n\n/**\n * Format ISO date string to compact time display.\n */\nfunction formatTime(isoDate: string): string {\n try {\n const date = new Date(isoDate);\n return date.toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n });\n } catch {\n return isoDate;\n }\n}\n","/**\n * Token Budget Manager\n *\n * Provides token counting and budget management for Progressive Disclosure.\n * Source: gpt-tokenizer (737 stars, JS port of OpenAI's tiktoken)\n *\n * Used by the Compact Engine to determine which layer of detail\n * fits within the caller's token budget.\n */\n\nimport { countTokens, isWithinTokenLimit } from 'gpt-tokenizer';\n\n/**\n * Count tokens in a string.\n */\nexport function countTextTokens(text: string): number {\n return countTokens(text);\n}\n\n/**\n * Check if text fits within a token limit.\n * Returns the token count if within limit, false otherwise.\n */\nexport function fitsInBudget(text: string, limit: number): number | false {\n return isWithinTokenLimit(text, limit);\n}\n\n/**\n * Truncate text to fit within a token budget.\n * Truncates at sentence boundaries when possible.\n */\nexport function truncateToTokenBudget(text: string, budget: number): string {\n if (fitsInBudget(text, budget) !== false) {\n return text;\n }\n\n // Binary search for the right length\n const sentences = text.split(/(?<=[.!?])\\s+/);\n let result = '';\n\n for (const sentence of sentences) {\n const candidate = result ? `${result} ${sentence}` : sentence;\n if (fitsInBudget(candidate, budget) === false) {\n break;\n }\n result = candidate;\n }\n\n // If no complete sentence fits, truncate by characters\n if (!result) {\n // Rough estimate: 1 token ≈ 4 chars for English, ≈ 1.5 chars for Chinese\n const estimatedChars = budget * 2;\n result = text.slice(0, estimatedChars);\n // Refine\n while (fitsInBudget(result, budget) === false && result.length > 0) {\n result = result.slice(0, Math.floor(result.length * 0.9));\n }\n if (result.length < text.length) {\n result += '...';\n }\n }\n\n return result;\n}\n\n/**\n * Estimate the token cost of an IndexEntry line.\n * Used to predict compact index size.\n */\nexport function estimateIndexEntryTokens(title: string): number {\n // Format: \"| #ID | Time | Icon | Title | ~Tokens |\"\n // Overhead is roughly 15 tokens for formatting\n return countTextTokens(title) + 15;\n}\n","/**\n * Entity Extractor\n *\n * Regex-based entity extraction from observation content.\n * Inspired by MemCP's RegexEntityExtractor (MAGMA paper).\n *\n * Extracts: file paths, module paths, URLs, @mentions, CamelCase identifiers.\n * Also detects causal patterns for automatic edge typing.\n */\n\nconst ENTITY_PATTERNS: Array<{ kind: string; pattern: RegExp }> = [\n // File paths (e.g. src/auth/jwt.ts, ./config.json)\n { kind: 'file', pattern: /(?:^|[\\s\"'(])([.\\w/-]+\\.\\w{1,10})(?:[\\s\"'),]|$)/g },\n // Module/package paths (e.g. @orama/orama, memcp.core.graph)\n { kind: 'module', pattern: /(?:^|[\\s\"'(,])(@[\\w-]+\\/[\\w.-]+)|\\b([a-zA-Z_]\\w*(?:\\.[a-zA-Z_]\\w*){2,})\\b/g },\n // URLs\n { kind: 'url', pattern: /https?:\\/\\/[^\\s\"'<>)]+/g },\n // @mentions\n { kind: 'mention', pattern: /@([a-zA-Z_]\\w+)/g },\n // CamelCase identifiers (likely class/type names)\n { kind: 'identifier', pattern: /\\b([A-Z][a-z]+(?:[A-Z][a-z]+)+)\\b/g },\n];\n\n/**\n * Patterns that indicate causal relationships.\n * Used to auto-detect causal edge types in Knowledge Graph.\n */\nconst CAUSAL_PATTERN = /\\b(?:because|therefore|due to|caused by|as a result|decided to|chosen because|so that|in order to|leads to|results in|fixed by|resolved by)\\b/i;\n\nexport interface ExtractedEntities {\n files: string[];\n modules: string[];\n urls: string[];\n mentions: string[];\n identifiers: string[];\n hasCausalLanguage: boolean;\n}\n\n/**\n * Extract entities from text content.\n * Returns deduplicated lists of each entity type.\n */\nexport function extractEntities(content: string): ExtractedEntities {\n const result: ExtractedEntities = {\n files: [],\n modules: [],\n urls: [],\n mentions: [],\n identifiers: [],\n hasCausalLanguage: false,\n };\n\n const seen = new Set<string>();\n\n for (const { kind, pattern } of ENTITY_PATTERNS) {\n // Reset lastIndex for global regexes\n pattern.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(content)) !== null) {\n const entity = (match[1] ?? match[2] ?? match[0]).trim().replace(/^[\"'(]+|[\"'),]+$/g, '');\n if (entity.length < 3 || (kind === 'file' && entity.length < 5)) continue;\n\n const key = `${kind}:${entity.toLowerCase()}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n switch (kind) {\n case 'file':\n result.files.push(entity);\n break;\n case 'module':\n result.modules.push(entity);\n break;\n case 'url':\n result.urls.push(entity);\n break;\n case 'mention':\n result.mentions.push(entity);\n break;\n case 'identifier':\n result.identifiers.push(entity);\n break;\n }\n }\n }\n\n result.hasCausalLanguage = CAUSAL_PATTERN.test(content);\n\n return result;\n}\n\n/**\n * Auto-generate concepts from extracted entities.\n * Merges with any user-provided concepts.\n */\nexport function enrichConcepts(\n userConcepts: string[],\n extracted: ExtractedEntities,\n): string[] {\n const all = new Set(userConcepts.map((c) => c.toLowerCase()));\n const enriched = [...userConcepts];\n\n // Add file names (without path) as concepts\n for (const f of extracted.files) {\n const name = f.split('/').pop()?.replace(/\\.\\w+$/, '') ?? '';\n if (name.length >= 3 && !all.has(name.toLowerCase())) {\n all.add(name.toLowerCase());\n enriched.push(name);\n }\n }\n\n // Add module names as concepts\n for (const m of extracted.modules) {\n const short = m.split(/[./]/).pop() ?? '';\n if (short.length >= 3 && !all.has(short.toLowerCase())) {\n all.add(short.toLowerCase());\n enriched.push(short);\n }\n }\n\n // Add CamelCase identifiers as concepts\n for (const id of extracted.identifiers) {\n if (!all.has(id.toLowerCase())) {\n all.add(id.toLowerCase());\n enriched.push(id);\n }\n }\n\n return enriched;\n}\n","/**\n * Observations Manager\n *\n * Manages rich observation records with auto-classification and token counting.\n * Source: claude-mem's observation data model with structured fields.\n *\n * Each observation is stored both in the knowledge graph (as entity observation)\n * and in the Orama search index (for full-text + vector search).\n */\n\nimport type { Observation, ObservationType, MemorixDocument } from '../types.js';\nimport { insertObservation, generateEmbedding, isEmbeddingEnabled } from '../store/orama-store.js';\nimport { saveObservationsJson, loadObservationsJson, saveIdCounter, loadIdCounter } from '../store/persistence.js';\nimport { countTextTokens } from '../compact/token-budget.js';\nimport { extractEntities, enrichConcepts } from './entity-extractor.js';\n\n/** In-memory observation list (loaded from persistence on init) */\nlet observations: Observation[] = [];\nlet nextId = 1;\nlet projectDir: string | null = null;\n\n/**\n * Initialize the observations manager with a project directory.\n */\nexport async function initObservations(dir: string): Promise<void> {\n projectDir = dir;\n const loaded = await loadObservationsJson(dir);\n observations = loaded as Observation[];\n nextId = await loadIdCounter(dir);\n}\n\n/**\n * Store a new observation.\n *\n * This is the primary write API — called by the `memorix_store` MCP tool.\n * Automatically:\n * 1. Assigns an incremental ID\n * 2. Counts tokens for the observation content\n * 3. Inserts into Orama for full-text search\n * 4. Persists to disk\n */\nexport async function storeObservation(input: {\n entityName: string;\n type: ObservationType;\n title: string;\n narrative: string;\n facts?: string[];\n filesModified?: string[];\n concepts?: string[];\n projectId: string;\n}): Promise<Observation> {\n const id = nextId++;\n const now = new Date().toISOString();\n\n // Auto-extract entities from narrative (inspired by MemCP RegexEntityExtractor)\n const contentForExtraction = [input.title, input.narrative, ...(input.facts ?? [])].join(' ');\n const extracted = extractEntities(contentForExtraction);\n\n // Auto-enrich concepts with extracted entities\n const enrichedConcepts = enrichConcepts(input.concepts ?? [], extracted);\n\n // Auto-enrich filesModified with extracted file paths\n const userFiles = new Set((input.filesModified ?? []).map((f) => f.toLowerCase()));\n const enrichedFiles = [...(input.filesModified ?? [])];\n for (const f of extracted.files) {\n if (!userFiles.has(f.toLowerCase())) {\n enrichedFiles.push(f);\n }\n }\n\n // Count tokens for the full observation content\n const fullText = [\n input.title,\n input.narrative,\n ...(input.facts ?? []),\n ...enrichedFiles,\n ...enrichedConcepts,\n ].join(' ');\n const tokens = countTextTokens(fullText);\n\n const observation: Observation = {\n id,\n entityName: input.entityName,\n type: input.type,\n title: input.title,\n narrative: input.narrative,\n facts: input.facts ?? [],\n filesModified: enrichedFiles,\n concepts: enrichedConcepts,\n tokens,\n createdAt: now,\n projectId: input.projectId,\n hasCausalLanguage: extracted.hasCausalLanguage,\n };\n\n observations.push(observation);\n\n // Generate embedding if provider is available (graceful degradation)\n const searchableText = [input.title, input.narrative, ...(input.facts ?? [])].join(' ');\n const embedding = await generateEmbedding(searchableText);\n\n // Insert into Orama search index\n const doc: MemorixDocument = {\n id: `obs-${id}`,\n observationId: id,\n entityName: input.entityName,\n type: input.type,\n title: input.title,\n narrative: input.narrative,\n facts: (input.facts ?? []).join('\\n'),\n filesModified: enrichedFiles.join('\\n'),\n concepts: enrichedConcepts.join(', '),\n tokens,\n createdAt: now,\n projectId: input.projectId,\n accessCount: 0,\n lastAccessedAt: '',\n ...(embedding ? { embedding } : {}),\n };\n\n await insertObservation(doc);\n\n // Persist to disk\n if (projectDir) {\n await saveObservationsJson(projectDir, observations);\n await saveIdCounter(projectDir, nextId);\n }\n\n return observation;\n}\n\n/**\n * Get an observation by ID.\n */\nexport function getObservation(id: number): Observation | undefined {\n return observations.find((o) => o.id === id);\n}\n\n/**\n * Get all observations for a project.\n */\nexport function getProjectObservations(projectId: string): Observation[] {\n return observations.filter((o) => o.projectId === projectId);\n}\n\n/**\n * Get the total number of stored observations.\n */\nexport function getObservationCount(): number {\n return observations.length;\n}\n\n/**\n * Reload observations into the Orama index.\n * Called during server startup to restore the search index.\n */\nexport async function reindexObservations(): Promise<number> {\n let count = 0;\n for (const obs of observations) {\n try {\n // Generate embedding during reindex if provider is available\n let embedding: number[] | null = null;\n if (isEmbeddingEnabled()) {\n try {\n const searchableText = [obs.title, obs.narrative, ...obs.facts].join(' ');\n embedding = await generateEmbedding(searchableText);\n } catch {\n // Embedding generation failed for this observation — skip vector, use fulltext\n }\n }\n\n const doc: MemorixDocument = {\n id: `obs-${obs.id}`,\n observationId: obs.id,\n entityName: obs.entityName,\n type: obs.type,\n title: obs.title,\n narrative: obs.narrative,\n facts: obs.facts.join('\\n'),\n filesModified: obs.filesModified.join('\\n'),\n concepts: obs.concepts.join(', '),\n tokens: obs.tokens,\n createdAt: obs.createdAt,\n projectId: obs.projectId,\n accessCount: 0,\n lastAccessedAt: '',\n ...(embedding ? { embedding } : {}),\n };\n await insertObservation(doc);\n count++;\n } catch (err) {\n console.error(`[memorix] Failed to reindex observation #${obs.id}: ${err}`);\n }\n }\n return count;\n}\n","/**\n * Auto-Relation Creator\n *\n * Automatically creates Knowledge Graph relations from entity extraction.\n * Inspired by mcp-memory-service's typed relationships and MemCP's MAGMA 4-graph.\n *\n * When an observation is stored:\n * 1. Extract entities from narrative (files, modules, CamelCase)\n * 2. Find matching existing entities in the graph\n * 3. Auto-create relations: \"references\", \"modifies\", or \"causes\" (if causal)\n *\n * This is \"implicit memory\" — the agent doesn't need to call create_relations.\n */\n\nimport type { Observation, Relation } from '../types.js';\nimport type { KnowledgeGraphManager } from './graph.js';\nimport type { ExtractedEntities } from './entity-extractor.js';\n\n/**\n * Infer relation type based on observation type and causal language.\n */\nfunction inferRelationType(obs: Observation): string {\n if (obs.hasCausalLanguage) return 'causes';\n\n switch (obs.type) {\n case 'problem-solution':\n return 'fixes';\n case 'decision':\n case 'trade-off':\n return 'decides';\n case 'what-changed':\n return 'modifies';\n case 'gotcha':\n return 'warns_about';\n default:\n return 'references';\n }\n}\n\n/**\n * Auto-create relations from a stored observation.\n *\n * Scans the knowledge graph for entities matching extracted file names,\n * modules, and identifiers, then creates typed relations.\n *\n * Returns the number of relations created.\n */\nexport async function createAutoRelations(\n obs: Observation,\n extracted: ExtractedEntities,\n graphManager: KnowledgeGraphManager,\n): Promise<number> {\n const relationType = inferRelationType(obs);\n const relations: Relation[] = [];\n\n // Get all existing entity names from the graph\n const graph = await graphManager.readGraph();\n const existingNames = new Set(graph.entities.map((e) => e.name.toLowerCase()));\n\n // Skip self-references\n const selfName = obs.entityName.toLowerCase();\n\n // Check extracted identifiers against existing entities\n const candidates = [\n ...extracted.identifiers,\n ...extracted.files.map((f) => f.split('/').pop()?.replace(/\\.\\w+$/, '') ?? ''),\n ...extracted.modules.map((m) => m.split(/[./]/).pop() ?? ''),\n ].filter((c) => c.length >= 3);\n\n for (const candidate of candidates) {\n const lower = candidate.toLowerCase();\n if (lower === selfName) continue;\n\n // Find matching entity (case-insensitive)\n const matchedEntity = graph.entities.find(\n (e) => e.name.toLowerCase() === lower,\n );\n\n if (matchedEntity) {\n relations.push({\n from: obs.entityName,\n to: matchedEntity.name,\n relationType,\n });\n }\n }\n\n // Also create relations from explicit filesModified → existing entities\n for (const file of obs.filesModified) {\n const basename = file.split('/').pop()?.replace(/\\.\\w+$/, '') ?? '';\n if (basename.length < 3 || basename.toLowerCase() === selfName) continue;\n\n const matchedEntity = graph.entities.find(\n (e) => e.name.toLowerCase() === basename.toLowerCase(),\n );\n\n if (matchedEntity) {\n relations.push({\n from: obs.entityName,\n to: matchedEntity.name,\n relationType: 'modifies',\n });\n }\n }\n\n if (relations.length === 0) return 0;\n\n // Deduplicate\n const unique = relations.filter(\n (r, i, arr) =>\n arr.findIndex(\n (o) => o.from === r.from && o.to === r.to && o.relationType === r.relationType,\n ) === i,\n );\n\n const created = await graphManager.createRelations(unique);\n return created.length;\n}\n","/**\n * Index Formatter\n *\n * Formats observation search results into the compact index table format.\n * Source: claude-mem's Progressive Disclosure index format.\n *\n * Output is a markdown table that agents can scan efficiently:\n * | ID | Time | T | Title | Tokens |\n * |-------|----------|----|--------------------------|--------|\n * | #42 | 2:14 PM | 🔴 | port 3001 conflict fix | ~155 |\n */\n\nimport type { IndexEntry, TimelineContext } from '../types.js';\n\n/**\n * Format a list of IndexEntries as a compact markdown table.\n * Grouped by date for readability (claude-mem pattern).\n */\nexport function formatIndexTable(entries: IndexEntry[], query?: string): string {\n if (entries.length === 0) {\n return query\n ? `No observations found matching \"${query}\".`\n : 'No observations found.';\n }\n\n const lines: string[] = [];\n\n if (query) {\n lines.push(`Found ${entries.length} observation(s) matching \"${query}\":\\n`);\n }\n\n lines.push('| ID | Time | T | Title | Tokens |');\n lines.push('|----|------|---|-------|--------|');\n\n for (const entry of entries) {\n lines.push(\n `| #${entry.id} | ${entry.time} | ${entry.icon} | ${entry.title} | ~${entry.tokens} |`,\n );\n }\n\n lines.push('');\n lines.push(PROGRESSIVE_DISCLOSURE_HINT);\n\n return lines.join('\\n');\n}\n\n/**\n * Format a timeline context around an anchor observation.\n */\nexport function formatTimeline(timeline: TimelineContext): string {\n if (!timeline.anchorEntry) {\n return `Observation #${timeline.anchorId} not found.`;\n }\n\n const lines: string[] = [];\n lines.push(`Timeline around #${timeline.anchorId}:\\n`);\n\n if (timeline.before.length > 0) {\n lines.push('**Before:**');\n lines.push('| ID | Time | T | Title | Tokens |');\n lines.push('|----|------|---|-------|--------|');\n for (const entry of timeline.before) {\n lines.push(`| #${entry.id} | ${entry.time} | ${entry.icon} | ${entry.title} | ~${entry.tokens} |`);\n }\n lines.push('');\n }\n\n lines.push('**► Anchor:**');\n lines.push('| ID | Time | T | Title | Tokens |');\n lines.push('|----|------|---|-------|--------|');\n const a = timeline.anchorEntry;\n lines.push(`| #${a.id} | ${a.time} | ${a.icon} | ${a.title} | ~${a.tokens} |`);\n lines.push('');\n\n if (timeline.after.length > 0) {\n lines.push('**After:**');\n lines.push('| ID | Time | T | Title | Tokens |');\n lines.push('|----|------|---|-------|--------|');\n for (const entry of timeline.after) {\n lines.push(`| #${entry.id} | ${entry.time} | ${entry.icon} | ${entry.title} | ~${entry.tokens} |`);\n }\n lines.push('');\n }\n\n lines.push(PROGRESSIVE_DISCLOSURE_HINT);\n return lines.join('\\n');\n}\n\n/**\n * Format full observation details (Layer 3).\n * Adopted from claude-mem's observation detail format.\n */\nexport function formatObservationDetail(doc: {\n observationId: number;\n type: string;\n title: string;\n narrative: string;\n facts: string;\n filesModified: string;\n concepts: string;\n createdAt: string;\n projectId: string;\n entityName: string;\n}): string {\n const icon = getTypeIcon(doc.type);\n const lines: string[] = [];\n\n lines.push(`#${doc.observationId} ${icon} ${doc.title}`);\n lines.push('─'.repeat(50));\n lines.push(`Date: ${new Date(doc.createdAt).toLocaleString()}`);\n lines.push(`Type: ${doc.type}`);\n lines.push(`Entity: ${doc.entityName}`);\n lines.push(`Project: ${doc.projectId}`);\n lines.push('');\n lines.push(`Narrative: ${doc.narrative}`);\n\n const facts = doc.facts ? doc.facts.split('\\n').filter(Boolean) : [];\n if (facts.length > 0) {\n lines.push('');\n lines.push('Facts:');\n for (const fact of facts) {\n lines.push(`- ${fact}`);\n }\n }\n\n const files = doc.filesModified ? doc.filesModified.split('\\n').filter(Boolean) : [];\n if (files.length > 0) {\n lines.push('');\n lines.push('Files Modified:');\n for (const file of files) {\n lines.push(`- ${file}`);\n }\n }\n\n if (doc.concepts) {\n lines.push('');\n lines.push(`Concepts: ${doc.concepts}`);\n }\n\n return lines.join('\\n');\n}\n\n/** Icon lookup by observation type string */\nfunction getTypeIcon(type: string): string {\n const icons: Record<string, string> = {\n 'session-request': '🎯',\n 'gotcha': '🔴',\n 'problem-solution': '🟡',\n 'how-it-works': '🔵',\n 'what-changed': '🟢',\n 'discovery': '🟣',\n 'why-it-exists': '🟠',\n 'decision': '🟤',\n 'trade-off': '⚖️',\n };\n return icons[type] ?? '❓';\n}\n\n/**\n * Progressive Disclosure instruction hint.\n * Appended to L1/L2 results to teach the agent the workflow.\n */\nconst PROGRESSIVE_DISCLOSURE_HINT = `💡 **Progressive Disclosure:** This index shows WHAT exists and retrieval COST.\n- Use \\`memorix_detail\\` to fetch full observation details by ID\n- Use \\`memorix_timeline\\` to see chronological context around an observation\n- Critical types (🔴 gotcha, 🟤 decision, ⚖️ trade-off) are often worth fetching immediately`;\n","/**\n * Compact Engine\n *\n * Orchestrates the 3-layer Progressive Disclosure workflow.\n * Source: claude-mem's proven architecture (27K stars, ~10x token savings).\n *\n * Layer 1 (search) → Compact index with IDs (~50-100 tokens/result)\n * Layer 2 (timeline) → Chronological context around an observation\n * Layer 3 (detail) → Full observation content (~500-1000 tokens/result)\n */\n\nimport type { SearchOptions, IndexEntry, TimelineContext, MemorixDocument } from '../types.js';\nimport { searchObservations, getTimeline } from '../store/orama-store.js';\nimport { getObservation } from '../memory/observations.js';\nimport { formatIndexTable, formatTimeline, formatObservationDetail } from './index-format.js';\nimport { countTextTokens } from './token-budget.js';\n\n/**\n * Layer 1: Search and return a compact index.\n * Agent scans this to decide which observations to fetch in detail.\n */\nexport async function compactSearch(options: SearchOptions): Promise<{\n entries: IndexEntry[];\n formatted: string;\n totalTokens: number;\n}> {\n const entries = await searchObservations(options);\n const formatted = formatIndexTable(entries, options.query);\n const totalTokens = countTextTokens(formatted);\n\n return { entries, formatted, totalTokens };\n}\n\n/**\n * Layer 2: Get timeline context around an anchor observation.\n * Shows what happened before and after for temporal understanding.\n */\nexport async function compactTimeline(\n anchorId: number,\n projectId?: string,\n depthBefore = 3,\n depthAfter = 3,\n): Promise<{\n timeline: TimelineContext;\n formatted: string;\n totalTokens: number;\n}> {\n const result = await getTimeline(anchorId, projectId, depthBefore, depthAfter);\n\n const timeline: TimelineContext = {\n anchorId,\n anchorEntry: result.anchor,\n before: result.before,\n after: result.after,\n };\n\n const formatted = formatTimeline(timeline);\n const totalTokens = countTextTokens(formatted);\n\n return { timeline, formatted, totalTokens };\n}\n\n/**\n * Layer 3: Get full observation details by IDs.\n * Only called after the agent has filtered via L1/L2.\n */\nexport async function compactDetail(\n ids: number[],\n): Promise<{\n documents: MemorixDocument[];\n formatted: string;\n totalTokens: number;\n}> {\n // Use in-memory observations for reliable ID lookup (Orama where-clause\n // can be unreliable with empty term + number filter)\n const documents: MemorixDocument[] = [];\n for (const id of ids) {\n const obs = getObservation(id);\n if (obs) {\n documents.push({\n id: `obs-${obs.id}`,\n observationId: obs.id,\n entityName: obs.entityName,\n type: obs.type,\n title: obs.title,\n narrative: obs.narrative,\n facts: obs.facts.join('\\n'),\n filesModified: obs.filesModified.join('\\n'),\n concepts: obs.concepts.join(', '),\n tokens: obs.tokens,\n createdAt: obs.createdAt,\n projectId: obs.projectId,\n accessCount: 0,\n lastAccessedAt: '',\n });\n }\n }\n\n const formattedParts = documents.map((doc: MemorixDocument) =>\n formatObservationDetail(doc),\n );\n\n const formatted = formattedParts.join('\\n\\n' + '═'.repeat(50) + '\\n\\n');\n const totalTokens = countTextTokens(formatted);\n\n return { documents, formatted, totalTokens };\n}\n","/**\n * Project Detector\n *\n * Identifies the current project using Git remote URL.\n * Source: shared-agent-memory's Git-based project isolation pattern.\n *\n * Extensible: fallback strategies can be added for non-git projects\n * (e.g., package.json name, directory name, etc.)\n */\n\nimport { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport type { ProjectInfo } from '../types.js';\n\n/**\n * Detect the current project identity from Git remote or fallback.\n * @param cwd - Working directory to detect from (defaults to process.cwd())\n */\nexport function detectProject(cwd?: string): ProjectInfo {\n const basePath = cwd ?? process.cwd();\n // Priority: git root > package.json dir > CWD\n const rootPath = getGitRoot(basePath) ?? findPackageRoot(basePath) ?? basePath;\n const gitRemote = getGitRemote(rootPath);\n\n if (gitRemote) {\n const id = normalizeGitRemote(gitRemote);\n const name = id.split('/').pop() ?? path.basename(rootPath);\n return { id, name, gitRemote, rootPath };\n }\n\n // Validate the root before creating a fallback project.\n // This prevents home dirs, system dirs, and IDE config dirs from\n // becoming phantom projects with garbage data directories.\n if (!isValidProjectRoot(rootPath)) {\n // Use a generic sentinel ID — data will NOT be persisted\n console.error(`[memorix] Skipped invalid project root: ${rootPath}`);\n return { id: '__invalid__', name: 'unknown', rootPath };\n }\n\n // Fallback: use \"local/<dirname>\" to distinguish non-git projects\n const name = path.basename(rootPath);\n const id = `local/${name}`;\n console.error(`[memorix] Warning: no git remote found at ${rootPath}, using fallback projectId: ${id}`);\n return { id, name, rootPath };\n}\n\n/**\n * Check whether a directory looks like a real project root.\n * Returns false for home directories, OS system directories,\n * drive roots, and IDE/tool configuration directories.\n */\nfunction isValidProjectRoot(dirPath: string): boolean {\n const resolved = path.resolve(dirPath);\n const home = path.resolve(os.homedir());\n\n // Reject the home directory itself (e.g., C:\\Users\\Lenovo, /home/user)\n if (resolved === home) return false;\n\n // Reject drive roots (C:\\, D:\\, /)\n if (resolved === path.parse(resolved).root) return false;\n\n // Reject immediate children of home that are IDE/tool config dirs\n const basename = path.basename(resolved).toLowerCase();\n const knownNonProjectDirs = new Set([\n // IDE / editor config dirs\n '.vscode', '.cursor', '.windsurf', '.kiro', '.codex',\n '.gemini', '.claude', '.github', '.git',\n // OS / system dirs\n 'desktop', 'documents', 'downloads', 'pictures', 'videos', 'music',\n 'appdata', 'application data', 'library',\n // Package manager / tool dirs\n 'node_modules', '.npm', '.yarn', '.pnpm-store',\n '.config', '.local', '.cache', '.ssh', '.memorix',\n ]);\n if (knownNonProjectDirs.has(basename)) {\n const parent = path.resolve(path.dirname(resolved));\n // Only block if it's directly under home or a drive root\n if (parent === home || parent === path.parse(parent).root) {\n return false;\n }\n }\n\n // Must have at least ONE project indicator file\n const projectIndicators = [\n 'package.json', 'Cargo.toml', 'go.mod', 'pyproject.toml',\n 'setup.py', 'pom.xml', 'build.gradle', 'Makefile',\n 'CMakeLists.txt', 'composer.json', 'Gemfile',\n '.git', 'README.md', 'README',\n ];\n return projectIndicators.some(f => existsSync(path.join(resolved, f)));\n}\n\n/**\n * Walk up from cwd to find the nearest directory containing package.json.\n * Useful for non-git projects where the MCP server CWD may differ from project root.\n */\nfunction findPackageRoot(cwd: string): string | null {\n let dir = path.resolve(cwd);\n const root = path.parse(dir).root;\n while (dir !== root) {\n if (existsSync(path.join(dir, 'package.json'))) {\n return dir;\n }\n dir = path.dirname(dir);\n }\n return null;\n}\n\n/**\n * Get the Git repository root directory.\n * Returns null if not inside a git repository.\n */\nfunction getGitRoot(cwd: string): string | null {\n try {\n const root = execSync('git rev-parse --show-toplevel', {\n cwd,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n return root || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get the Git remote URL for the given directory.\n * Returns null if not a git repository or no remote configured.\n */\nfunction getGitRemote(cwd: string): string | null {\n try {\n const remote = execSync('git remote get-url origin', {\n cwd,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n return remote || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Normalize a Git remote URL to a consistent project ID.\n *\n * Examples:\n * https://github.com/user/repo.git → user/repo\n * git@github.com:user/repo.git → user/repo\n * ssh://git@github.com/user/repo → user/repo\n */\nfunction normalizeGitRemote(remote: string): string {\n let normalized = remote;\n\n // Remove trailing .git\n normalized = normalized.replace(/\\.git$/, '');\n\n // Handle SSH format: git@github.com:user/repo\n const sshMatch = normalized.match(/^[\\w-]+@[\\w.-]+:(.+)$/);\n if (sshMatch) {\n return sshMatch[1];\n }\n\n // Handle HTTPS/SSH URL format\n try {\n const url = new URL(normalized);\n // Remove leading slash\n return url.pathname.replace(/^\\//, '');\n } catch {\n // If URL parsing fails, take last two segments\n const segments = normalized.split('/').filter(Boolean);\n return segments.slice(-2).join('/');\n }\n}\n","/**\n * Rules Utilities\n *\n * Shared helpers for rule parsing: content hashing, ID generation, etc.\n */\n\nimport { createHash } from 'node:crypto';\n\n/** Generate a deterministic content hash for deduplication */\nexport function hashContent(content: string): string {\n return createHash('sha256')\n .update(content.trim())\n .digest('hex')\n .substring(0, 16);\n}\n\n/** Generate a rule ID from source + file path */\nexport function generateRuleId(source: string, filePath: string): string {\n const sanitized = filePath.replace(/[\\/\\\\]/g, '-').replace(/^\\./, '');\n return `${source}:${sanitized}`;\n}\n","/**\n * Cursor Rule Format Adapter\n *\n * Parses and generates rules in Cursor's formats:\n * - .cursor/rules/*.mdc (Markdown + frontmatter with description, alwaysApply, globs)\n * - .cursorrules (legacy plain text)\n * - AGENTS.md (pure Markdown)\n *\n * Source: Cursor official documentation on Project Rules.\n */\n\nimport matter from 'gray-matter';\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\nimport { hashContent, generateRuleId } from '../utils.js';\n\nexport class CursorAdapter implements RuleFormatAdapter {\n readonly source: RuleSource = 'cursor';\n\n readonly filePatterns = [\n '.cursor/rules/*.mdc',\n '.cursorrules',\n 'AGENTS.md',\n ];\n\n parse(filePath: string, content: string): UnifiedRule[] {\n if (filePath.endsWith('.mdc')) {\n return this.parseMdc(filePath, content);\n }\n if (filePath === '.cursorrules' || filePath.endsWith('/.cursorrules')) {\n return this.parseLegacy(filePath, content);\n }\n if (filePath.endsWith('AGENTS.md')) {\n return this.parseAgentsMd(filePath, content);\n }\n return [];\n }\n\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\n return rules.map((rule, i) => {\n const fm: Record<string, unknown> = {};\n if (rule.description) fm.description = rule.description;\n if (rule.alwaysApply !== undefined) fm.alwaysApply = rule.alwaysApply;\n if (rule.paths && rule.paths.length > 0) fm.globs = rule.paths;\n\n const fileName = rule.id\n .replace(/^cursor:/, '')\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n || `rule-${i}`;\n\n const body = Object.keys(fm).length > 0\n ? matter.stringify(rule.content, fm)\n : rule.content;\n\n return {\n filePath: `.cursor/rules/${fileName}.mdc`,\n content: body,\n };\n });\n }\n\n private parseMdc(filePath: string, content: string): UnifiedRule[] {\n const { data, content: body } = matter(content);\n const trimmed = body.trim();\n if (!trimmed) return [];\n\n const globs = data.globs as string[] | undefined;\n const hasGlobs = Array.isArray(globs) && globs.length > 0;\n const alwaysApply = data.alwaysApply === true;\n\n let scope: UnifiedRule['scope'] = 'project';\n if (alwaysApply) scope = 'global';\n else if (hasGlobs) scope = 'path-specific';\n\n return [{\n id: generateRuleId('cursor', filePath),\n content: trimmed,\n description: data.description as string | undefined,\n source: 'cursor',\n scope,\n paths: hasGlobs ? globs : undefined,\n alwaysApply,\n priority: alwaysApply ? 10 : 5,\n hash: hashContent(trimmed),\n }];\n }\n\n private parseLegacy(filePath: string, content: string): UnifiedRule[] {\n const trimmed = content.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('cursor', filePath),\n content: trimmed,\n source: 'cursor',\n scope: 'project',\n priority: 3,\n hash: hashContent(trimmed),\n }];\n }\n\n private parseAgentsMd(filePath: string, content: string): UnifiedRule[] {\n const trimmed = content.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('cursor', filePath),\n content: trimmed,\n source: 'cursor',\n scope: 'project',\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n}\n","/**\n * Claude Code Rule Format Adapter\n *\n * Parses and generates rules in Claude Code's formats:\n * - CLAUDE.md / .claude/CLAUDE.md (project-level Markdown)\n * - .claude/rules/*.md (Markdown with optional `paths` frontmatter)\n *\n * Source: Claude Code official documentation.\n */\n\nimport matter from 'gray-matter';\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\nimport { hashContent, generateRuleId } from '../utils.js';\n\nexport class ClaudeCodeAdapter implements RuleFormatAdapter {\n readonly source: RuleSource = 'claude-code';\n\n readonly filePatterns = [\n 'CLAUDE.md',\n '.claude/CLAUDE.md',\n '.claude/rules/*.md',\n ];\n\n parse(filePath: string, content: string): UnifiedRule[] {\n // .claude/rules/*.md may have `paths` frontmatter\n if (filePath.includes('.claude/rules/')) {\n return this.parseModularRule(filePath, content);\n }\n // CLAUDE.md — project-level\n return this.parseClaudeMd(filePath, content);\n }\n\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\n const projectRules = rules.filter(r => r.scope !== 'path-specific');\n const pathRules = rules.filter(r => r.scope === 'path-specific');\n\n const files: { filePath: string; content: string }[] = [];\n\n if (projectRules.length > 0) {\n files.push({\n filePath: 'CLAUDE.md',\n content: projectRules.map(r => r.content).join('\\n\\n'),\n });\n }\n\n for (const rule of pathRules) {\n const fm: Record<string, unknown> = {};\n if (rule.paths && rule.paths.length > 0) fm.paths = rule.paths;\n\n const fileName = rule.id\n .replace(/^claude-code:/, '')\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n || 'rule';\n\n files.push({\n filePath: `.claude/rules/${fileName}.md`,\n content: Object.keys(fm).length > 0\n ? matter.stringify(rule.content, fm)\n : rule.content,\n });\n }\n\n return files;\n }\n\n private parseClaudeMd(filePath: string, content: string): UnifiedRule[] {\n const trimmed = content.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('claude-code', filePath),\n content: trimmed,\n source: 'claude-code',\n scope: 'project',\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n\n private parseModularRule(filePath: string, content: string): UnifiedRule[] {\n const { data, content: body } = matter(content);\n const trimmed = body.trim();\n if (!trimmed) return [];\n\n const paths = data.paths as string[] | undefined;\n const hasPaths = Array.isArray(paths) && paths.length > 0;\n\n return [{\n id: generateRuleId('claude-code', filePath),\n content: trimmed,\n description: data.description as string | undefined,\n source: 'claude-code',\n scope: hasPaths ? 'path-specific' : 'project',\n paths: hasPaths ? paths : undefined,\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n}\n","/**\n * OpenAI Codex Rule Format Adapter\n *\n * Parses and generates rules in Codex's formats:\n * - .agents/skills/[name]/SKILL.md (Markdown + frontmatter with name, description)\n * - AGENTS.md (pure Markdown)\n *\n * Source: OpenAI Codex Skills documentation.\n */\n\nimport matter from 'gray-matter';\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\nimport { hashContent, generateRuleId } from '../utils.js';\n\nexport class CodexAdapter implements RuleFormatAdapter {\n readonly source: RuleSource = 'codex';\n\n readonly filePatterns = [\n '.agents/skills/*/SKILL.md',\n 'AGENTS.md',\n ];\n\n parse(filePath: string, content: string): UnifiedRule[] {\n if (filePath.includes('SKILL.md')) {\n return this.parseSkillMd(filePath, content);\n }\n if (filePath.endsWith('AGENTS.md')) {\n return this.parseAgentsMd(filePath, content);\n }\n return [];\n }\n\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\n return rules.map((rule, i) => {\n const skillName = rule.id\n .replace(/^codex:/, '')\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n || `skill-${i}`;\n\n const fm: Record<string, unknown> = {\n name: skillName,\n };\n\n // Codex needs description to know WHEN to trigger the skill.\n // If no description exists, auto-generate from content (first 120 chars).\n if (rule.description) {\n fm.description = rule.description;\n } else {\n fm.description = this.autoDescription(rule.content);\n }\n\n return {\n filePath: `.agents/skills/${skillName}/SKILL.md`,\n content: matter.stringify(rule.content, fm),\n };\n });\n }\n\n /** Extract a short description from rule content for Codex skill triggering */\n private autoDescription(content: string): string {\n // Take first meaningful line, strip markdown formatting\n const lines = content.split('\\n').map(l => l.trim()).filter(Boolean);\n const first = lines[0]?.replace(/^#+\\s*/, '').replace(/^[-*]\\s*/, '') || 'Project rules';\n if (first.length <= 120) return first;\n return first.substring(0, 117) + '...';\n }\n\n private parseSkillMd(filePath: string, content: string): UnifiedRule[] {\n const { data, content: body } = matter(content);\n const trimmed = body.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('codex', filePath),\n content: trimmed,\n description: (data.description as string) || undefined,\n source: 'codex',\n scope: 'project',\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n\n private parseAgentsMd(filePath: string, content: string): UnifiedRule[] {\n const trimmed = content.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('codex', filePath),\n content: trimmed,\n source: 'codex',\n scope: 'project',\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n}\n","/**\n * Windsurf Rule Format Adapter\n *\n * Parses and generates rules in Windsurf's formats:\n * - .windsurfrules (legacy plain text)\n * - .windsurf/rules/*.md (Markdown with optional frontmatter)\n *\n * Source: Windsurf/Codeium documentation.\n */\n\nimport matter from 'gray-matter';\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\nimport { hashContent, generateRuleId } from '../utils.js';\n\nexport class WindsurfAdapter implements RuleFormatAdapter {\n readonly source: RuleSource = 'windsurf';\n\n readonly filePatterns = [\n '.windsurfrules',\n '.windsurf/rules/*.md',\n ];\n\n parse(filePath: string, content: string): UnifiedRule[] {\n if (filePath === '.windsurfrules' || filePath.endsWith('/.windsurfrules')) {\n return this.parseLegacy(filePath, content);\n }\n if (filePath.includes('.windsurf/rules/')) {\n return this.parseModularRule(filePath, content);\n }\n return [];\n }\n\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\n return rules.map((rule, i) => {\n const fm: Record<string, unknown> = {};\n if (rule.description) fm.description = rule.description;\n\n const fileName = rule.id\n .replace(/^windsurf:/, '')\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n || `rule-${i}`;\n\n const body = Object.keys(fm).length > 0\n ? matter.stringify(rule.content, fm)\n : rule.content;\n\n return {\n filePath: `.windsurf/rules/${fileName}.md`,\n content: body,\n };\n });\n }\n\n private parseLegacy(filePath: string, content: string): UnifiedRule[] {\n const trimmed = content.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('windsurf', filePath),\n content: trimmed,\n source: 'windsurf',\n scope: 'project',\n priority: 3,\n hash: hashContent(trimmed),\n }];\n }\n\n private parseModularRule(filePath: string, content: string): UnifiedRule[] {\n const { data, content: body } = matter(content);\n const trimmed = body.trim();\n if (!trimmed) return [];\n\n return [{\n id: generateRuleId('windsurf', filePath),\n content: trimmed,\n description: data.description as string | undefined,\n source: 'windsurf',\n scope: 'project',\n priority: 5,\n hash: hashContent(trimmed),\n }];\n }\n}\n","/**\r\n * Antigravity IDE Rule Format Adapter\r\n *\r\n * Parses and generates rules in Antigravity's formats:\r\n * - GEMINI.md (global rules, similar to CLAUDE.md)\r\n * - .agent/rules/*.md (workspace rules, Markdown with optional frontmatter)\r\n * - .agent/skills/[name]/SKILL.md (skills, Markdown + YAML frontmatter)\r\n *\r\n * Source: Antigravity official documentation (https://antigravity.google/docs/agent/rules)\r\n *\r\n * Note: Antigravity is Google's agent-first IDE, a VS Code fork.\r\n * Global rules: ~/.gemini/GEMINI.md\r\n * Workspace rules: <project>/.agent/rules/*.md\r\n * Skills: <project>/.agent/skills/[name]/SKILL.md\r\n * Workflows: <project>/.agent/workflows/*.md\r\n */\r\n\r\nimport matter from 'gray-matter';\r\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\r\nimport { hashContent, generateRuleId } from '../utils.js';\r\n\r\nexport class AntigravityAdapter implements RuleFormatAdapter {\r\n readonly source: RuleSource = 'antigravity';\r\n\r\n readonly filePatterns = [\r\n 'GEMINI.md',\r\n '.agent/rules/*.md',\r\n '.agent/skills/*/SKILL.md',\r\n ];\r\n\r\n parse(filePath: string, content: string): UnifiedRule[] {\r\n // .agent/skills/*/SKILL.md — skill files with frontmatter\r\n if (filePath.includes('SKILL.md')) {\r\n return this.parseSkillMd(filePath, content);\r\n }\r\n // .agent/rules/*.md — workspace rules\r\n if (filePath.includes('.agent/rules/')) {\r\n return this.parseAgentRule(filePath, content);\r\n }\r\n // GEMINI.md — global project-level rules\r\n if (filePath === 'GEMINI.md' || filePath.endsWith('/GEMINI.md')) {\r\n return this.parseGeminiMd(filePath, content);\r\n }\r\n return [];\r\n }\r\n\r\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\r\n const projectRules = rules.filter(r => r.scope !== 'path-specific');\r\n const pathRules = rules.filter(r => r.scope === 'path-specific');\r\n\r\n const files: { filePath: string; content: string }[] = [];\r\n\r\n // Generate workspace rules as .agent/rules/*.md\r\n for (const rule of [...projectRules, ...pathRules]) {\r\n const fm: Record<string, unknown> = {};\r\n if (rule.description) fm.description = rule.description;\r\n\r\n const fileName = rule.id\r\n .replace(/^antigravity:/, '')\r\n .replace(/[^a-zA-Z0-9-_]/g, '-')\r\n || 'rule';\r\n\r\n const body = Object.keys(fm).length > 0\r\n ? matter.stringify(rule.content, fm)\r\n : rule.content;\r\n\r\n files.push({\r\n filePath: `.agent/rules/${fileName}.md`,\r\n content: body,\r\n });\r\n }\r\n\r\n return files;\r\n }\r\n\r\n private parseGeminiMd(filePath: string, content: string): UnifiedRule[] {\r\n const trimmed = content.trim();\r\n if (!trimmed) return [];\r\n\r\n return [{\r\n id: generateRuleId('antigravity', filePath),\r\n content: trimmed,\r\n source: 'antigravity',\r\n scope: 'global',\r\n priority: 10,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n\r\n private parseAgentRule(filePath: string, content: string): UnifiedRule[] {\r\n const { data, content: body } = matter(content);\r\n const trimmed = body.trim();\r\n if (!trimmed) return [];\r\n\r\n return [{\r\n id: generateRuleId('antigravity', filePath),\r\n content: trimmed,\r\n description: data.description as string | undefined,\r\n source: 'antigravity',\r\n scope: 'project',\r\n priority: 5,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n\r\n private parseSkillMd(filePath: string, content: string): UnifiedRule[] {\r\n const { data, content: body } = matter(content);\r\n const trimmed = body.trim();\r\n if (!trimmed) return [];\r\n\r\n return [{\r\n id: generateRuleId('antigravity', filePath),\r\n content: trimmed,\r\n description: (data.description as string) || undefined,\r\n source: 'antigravity',\r\n scope: 'project',\r\n priority: 5,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n}\r\n","/**\r\n * GitHub Copilot Rule Format Adapter\r\n *\r\n * Parses and generates rules in Copilot's formats:\r\n * - .github/copilot-instructions.md (repository-wide instructions, plain Markdown)\r\n * - .github/instructions/*.instructions.md (path-specific, YAML frontmatter with `applyTo` glob)\r\n *\r\n * Source: https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot\r\n */\r\n\r\nimport matter from 'gray-matter';\r\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\r\nimport { hashContent, generateRuleId } from '../utils.js';\r\n\r\nexport class CopilotAdapter implements RuleFormatAdapter {\r\n readonly source: RuleSource = 'copilot';\r\n\r\n readonly filePatterns = [\r\n '.github/copilot-instructions.md',\r\n '.github/instructions/*.instructions.md',\r\n ];\r\n\r\n parse(filePath: string, content: string): UnifiedRule[] {\r\n // Path-specific instruction files (.github/instructions/*.instructions.md)\r\n if (filePath.includes('.instructions.md') && filePath.includes('.github/instructions')) {\r\n return this.parsePathSpecific(filePath, content);\r\n }\r\n // Repository-wide instructions (.github/copilot-instructions.md)\r\n if (filePath.includes('copilot-instructions.md')) {\r\n return this.parseRepoWide(filePath, content);\r\n }\r\n return [];\r\n }\r\n\r\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\r\n // If only one rule with no path-specific globs, output as copilot-instructions.md\r\n if (rules.length === 1 && (!rules[0].paths || rules[0].paths.length === 0)) {\r\n return [{\r\n filePath: '.github/copilot-instructions.md',\r\n content: rules[0].content,\r\n }];\r\n }\r\n\r\n // Multiple rules → output as path-specific instruction files\r\n return rules.map((rule, i) => {\r\n const fm: Record<string, unknown> = {};\r\n\r\n // Preserve applyTo if available\r\n if (rule.paths && rule.paths.length > 0) {\r\n fm.applyTo = rule.paths.join(',');\r\n }\r\n if (rule.description) {\r\n fm.description = rule.description;\r\n }\r\n\r\n const fileName = rule.id\r\n .replace(/^copilot:/, '')\r\n .replace(/[^a-zA-Z0-9-_]/g, '-')\r\n || `instruction-${i}`;\r\n\r\n const body = Object.keys(fm).length > 0\r\n ? matter.stringify(rule.content, fm)\r\n : rule.content;\r\n\r\n return {\r\n filePath: `.github/instructions/${fileName}.instructions.md`,\r\n content: body,\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Parse repository-wide .github/copilot-instructions.md\r\n * This is plain Markdown with no frontmatter.\r\n */\r\n private parseRepoWide(filePath: string, content: string): UnifiedRule[] {\r\n const trimmed = content.trim();\r\n if (!trimmed) return [];\r\n\r\n return [{\r\n id: generateRuleId('copilot', filePath),\r\n content: trimmed,\r\n description: 'Repository-wide Copilot instructions',\r\n source: 'copilot',\r\n scope: 'project',\r\n priority: 3,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n\r\n /**\r\n * Parse path-specific .github/instructions/*.instructions.md\r\n * These have YAML frontmatter with `applyTo` glob pattern(s).\r\n */\r\n private parsePathSpecific(filePath: string, content: string): UnifiedRule[] {\r\n const { data, content: body } = matter(content);\r\n const trimmed = body.trim();\r\n if (!trimmed) return [];\r\n\r\n const applyTo = data.applyTo as string | undefined;\r\n const hasApplyTo = !!applyTo;\r\n\r\n const rule: UnifiedRule = {\r\n id: generateRuleId('copilot', filePath),\r\n content: trimmed,\r\n source: 'copilot',\r\n scope: hasApplyTo ? 'path-specific' : 'project',\r\n priority: 5,\r\n hash: hashContent(trimmed),\r\n };\r\n\r\n // Extract applyTo glob pattern(s) → store in paths[]\r\n if (hasApplyTo) {\r\n rule.paths = applyTo!.split(',').map(p => p.trim());\r\n }\r\n\r\n // Extract description if present\r\n if (data.description) {\r\n rule.description = data.description as string;\r\n }\r\n\r\n return [rule];\r\n }\r\n}\r\n","/**\r\n * Kiro Rule Format Adapter\r\n *\r\n * Parses and generates rules in Kiro's formats:\r\n * - .kiro/steering/*.md (Markdown steering rules with optional frontmatter)\r\n * - AGENTS.md (always included, pure Markdown)\r\n *\r\n * Source: Kiro official documentation on Steering Rules.\r\n * https://kiro.dev/docs/steering/\r\n *\r\n * Kiro uses \".kiro/steering/\" for project-level rules\r\n * and \"~/.kiro/steering/\" for user-level (global) rules.\r\n *\r\n * Frontmatter inclusion modes:\r\n * - always (default): loaded into every interaction\r\n * - fileMatch + fileMatchPattern: conditional on file globs\r\n * - manual: on-demand via #name in chat\r\n * - auto + name + description: auto-included when relevant\r\n */\r\n\r\nimport matter from 'gray-matter';\r\nimport type { RuleFormatAdapter, UnifiedRule, RuleSource } from '../../types.js';\r\nimport { hashContent, generateRuleId } from '../utils.js';\r\n\r\n/** Kiro inclusion mode values */\r\ntype KiroInclusion = 'always' | 'fileMatch' | 'manual' | 'auto';\r\n\r\nexport class KiroAdapter implements RuleFormatAdapter {\r\n readonly source: RuleSource = 'kiro';\r\n\r\n readonly filePatterns = [\r\n '.kiro/steering/*.md',\r\n 'AGENTS.md',\r\n ];\r\n\r\n parse(filePath: string, content: string): UnifiedRule[] {\r\n if (filePath.includes('.kiro/steering/')) {\r\n return this.parseSteeringRule(filePath, content);\r\n }\r\n if (filePath.endsWith('AGENTS.md')) {\r\n return this.parseAgentsMd(filePath, content);\r\n }\r\n return [];\r\n }\r\n\r\n generate(rules: UnifiedRule[]): { filePath: string; content: string }[] {\r\n return rules.map((rule, i) => {\r\n const fm: Record<string, unknown> = {};\r\n if (rule.description) fm.description = rule.description;\r\n\r\n // Map unified scope → Kiro inclusion mode\r\n if (rule.paths && rule.paths.length > 0) {\r\n fm.inclusion = 'fileMatch';\r\n fm.fileMatchPattern = rule.paths.length === 1\r\n ? rule.paths[0]\r\n : rule.paths;\r\n } else if (rule.alwaysApply) {\r\n fm.inclusion = 'always';\r\n }\r\n\r\n const fileName = rule.id\r\n .replace(/^kiro:/, '')\r\n .replace(/[^a-zA-Z0-9-_]/g, '-')\r\n || `rule-${i}`;\r\n\r\n const body = Object.keys(fm).length > 0\r\n ? matter.stringify(rule.content, fm)\r\n : rule.content;\r\n\r\n return {\r\n filePath: `.kiro/steering/${fileName}.md`,\r\n content: body,\r\n };\r\n });\r\n }\r\n\r\n private parseSteeringRule(filePath: string, content: string): UnifiedRule[] {\r\n const { data, content: body } = matter(content);\r\n const trimmed = body.trim();\r\n if (!trimmed) return [];\r\n\r\n // Kiro uses \"inclusion\" field: always | fileMatch | manual | auto\r\n const inclusion = (data.inclusion as KiroInclusion | undefined) ?? 'always';\r\n const alwaysApply = inclusion === 'always' || inclusion === 'auto';\r\n\r\n // fileMatchPattern can be a string or string[]\r\n let paths: string[] | undefined;\r\n if (inclusion === 'fileMatch' && data.fileMatchPattern) {\r\n paths = Array.isArray(data.fileMatchPattern)\r\n ? data.fileMatchPattern\r\n : [data.fileMatchPattern];\r\n }\r\n\r\n let scope: UnifiedRule['scope'] = 'project';\r\n if (alwaysApply) scope = 'global';\r\n else if (paths && paths.length > 0) scope = 'path-specific';\r\n\r\n return [{\r\n id: generateRuleId('kiro', filePath),\r\n content: trimmed,\r\n description: data.description as string | undefined,\r\n source: 'kiro',\r\n scope,\r\n paths,\r\n alwaysApply,\r\n priority: alwaysApply ? 10 : 5,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n\r\n private parseAgentsMd(filePath: string, content: string): UnifiedRule[] {\r\n const trimmed = content.trim();\r\n if (!trimmed) return [];\r\n\r\n return [{\r\n id: generateRuleId('kiro', filePath),\r\n content: trimmed,\r\n source: 'kiro',\r\n scope: 'project',\r\n alwaysApply: true,\r\n priority: 10,\r\n hash: hashContent(trimmed),\r\n }];\r\n }\r\n}\r\n\r\n","/**\n * Rules Syncer\n *\n * Core sync engine for cross-agent rule synchronization.\n * Scans project for rule files from all supported agents,\n * deduplicates by content hash, detects conflicts, and\n * generates output in any target agent format.\n *\n * This is the ~15% original logic in Memorix — dedup and\n * conflict detection are not found in any existing tool.\n */\n\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { UnifiedRule, RuleSource, RuleFormatAdapter } from '../types.js';\nimport { CursorAdapter } from './adapters/cursor.js';\nimport { ClaudeCodeAdapter } from './adapters/claude-code.js';\nimport { CodexAdapter } from './adapters/codex.js';\nimport { WindsurfAdapter } from './adapters/windsurf.js';\nimport { AntigravityAdapter } from './adapters/antigravity.js';\nimport { CopilotAdapter } from './adapters/copilot.js';\nimport { KiroAdapter } from './adapters/kiro.js';\n\n/** A detected conflict between two rules */\nexport interface RuleConflict {\n ruleA: UnifiedRule;\n ruleB: UnifiedRule;\n reason: string;\n}\n\n/** Sync status report */\nexport interface SyncStatus {\n totalRules: number;\n uniqueRules: number;\n sources: RuleSource[];\n conflicts: RuleConflict[];\n}\n\n/** File scan patterns for each adapter */\ninterface ScanEntry {\n adapter: RuleFormatAdapter;\n paths: string[];\n}\n\nexport class RulesSyncer {\n private readonly projectRoot: string;\n private readonly adapters: Map<RuleSource, RuleFormatAdapter>;\n\n constructor(projectRoot: string) {\n this.projectRoot = projectRoot;\n this.adapters = new Map();\n\n const all: RuleFormatAdapter[] = [\n new CursorAdapter(),\n new ClaudeCodeAdapter(),\n new CodexAdapter(),\n new WindsurfAdapter(),\n new AntigravityAdapter(),\n new CopilotAdapter(),\n new KiroAdapter(),\n ];\n for (const a of all) {\n this.adapters.set(a.source, a);\n }\n }\n\n /** Scan the project root for all known rule files and parse them */\n async scanRules(): Promise<UnifiedRule[]> {\n const rules: UnifiedRule[] = [];\n\n const scanEntries = this.buildScanEntries();\n\n for (const entry of scanEntries) {\n for (const scanPath of entry.paths) {\n const found = await this.findFiles(scanPath);\n for (const filePath of found) {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const relativePath = path.relative(this.projectRoot, filePath).replace(/\\\\/g, '/');\n const parsed = entry.adapter.parse(relativePath, content);\n rules.push(...parsed);\n } catch {\n // Skip unreadable files\n }\n }\n }\n }\n\n return rules;\n }\n\n /** Remove duplicate rules by content hash, keeping highest priority */\n deduplicateRules(rules: UnifiedRule[]): UnifiedRule[] {\n const byHash = new Map<string, UnifiedRule>();\n\n for (const rule of rules) {\n const existing = byHash.get(rule.hash);\n if (!existing || rule.priority > existing.priority) {\n byHash.set(rule.hash, rule);\n }\n }\n\n return Array.from(byHash.values());\n }\n\n /** Detect conflicts: rules with overlapping paths but different content */\n detectConflicts(rules: UnifiedRule[]): RuleConflict[] {\n const conflicts: RuleConflict[] = [];\n\n for (let i = 0; i < rules.length; i++) {\n for (let j = i + 1; j < rules.length; j++) {\n const a = rules[i];\n const b = rules[j];\n\n // Only compare rules from different sources\n if (a.source === b.source) continue;\n // Only compare if both have overlapping paths\n if (a.scope === 'path-specific' && b.scope === 'path-specific') {\n if (this.pathsOverlap(a.paths || [], b.paths || [])) {\n conflicts.push({\n ruleA: a,\n ruleB: b,\n reason: `Overlapping paths: ${a.source} vs ${b.source}`,\n });\n }\n }\n }\n }\n\n return conflicts;\n }\n\n /** Generate rule files for a target agent format */\n generateForTarget(\n rules: UnifiedRule[],\n target: RuleSource,\n ): { filePath: string; content: string }[] {\n const adapter = this.adapters.get(target);\n if (!adapter) {\n throw new Error(`No adapter for target: ${target}`);\n }\n return adapter.generate(rules);\n }\n\n /** Get a full sync status report */\n async syncStatus(): Promise<SyncStatus> {\n const rules = await this.scanRules();\n const deduped = this.deduplicateRules(rules);\n const conflicts = this.detectConflicts(deduped);\n const sources = [...new Set(rules.map(r => r.source))];\n\n return {\n totalRules: rules.length,\n uniqueRules: deduped.length,\n sources,\n conflicts,\n };\n }\n\n /** Build scan entries mapping adapters to their file search paths */\n private buildScanEntries(): ScanEntry[] {\n const entries: ScanEntry[] = [];\n\n for (const adapter of this.adapters.values()) {\n const absolutePaths = adapter.filePatterns.map(p =>\n path.join(this.projectRoot, p),\n );\n entries.push({ adapter, paths: absolutePaths });\n }\n\n return entries;\n }\n\n /** Find files matching a glob-like path (simple implementation) */\n private async findFiles(pattern: string): Promise<string[]> {\n const dir = path.dirname(pattern);\n const fileGlob = path.basename(pattern);\n\n try {\n const stat = await fs.stat(dir);\n if (!stat.isDirectory()) {\n // It's a direct file path\n try {\n await fs.access(pattern);\n return [pattern];\n } catch {\n return [];\n }\n }\n } catch {\n // If dir doesn't exist, check if pattern itself is a file\n try {\n await fs.access(pattern);\n return [pattern];\n } catch {\n return [];\n }\n }\n\n // If it's a glob pattern (contains *), list dir and filter\n if (fileGlob.includes('*')) {\n try {\n const files = await fs.readdir(dir);\n const ext = fileGlob.replace('*', '');\n return files\n .filter(f => ext ? f.endsWith(ext) : true)\n .map(f => path.join(dir, f));\n } catch {\n return [];\n }\n }\n\n // Direct file\n try {\n await fs.access(path.join(dir, fileGlob));\n return [path.join(dir, fileGlob)];\n } catch {\n return [];\n }\n }\n\n /** Check if two sets of glob paths overlap (simplified: exact match) */\n private pathsOverlap(a: string[], b: string[]): boolean {\n for (const pa of a) {\n for (const pb of b) {\n if (pa === pb) return true;\n }\n }\n return false;\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * Windsurf MCP config adapter.\n * Format: JSON file at ~/.codeium/windsurf/mcp_config.json\n *\n * Supports two transport modes:\n * 1. stdio: { command, args, env? }\n * 2. HTTP: { serverUrl, headers? }\n *\n * Also handles: disabled, disabledTools, env: null\n */\nexport class WindsurfMCPAdapter implements MCPConfigAdapter {\n readonly source = 'windsurf' as const;\n\n parse(content: string): MCPServerEntry[] {\n try {\n const config = JSON.parse(content);\n const servers = config.mcpServers ?? config.mcp_servers ?? {};\n return Object.entries(servers).map(([name, entry]: [string, any]) => {\n const result: MCPServerEntry = {\n name,\n command: entry.command ?? '',\n args: entry.args ?? [],\n };\n\n // HTTP transport: Windsurf uses \"serverUrl\" (not \"url\")\n if (entry.serverUrl) {\n result.url = entry.serverUrl;\n } else if (entry.url) {\n result.url = entry.url;\n }\n\n // Headers (for HTTP transport)\n if (entry.headers && typeof entry.headers === 'object' && Object.keys(entry.headers).length > 0) {\n result.headers = entry.headers;\n }\n\n // Env (can be null in Windsurf)\n if (entry.env && typeof entry.env === 'object' && Object.keys(entry.env).length > 0) {\n result.env = entry.env;\n }\n\n // Disabled flag\n if (entry.disabled === true) {\n result.disabled = true;\n }\n\n return result;\n });\n } catch {\n return [];\n }\n }\n\n generate(servers: MCPServerEntry[]): string {\n const mcpServers: Record<string, any> = {};\n for (const s of servers) {\n const entry: Record<string, any> = {};\n\n if (s.url) {\n // HTTP transport — Windsurf uses \"serverUrl\"\n entry.serverUrl = s.url;\n if (s.headers && Object.keys(s.headers).length > 0) {\n entry.headers = s.headers;\n }\n } else {\n // stdio transport\n entry.command = s.command;\n entry.args = s.args;\n }\n\n if (s.env && Object.keys(s.env).length > 0) {\n entry.env = s.env;\n }\n\n if (s.disabled === true) {\n entry.disabled = true;\n }\n\n mcpServers[s.name] = entry;\n }\n return JSON.stringify({ mcpServers }, null, 2);\n }\n\n getConfigPath(_projectRoot?: string): string {\n return join(homedir(), '.codeium', 'windsurf', 'mcp_config.json');\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * Cursor MCP config adapter.\n * Format: JSON file at ~/.cursor/mcp.json or .cursor/mcp.json (project-level)\n * Structure: { mcpServers: { [name]: { command, args, env?, url? } } }\n */\nexport class CursorMCPAdapter implements MCPConfigAdapter {\n readonly source = 'cursor' as const;\n\n parse(content: string): MCPServerEntry[] {\n try {\n const config = JSON.parse(content);\n const servers = config.mcpServers ?? {};\n return Object.entries(servers).map(([name, entry]: [string, any]) => ({\n name,\n command: entry.command ?? '',\n args: entry.args ?? [],\n ...(entry.env && Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),\n ...(entry.url ? { url: entry.url } : {}),\n }));\n } catch {\n return [];\n }\n }\n\n generate(servers: MCPServerEntry[]): string {\n const mcpServers: Record<string, any> = {};\n for (const s of servers) {\n const entry: Record<string, any> = {};\n if (s.url) {\n entry.url = s.url;\n } else {\n entry.command = s.command;\n entry.args = s.args;\n }\n if (s.env && Object.keys(s.env).length > 0) {\n entry.env = s.env;\n }\n mcpServers[s.name] = entry;\n }\n return JSON.stringify({ mcpServers }, null, 2);\n }\n\n getConfigPath(projectRoot?: string): string {\n if (projectRoot) {\n return join(projectRoot, '.cursor', 'mcp.json');\n }\n return join(homedir(), '.cursor', 'mcp.json');\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * Codex MCP config adapter.\n * Format: TOML file at ~/.codex/config.toml or .codex/config.toml (project-level)\n *\n * Structure:\n * [mcp_servers.<name>]\n * command = \"npx\"\n * args = [\"-y\", \"memorix-mcp\"]\n * url = \"https://...\" # for HTTP servers\n *\n * [mcp_servers.<name>.env]\n * KEY = \"value\"\n *\n * We implement a lightweight TOML parser (no external deps) sufficient\n * for MCP server config blocks. This avoids adding a TOML dependency.\n */\nexport class CodexMCPAdapter implements MCPConfigAdapter {\n readonly source = 'codex' as const;\n\n parse(content: string): MCPServerEntry[] {\n if (!content.trim()) return [];\n\n const servers: MCPServerEntry[] = [];\n const lines = content.split('\\n');\n\n let currentServer: string | null = null;\n let isEnvBlock = false;\n const serverMap = new Map<\n string,\n { command: string; args: string[]; env: Record<string, string>; url?: string; enabled?: boolean }\n >();\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n\n // Skip comments and empty lines\n if (!line || line.startsWith('#')) continue;\n\n // Match [mcp_servers.<name>.env]\n const envMatch = line.match(/^\\[mcp_servers\\.([^.\\]]+)\\.env\\]$/);\n if (envMatch) {\n currentServer = envMatch[1];\n isEnvBlock = true;\n if (!serverMap.has(currentServer)) {\n serverMap.set(currentServer, { command: '', args: [], env: {} });\n }\n continue;\n }\n\n // Match [mcp_servers.<name>]\n const serverMatch = line.match(/^\\[mcp_servers\\.([^.\\]]+)\\]$/);\n if (serverMatch) {\n currentServer = serverMatch[1];\n isEnvBlock = false;\n if (!serverMap.has(currentServer)) {\n serverMap.set(currentServer, { command: '', args: [], env: {} });\n }\n continue;\n }\n\n // Any other section header resets context\n if (line.startsWith('[')) {\n currentServer = null;\n isEnvBlock = false;\n continue;\n }\n\n // Parse key = value within current server block\n if (currentServer) {\n const kvMatch = line.match(/^(\\w+)\\s*=\\s*(.+)$/);\n if (!kvMatch) continue;\n\n const key = kvMatch[1];\n const rawValue = kvMatch[2].trim();\n const entry = serverMap.get(currentServer)!;\n\n if (isEnvBlock) {\n entry.env[key] = this.parseTomlString(rawValue);\n } else if (key === 'command') {\n entry.command = this.parseTomlString(rawValue);\n } else if (key === 'args') {\n entry.args = this.parseTomlArray(rawValue);\n } else if (key === 'url') {\n entry.url = this.parseTomlString(rawValue);\n } else if (key === 'enabled') {\n entry.enabled = rawValue === 'true';\n }\n }\n }\n\n for (const [name, entry] of serverMap) {\n servers.push({\n name,\n command: entry.command,\n args: entry.args,\n ...(Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),\n ...(entry.url ? { url: entry.url } : {}),\n });\n }\n\n return servers;\n }\n\n generate(servers: MCPServerEntry[]): string {\n const blocks: string[] = [];\n\n for (const s of servers) {\n const lines: string[] = [];\n lines.push(`[mcp_servers.${s.name}]`);\n\n if (s.url) {\n lines.push(`url = ${this.toTomlString(s.url)}`);\n } else {\n lines.push(`command = ${this.toTomlString(s.command)}`);\n lines.push(`args = [${s.args.map((a) => this.toTomlString(a)).join(', ')}]`);\n }\n\n if (s.env && Object.keys(s.env).length > 0) {\n lines.push('');\n lines.push(`[mcp_servers.${s.name}.env]`);\n for (const [key, value] of Object.entries(s.env)) {\n lines.push(`${key} = ${this.toTomlString(value)}`);\n }\n }\n\n blocks.push(lines.join('\\n'));\n }\n\n return blocks.join('\\n\\n') + '\\n';\n }\n\n getConfigPath(projectRoot?: string): string {\n if (projectRoot) {\n return join(projectRoot, '.codex', 'config.toml');\n }\n return join(homedir(), '.codex', 'config.toml');\n }\n\n // ---- TOML helpers ----\n\n private parseTomlString(raw: string): string {\n const trimmed = raw.trim();\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n }\n\n private parseTomlArray(raw: string): string[] {\n const trimmed = raw.trim();\n if (!trimmed.startsWith('[') || !trimmed.endsWith(']')) return [];\n const inner = trimmed.slice(1, -1);\n const result: string[] = [];\n // Simple CSV parse respecting quotes\n let current = '';\n let inQuote = false;\n let quoteChar = '';\n for (const ch of inner) {\n if (inQuote) {\n if (ch === quoteChar) {\n inQuote = false;\n } else {\n current += ch;\n }\n } else if (ch === '\"' || ch === \"'\") {\n inQuote = true;\n quoteChar = ch;\n } else if (ch === ',') {\n const val = current.trim();\n if (val) result.push(val);\n current = '';\n } else {\n current += ch;\n }\n }\n const last = current.trim();\n if (last) result.push(last);\n return result;\n }\n\n private toTomlString(value: string): string {\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * Claude Code MCP config adapter.\n * Format: JSON file at ~/.claude.json or project-level .claude/settings.json\n * Structure: { mcpServers: { [name]: { command, args, env?, url? } } }\n */\nexport class ClaudeCodeMCPAdapter implements MCPConfigAdapter {\n readonly source = 'claude-code' as const;\n\n parse(content: string): MCPServerEntry[] {\n try {\n const config = JSON.parse(content);\n const servers = config.mcpServers ?? {};\n return Object.entries(servers).map(([name, entry]: [string, any]) => ({\n name,\n command: entry.command ?? '',\n args: entry.args ?? [],\n ...(entry.env && Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),\n ...(entry.url ? { url: entry.url } : {}),\n }));\n } catch {\n return [];\n }\n }\n\n generate(servers: MCPServerEntry[]): string {\n const mcpServers: Record<string, any> = {};\n for (const s of servers) {\n const entry: Record<string, any> = {};\n if (s.url) {\n entry.url = s.url;\n } else {\n entry.command = s.command;\n entry.args = s.args;\n }\n if (s.env && Object.keys(s.env).length > 0) {\n entry.env = s.env;\n }\n mcpServers[s.name] = entry;\n }\n return JSON.stringify({ mcpServers }, null, 2);\n }\n\n getConfigPath(projectRoot?: string): string {\n if (projectRoot) {\n return join(projectRoot, '.claude', 'settings.json');\n }\n return join(homedir(), '.claude.json');\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync, readFileSync } from 'node:fs';\n\n/**\n * VS Code Copilot MCP config adapter.\n *\n * Config location: %APPDATA%/Code/User/settings.json (global)\n * or .vscode/mcp.json (workspace-level)\n *\n * Format inside settings.json:\n * { \"mcp\": { \"servers\": { [name]: { command, args, env? } } } }\n *\n * IMPORTANT: settings.json contains many non-MCP settings.\n * generate() merges MCP servers into the existing file instead of overwriting.\n */\nexport class CopilotMCPAdapter implements MCPConfigAdapter {\n readonly source = 'copilot' as const;\n\n parse(content: string): MCPServerEntry[] {\n try {\n const config = JSON.parse(content);\n\n // settings.json format: { \"mcp\": { \"servers\": { ... } } }\n const servers = config?.mcp?.servers ?? {};\n\n return Object.entries(servers).map(([name, entry]: [string, any]) => {\n const result: MCPServerEntry = {\n name,\n command: entry.command ?? '',\n args: entry.args ?? [],\n };\n\n if (entry.url) {\n result.url = entry.url;\n }\n\n if (entry.env && typeof entry.env === 'object' && Object.keys(entry.env).length > 0) {\n result.env = entry.env;\n }\n\n return result;\n });\n } catch {\n return [];\n }\n }\n\n generate(servers: MCPServerEntry[]): string {\n const mcpServers: Record<string, any> = {};\n for (const s of servers) {\n const entry: Record<string, any> = {};\n if (s.url) {\n entry.url = s.url;\n } else {\n entry.command = s.command;\n entry.args = s.args;\n }\n if (s.env && Object.keys(s.env).length > 0) {\n entry.env = s.env;\n }\n mcpServers[s.name] = entry;\n }\n\n // Merge into existing settings.json if it exists\n const configPath = this.getConfigPath();\n let existing: Record<string, any> = {};\n if (existsSync(configPath)) {\n try {\n existing = JSON.parse(readFileSync(configPath, 'utf-8'));\n } catch {\n // If parse fails, start fresh\n }\n }\n\n // Merge MCP servers into existing mcp.servers (preserve other servers)\n const existingMcp = existing.mcp ?? {};\n const existingServers = existingMcp.servers ?? {};\n existing.mcp = {\n ...existingMcp,\n servers: { ...existingServers, ...mcpServers },\n };\n\n return JSON.stringify(existing, null, 4);\n }\n\n getConfigPath(_projectRoot?: string): string {\n // VS Code user settings path varies by OS\n const home = homedir();\n if (process.platform === 'win32') {\n return join(home, 'AppData', 'Roaming', 'Code', 'User', 'settings.json');\n } else if (process.platform === 'darwin') {\n return join(home, 'Library', 'Application Support', 'Code', 'User', 'settings.json');\n } else {\n return join(home, '.config', 'Code', 'User', 'settings.json');\n }\n }\n}\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\r\nimport { homedir } from 'node:os';\r\nimport { join } from 'node:path';\r\n\r\n/**\r\n * Antigravity IDE MCP Configuration Adapter.\r\n *\r\n * Antigravity uses two JSON config files for MCP servers:\r\n * 1. Global MCP: ~/.gemini/antigravity/mcp_config.json\r\n * Format: { \"mcpServers\": { \"name\": { command, args, env? } } }\r\n *\r\n * 2. Global settings: ~/.gemini/settings.json\r\n * Format: { \"mcpServers\": { \"name\": { command, args, env? } } }\r\n *\r\n * The mcp_config.json format is the primary config, same JSON structure\r\n * as Windsurf but at a different path. Also supports HTTP transport via url.\r\n *\r\n * Source: Antigravity official documentation (https://antigravity.google/docs/agent/mcp)\r\n * Verified on local machine: C:\\Users\\<USER>\\.gemini\\antigravity\\mcp_config.json\r\n */\r\nexport class AntigravityMCPAdapter implements MCPConfigAdapter {\r\n readonly source = 'antigravity' as const;\r\n\r\n parse(content: string): MCPServerEntry[] {\r\n try {\r\n const config = JSON.parse(content);\r\n const servers = config.mcpServers ?? config.mcp_servers ?? {};\r\n return Object.entries(servers).map(([name, entry]: [string, any]) => {\r\n const result: MCPServerEntry = {\r\n name,\r\n command: entry.command ?? '',\r\n args: entry.args ?? [],\r\n };\r\n\r\n // HTTP transport\r\n if (entry.serverUrl) {\r\n result.url = entry.serverUrl;\r\n } else if (entry.url) {\r\n result.url = entry.url;\r\n }\r\n\r\n // Headers (for HTTP transport)\r\n if (entry.headers && typeof entry.headers === 'object' && Object.keys(entry.headers).length > 0) {\r\n result.headers = entry.headers;\r\n }\r\n\r\n // Env\r\n if (entry.env && typeof entry.env === 'object' && Object.keys(entry.env).length > 0) {\r\n result.env = entry.env;\r\n }\r\n\r\n // Disabled flag\r\n if (entry.disabled === true) {\r\n result.disabled = true;\r\n }\r\n\r\n return result;\r\n });\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n generate(servers: MCPServerEntry[]): string {\r\n const mcpServers: Record<string, any> = {};\r\n for (const s of servers) {\r\n const entry: Record<string, any> = {};\r\n\r\n if (s.url) {\r\n // HTTP transport\r\n entry.url = s.url;\r\n if (s.headers && Object.keys(s.headers).length > 0) {\r\n entry.headers = s.headers;\r\n }\r\n } else {\r\n // stdio transport\r\n entry.command = s.command;\r\n entry.args = s.args;\r\n }\r\n\r\n if (s.env && Object.keys(s.env).length > 0) {\r\n entry.env = s.env;\r\n }\r\n\r\n if (s.disabled === true) {\r\n entry.disabled = true;\r\n }\r\n\r\n mcpServers[s.name] = entry;\r\n }\r\n return JSON.stringify({ mcpServers }, null, 2);\r\n }\r\n\r\n getConfigPath(_projectRoot?: string): string {\r\n // Antigravity primary MCP config location\r\n return join(homedir(), '.gemini', 'antigravity', 'mcp_config.json');\r\n }\r\n}\r\n","import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';\r\nimport { homedir } from 'node:os';\r\nimport { join } from 'node:path';\r\n\r\n/**\r\n * Kiro MCP config adapter.\r\n * Format: JSON file at .kiro/settings/mcp.json (project-level)\r\n * or ~/.kiro/settings/mcp.json (user-level)\r\n * Structure: { mcpServers: { [name]: { command, args, env?, disabled?, autoApprove?, timeout? } } }\r\n *\r\n * Source: Kiro official MCP documentation.\r\n */\r\nexport class KiroMCPAdapter implements MCPConfigAdapter {\r\n readonly source = 'kiro' as const;\r\n\r\n parse(content: string): MCPServerEntry[] {\r\n try {\r\n const config = JSON.parse(content);\r\n const servers = config.mcpServers ?? {};\r\n return Object.entries(servers).map(([name, entry]: [string, any]) => ({\r\n name,\r\n command: entry.command ?? '',\r\n args: entry.args ?? [],\r\n ...(entry.env && Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),\r\n ...(entry.url ? { url: entry.url } : {}),\r\n }));\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n generate(servers: MCPServerEntry[]): string {\r\n const mcpServers: Record<string, any> = {};\r\n for (const s of servers) {\r\n const entry: Record<string, any> = {};\r\n if (s.url) {\r\n entry.url = s.url;\r\n } else {\r\n entry.command = s.command;\r\n entry.args = s.args;\r\n }\r\n if (s.env && Object.keys(s.env).length > 0) {\r\n entry.env = s.env;\r\n }\r\n mcpServers[s.name] = entry;\r\n }\r\n return JSON.stringify({ mcpServers }, null, 2);\r\n }\r\n\r\n getConfigPath(projectRoot?: string): string {\r\n if (projectRoot) {\r\n return join(projectRoot, '.kiro', 'settings', 'mcp.json');\r\n }\r\n return join(homedir(), '.kiro', 'settings', 'mcp.json');\r\n }\r\n}\r\n","import matter from 'gray-matter';\nimport type { AgentTarget, WorkflowEntry } from '../types.js';\n\n/**\n * WorkflowSyncer — converts workflows between agent formats.\n *\n * Supported conversions:\n * Windsurf .windsurf/workflows/*.md → Codex SKILL.md\n * Windsurf .windsurf/workflows/*.md → Cursor .cursor/rules/*.mdc\n * Windsurf .windsurf/workflows/*.md → Claude Code CLAUDE.md section\n */\nexport class WorkflowSyncer {\n /**\n * Parse a Windsurf workflow markdown file into a WorkflowEntry.\n */\n parseWindsurfWorkflow(fileName: string, raw: string): WorkflowEntry {\n const name = fileName.replace(/\\.md$/i, '');\n let description = '';\n let content = raw;\n\n try {\n const parsed = matter(raw);\n description = parsed.data?.description ?? '';\n content = parsed.content.trim();\n } catch {\n // No frontmatter — use raw content\n }\n\n return {\n name,\n description,\n content,\n source: 'windsurf',\n filePath: `.windsurf/workflows/${fileName}`,\n };\n }\n\n /**\n * Convert a workflow to Codex SKILL.md format.\n */\n toCodexSkill(wf: WorkflowEntry): { filePath: string; content: string } {\n const safeName = this.sanitizeName(wf.name);\n const fm: Record<string, string> = { name: safeName };\n if (wf.description) {\n fm.description = wf.description;\n }\n const content = matter.stringify(wf.content, fm);\n return {\n filePath: `.agents/skills/${safeName}/SKILL.md`,\n content,\n };\n }\n\n /**\n * Convert a workflow to Cursor .mdc rule format.\n */\n toCursorRule(wf: WorkflowEntry): { filePath: string; content: string } {\n const safeName = this.sanitizeName(wf.name);\n const fm: Record<string, string> = {};\n if (wf.description) {\n fm.description = wf.description;\n }\n fm.globs = '';\n fm.alwaysApply = 'false';\n const content = matter.stringify(wf.content, fm);\n return {\n filePath: `.cursor/rules/${safeName}.mdc`,\n content,\n };\n }\n\n /**\n * Convert a workflow to a CLAUDE.md section string.\n */\n toClaudeSection(wf: WorkflowEntry): string {\n const lines: string[] = [];\n lines.push(`## Workflow: ${wf.name}`);\n if (wf.description) {\n lines.push('');\n lines.push(`> ${wf.description}`);\n }\n lines.push('');\n lines.push(wf.content);\n return lines.join('\\n');\n }\n\n /**\n * Convert all workflows to the target agent format.\n * Returns an array of { filePath, content } for each generated file.\n */\n convertAll(\n workflows: WorkflowEntry[],\n target: AgentTarget,\n ): { filePath: string; content: string }[] {\n if (target === 'windsurf') {\n // No conversion needed — already in Windsurf format\n return [];\n }\n\n if (target === 'codex') {\n return workflows.map((wf) => this.toCodexSkill(wf));\n }\n\n if (target === 'cursor') {\n return workflows.map((wf) => this.toCursorRule(wf));\n }\n\n if (target === 'claude-code') {\n // Merge all workflows into a single CLAUDE.md\n const sections = workflows.map((wf) => this.toClaudeSection(wf));\n return [\n {\n filePath: 'CLAUDE.md',\n content: sections.join('\\n\\n'),\n },\n ];\n }\n\n return [];\n }\n\n // ---- Helpers ----\n\n private sanitizeName(name: string): string {\n return name\n .replace(/[^a-zA-Z0-9_-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n || 'workflow';\n }\n}\n","/**\n * Sanitizer — mask sensitive values (tokens, keys, passwords) in output.\n *\n * Patterns detected:\n * - API keys / tokens (github_pat_*, ctx7sk-*, sk-*, ghp_*, ghu_*, etc.)\n * - Generic key=value where key contains \"token\", \"key\", \"secret\", \"password\"\n * - Bearer tokens\n */\n\nconst SENSITIVE_PATTERNS: { pattern: RegExp; replacement: string }[] = [\n // GitHub PAT (classic & fine-grained)\n { pattern: /ghp_[A-Za-z0-9_]{36,}/g, replacement: 'ghp_***' },\n { pattern: /github_pat_[A-Za-z0-9_]{60,}/g, replacement: 'github_pat_***' },\n { pattern: /ghu_[A-Za-z0-9_]{36,}/g, replacement: 'ghu_***' },\n { pattern: /ghs_[A-Za-z0-9_]{36,}/g, replacement: 'ghs_***' },\n // OpenAI / Anthropic style keys\n { pattern: /sk-[A-Za-z0-9_-]{20,}/g, replacement: 'sk-***' },\n // Context7 keys\n { pattern: /ctx7sk-[A-Za-z0-9-]{20,}/g, replacement: 'ctx7sk-***' },\n // Generic long hex/base64 tokens (32+ chars) in quoted values\n { pattern: /\"([A-Za-z0-9_-]{40,})\"/g, replacement: '\"***\"' },\n];\n\nconst SENSITIVE_KEY_PATTERN = /(?:token|key|secret|password|credential|auth)/i;\n\n/**\n * Mask sensitive values in a string.\n */\nexport function sanitize(input: string): string {\n let result = input;\n\n // Apply known token patterns\n for (const { pattern, replacement } of SENSITIVE_PATTERNS) {\n // Reset lastIndex for global regexes\n pattern.lastIndex = 0;\n result = result.replace(pattern, replacement);\n }\n\n return result;\n}\n\n/**\n * Mask sensitive values in MCPServerEntry env/headers objects.\n * Returns a new object with masked values.\n */\nexport function sanitizeRecord(\n record: Record<string, string> | undefined | null,\n): Record<string, string> | undefined {\n if (!record) return undefined;\n\n const masked: Record<string, string> = {};\n for (const [key, value] of Object.entries(record)) {\n if (SENSITIVE_KEY_PATTERN.test(key)) {\n masked[key] = '***';\n } else {\n masked[key] = value;\n }\n }\n return masked;\n}\n","/**\n * Workspace Sync Applier\n *\n * Writes generated workspace sync results to disk with safety features:\n * 1. Pre-flight validation (check writability)\n * 2. Backup existing files before overwrite\n * 3. Atomic write (write to temp, then rename)\n * 4. Rollback on failure\n *\n * Usage:\n * const applier = new WorkspaceSyncApplier();\n * const result = await applier.apply(syncResult);\n * if (!result.success) await applier.rollback(result.backups);\n */\n\nimport { existsSync, mkdirSync, copyFileSync, writeFileSync, unlinkSync, renameSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nexport interface ApplyResult {\n success: boolean;\n filesWritten: string[];\n backups: BackupEntry[];\n errors: string[];\n}\n\nexport interface BackupEntry {\n originalPath: string;\n backupPath: string;\n}\n\ninterface FileToWrite {\n filePath: string;\n content: string;\n}\n\n/**\n * Apply workspace sync results to disk with backup and rollback.\n */\nexport class WorkspaceSyncApplier {\n /**\n * Apply generated files to disk.\n *\n * Steps:\n * 1. Validate all target directories exist or can be created\n * 2. Backup existing files\n * 3. Write new files\n * 4. On any error → rollback all changes\n */\n async apply(files: FileToWrite[]): Promise<ApplyResult> {\n const result: ApplyResult = {\n success: false,\n filesWritten: [],\n backups: [],\n errors: [],\n };\n\n if (files.length === 0) {\n result.success = true;\n return result;\n }\n\n // Step 1: Pre-flight — ensure all directories exist\n for (const file of files) {\n try {\n const dir = dirname(file.filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n } catch (err) {\n result.errors.push(`Cannot create directory for ${file.filePath}: ${err}`);\n return result;\n }\n }\n\n // Step 2: Backup existing files\n for (const file of files) {\n if (existsSync(file.filePath)) {\n try {\n const backupPath = file.filePath + `.backup-${Date.now()}`;\n copyFileSync(file.filePath, backupPath);\n result.backups.push({\n originalPath: file.filePath,\n backupPath,\n });\n } catch (err) {\n result.errors.push(`Cannot backup ${file.filePath}: ${err}`);\n return result;\n }\n }\n }\n\n // Step 3: Write new files\n for (const file of files) {\n try {\n // Write to temp file first, then rename (pseudo-atomic)\n const tempPath = file.filePath + `.tmp-${Date.now()}`;\n writeFileSync(tempPath, file.content, 'utf-8');\n renameSync(tempPath, file.filePath);\n result.filesWritten.push(file.filePath);\n } catch (err) {\n result.errors.push(`Cannot write ${file.filePath}: ${err}`);\n // Rollback everything written so far\n this.rollback(result.backups);\n return result;\n }\n }\n\n result.success = true;\n return result;\n }\n\n /**\n * Rollback applied changes by restoring backups.\n */\n rollback(backups: BackupEntry[]): { restored: number; errors: string[] } {\n const errors: string[] = [];\n let restored = 0;\n\n for (const backup of backups) {\n try {\n copyFileSync(backup.backupPath, backup.originalPath);\n restored++;\n } catch (err) {\n errors.push(`Cannot restore ${backup.originalPath} from ${backup.backupPath}: ${err}`);\n }\n }\n\n return { restored, errors };\n }\n\n /**\n * Clean up backup files after successful apply.\n */\n cleanBackups(backups: BackupEntry[]): void {\n for (const backup of backups) {\n try {\n if (existsSync(backup.backupPath)) {\n unlinkSync(backup.backupPath);\n }\n } catch {\n // Best-effort cleanup\n }\n }\n }\n}\n","import { readFileSync, readdirSync, existsSync, cpSync, mkdirSync } from 'node:fs';\nimport { join, basename } from 'node:path';\nimport { homedir } from 'node:os';\nimport type {\n AgentTarget,\n MCPServerEntry,\n MCPConfigAdapter,\n WorkflowEntry,\n WorkspaceSyncResult,\n RuleSource,\n SkillEntry,\n SkillConflict,\n} from '../types.js';\nimport { WindsurfMCPAdapter } from './mcp-adapters/windsurf.js';\nimport { CursorMCPAdapter } from './mcp-adapters/cursor.js';\nimport { CodexMCPAdapter } from './mcp-adapters/codex.js';\nimport { ClaudeCodeMCPAdapter } from './mcp-adapters/claude-code.js';\nimport { CopilotMCPAdapter } from './mcp-adapters/copilot.js';\nimport { AntigravityMCPAdapter } from './mcp-adapters/antigravity.js';\nimport { KiroMCPAdapter } from './mcp-adapters/kiro.js';\nimport { WorkflowSyncer } from './workflow-sync.js';\nimport { RulesSyncer } from '../rules/syncer.js';\nimport { sanitize } from './sanitizer.js';\nimport { WorkspaceSyncApplier, type ApplyResult } from './applier.js';\n\n/** Scan result from workspace analysis */\nexport interface WorkspaceScanResult {\n mcpConfigs: Record<AgentTarget, MCPServerEntry[]>;\n workflows: WorkflowEntry[];\n rulesCount: number;\n skills: SkillEntry[];\n skillConflicts: SkillConflict[];\n}\n\n/**\n * WorkspaceSyncEngine — orchestrates cross-agent workspace migration.\n *\n * Capabilities:\n * 1. MCP config sync (JSON ↔ TOML across 4 agents)\n * 2. Workflow sync (Windsurf workflows → Codex skills / Cursor rules / CLAUDE.md)\n * 3. Rules sync (via existing RulesSyncer)\n */\nexport class WorkspaceSyncEngine {\n private adapters: Map<AgentTarget, MCPConfigAdapter>;\n private workflowSyncer: WorkflowSyncer;\n private rulesSyncer: RulesSyncer;\n\n constructor(private projectRoot: string) {\n this.adapters = new Map<AgentTarget, MCPConfigAdapter>([\n ['windsurf', new WindsurfMCPAdapter()],\n ['cursor', new CursorMCPAdapter()],\n ['codex', new CodexMCPAdapter()],\n ['claude-code', new ClaudeCodeMCPAdapter()],\n ['copilot', new CopilotMCPAdapter()],\n ['antigravity', new AntigravityMCPAdapter()],\n ['kiro', new KiroMCPAdapter()],\n ]);\n this.workflowSyncer = new WorkflowSyncer();\n this.rulesSyncer = new RulesSyncer(projectRoot);\n }\n\n /**\n * Scan the workspace for all agent configs, workflows, and rules.\n */\n async scan(): Promise<WorkspaceScanResult> {\n const mcpConfigs: Record<AgentTarget, MCPServerEntry[]> = {\n windsurf: [],\n cursor: [],\n codex: [],\n 'claude-code': [],\n copilot: [],\n antigravity: [],\n kiro: [],\n };\n\n // Scan MCP configs from each agent\n for (const [target, adapter] of this.adapters) {\n const configPath = adapter.getConfigPath(this.projectRoot);\n const globalPath = adapter.getConfigPath();\n\n // Try project-level first, then global\n for (const path of [configPath, globalPath]) {\n if (existsSync(path)) {\n try {\n const content = readFileSync(path, 'utf-8');\n const servers = adapter.parse(content);\n if (servers.length > 0) {\n mcpConfigs[target] = servers;\n break;\n }\n } catch {\n // Skip unreadable configs\n }\n }\n }\n }\n\n // Scan Windsurf workflows\n const workflows = this.scanWorkflows();\n\n // Scan rules\n let rulesCount = 0;\n try {\n const rules = await this.rulesSyncer.scanRules();\n rulesCount = rules.length;\n } catch {\n // Rules scan may fail if no rules exist\n }\n\n // Scan skills across all agents\n const { skills, conflicts: skillConflicts } = this.scanSkills();\n\n return { mcpConfigs, workflows, rulesCount, skills, skillConflicts };\n }\n\n /**\n * Migrate workspace configs to a target agent format.\n * @param items — optional list of specific item names (MCP servers / skills) to sync.\n * When provided, only matching items are included. Omit to sync all.\n */\n async migrate(target: AgentTarget, items?: string[]): Promise<WorkspaceSyncResult> {\n const scan = await this.scan();\n const result: WorkspaceSyncResult = {\n mcpServers: { scanned: [], generated: [] },\n workflows: { scanned: [], generated: [] },\n rules: { scanned: 0, generated: 0 },\n skills: { scanned: [], conflicts: [], copied: [], skipped: [] },\n };\n\n const itemFilter = items && items.length > 0\n ? new Set(items.map(i => i.toLowerCase()))\n : null;\n\n // 1. Merge all MCP servers from all sources (dedup by name)\n const allServers = new Map<string, MCPServerEntry>();\n for (const servers of Object.values(scan.mcpConfigs)) {\n for (const s of servers) {\n if (!allServers.has(s.name)) {\n if (!itemFilter || itemFilter.has(s.name.toLowerCase())) {\n allServers.set(s.name, s);\n }\n }\n }\n }\n result.mcpServers.scanned = Array.from(allServers.values());\n\n // Generate target MCP config (sanitize sensitive values in output)\n if (result.mcpServers.scanned.length > 0) {\n const adapter = this.adapters.get(target)!;\n const configContent = adapter.generate(result.mcpServers.scanned);\n const configPath = adapter.getConfigPath(this.projectRoot);\n result.mcpServers.generated.push({\n filePath: configPath,\n content: sanitize(configContent),\n });\n }\n\n // 2. Convert workflows to target format\n result.workflows.scanned = scan.workflows;\n if (scan.workflows.length > 0) {\n result.workflows.generated = this.workflowSyncer.convertAll(scan.workflows, target);\n }\n\n // 3. Rules sync\n try {\n const rules = await this.rulesSyncer.scanRules();\n result.rules.scanned = rules.length;\n if (rules.length > 0) {\n const deduped = this.rulesSyncer.deduplicateRules(rules);\n const ruleSource = this.agentToRuleSource(target);\n if (ruleSource) {\n const files = this.rulesSyncer.generateForTarget(deduped, ruleSource);\n result.rules.generated = files.length;\n }\n }\n } catch {\n // Rules may not exist\n }\n\n // 4. Skills sync (no format conversion, just copy folders)\n result.skills.scanned = itemFilter\n ? scan.skills.filter(sk => itemFilter.has(sk.name.toLowerCase()))\n : scan.skills;\n result.skills.conflicts = scan.skillConflicts;\n\n return result;\n }\n\n // ---- Private helpers ----\n\n /** Skills directories per agent */\n private static SKILLS_DIRS: Record<AgentTarget, string[]> = {\n codex: ['.codex/skills', '.agents/skills'],\n cursor: ['.cursor/skills', '.cursor/skills-cursor'],\n windsurf: ['.windsurf/skills'],\n 'claude-code': ['.claude/skills'],\n copilot: ['.github/skills', '.copilot/skills'],\n antigravity: ['.agent/skills', '.gemini/skills', '.gemini/antigravity/skills'],\n kiro: ['.kiro/skills'],\n };\n\n /** Get the target skills directory for an agent (null if agent has no skills support) */\n private getTargetSkillsDir(target: AgentTarget): string | null {\n const dirs = WorkspaceSyncEngine.SKILLS_DIRS[target];\n if (!dirs || dirs.length === 0) return null;\n return join(this.projectRoot, dirs[0]);\n }\n\n /**\n * Scan all agent skills directories and collect unique skills.\n */\n private scanSkills(): { skills: SkillEntry[]; conflicts: SkillConflict[] } {\n const skills: SkillEntry[] = [];\n const conflicts: SkillConflict[] = [];\n const seen = new Map<string, SkillEntry>();\n const home = homedir();\n\n for (const [agent, dirs] of Object.entries(WorkspaceSyncEngine.SKILLS_DIRS)) {\n for (const dir of dirs) {\n // Check project-level and global\n const paths = [\n join(this.projectRoot, dir),\n join(home, dir),\n ];\n\n for (const skillsRoot of paths) {\n if (!existsSync(skillsRoot)) continue;\n\n try {\n const entries = readdirSync(skillsRoot, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const skillMd = join(skillsRoot, entry.name, 'SKILL.md');\n if (!existsSync(skillMd)) continue;\n\n // Parse description from frontmatter\n let description = '';\n try {\n const content = readFileSync(skillMd, 'utf-8');\n const match = content.match(/^---[\\s\\S]*?description:\\s*[\"']?(.+?)[\"']?\\s*$/m);\n if (match) description = match[1];\n } catch { /* skip */ }\n\n const newEntry: SkillEntry = {\n name: entry.name,\n description,\n sourcePath: join(skillsRoot, entry.name),\n sourceAgent: agent as AgentTarget,\n };\n\n const existing = seen.get(entry.name);\n if (existing) {\n // Conflict: same name from different agent\n if (existing.sourceAgent !== agent) {\n conflicts.push({\n name: entry.name,\n kept: existing,\n skipped: newEntry,\n });\n }\n continue;\n }\n\n seen.set(entry.name, newEntry);\n skills.push(newEntry);\n }\n } catch { /* skip unreadable dirs */ }\n }\n }\n }\n\n return { skills, conflicts };\n }\n\n /**\n * Copy skills to a target agent's skills directory.\n * Returns list of copied skill names.\n */\n copySkills(skills: SkillEntry[], target: AgentTarget): { copied: string[]; skipped: string[] } {\n const targetDir = this.getTargetSkillsDir(target);\n const copied: string[] = [];\n const skipped: string[] = [];\n\n // Agent has no skills directory support (e.g. copilot)\n if (!targetDir) {\n return { copied, skipped };\n }\n\n for (const skill of skills) {\n // Don't copy a skill back to its own agent\n if (skill.sourceAgent === target) continue;\n\n const dest = join(targetDir, skill.name);\n if (existsSync(dest)) {\n skipped.push(`${skill.name} (already exists in ${target})`);\n continue;\n }\n\n try {\n mkdirSync(targetDir, { recursive: true });\n cpSync(skill.sourcePath, dest, { recursive: true });\n copied.push(skill.name);\n } catch { /* skip on error */ }\n }\n\n return { copied, skipped };\n }\n\n private scanWorkflows(): WorkflowEntry[] {\n const workflows: WorkflowEntry[] = [];\n const wfDir = join(this.projectRoot, '.windsurf', 'workflows');\n\n if (!existsSync(wfDir)) return workflows;\n\n try {\n const files = readdirSync(wfDir).filter((f) => f.endsWith('.md'));\n for (const file of files) {\n try {\n const content = readFileSync(join(wfDir, file), 'utf-8');\n workflows.push(this.workflowSyncer.parseWindsurfWorkflow(file, content));\n } catch {\n // Skip unreadable files\n }\n }\n } catch {\n // Directory read error\n }\n\n return workflows;\n }\n\n /**\n * Apply migration results to disk with backup and rollback.\n *\n * Safety features:\n * - Backs up every existing file before overwriting\n * - Atomic writes (temp → rename)\n * - Auto-rollback on any failure\n * - Returns backup paths for manual rollback if needed\n */\n async apply(target: AgentTarget, items?: string[]): Promise<ApplyResult & { migrationSummary: string }> {\n const syncResult = await this.migrate(target, items);\n const applier = new WorkspaceSyncApplier();\n\n // Collect all files to write\n const filesToWrite = [\n ...syncResult.mcpServers.generated,\n ...syncResult.workflows.generated,\n ];\n\n const applyResult = await applier.apply(filesToWrite);\n\n // Copy skills (no format conversion needed)\n let skillResult = { copied: [] as string[], skipped: [] as string[] };\n if (syncResult.skills.scanned.length > 0) {\n skillResult = this.copySkills(syncResult.skills.scanned, target);\n }\n\n // Build summary\n const lines: string[] = [];\n if (applyResult.success) {\n lines.push(`✅ Applied ${applyResult.filesWritten.length} file(s) for ${target}`);\n for (const f of applyResult.filesWritten) {\n lines.push(` → ${f}`);\n }\n if (skillResult.copied.length > 0) {\n lines.push(`\\n🧩 Copied ${skillResult.copied.length} skill(s):`);\n for (const sk of skillResult.copied) {\n lines.push(` → ${sk}`);\n }\n }\n if (skillResult.skipped.length > 0) {\n lines.push(`\\n⏭️ Skipped ${skillResult.skipped.length} skill(s):`);\n for (const sk of skillResult.skipped) {\n lines.push(` → ${sk}`);\n }\n }\n if (syncResult.skills.conflicts.length > 0) {\n lines.push(`\\n⚠️ Name conflicts (${syncResult.skills.conflicts.length}):`);\n for (const c of syncResult.skills.conflicts) {\n lines.push(` → \"${c.name}\": kept ${c.kept.sourceAgent}, skipped ${c.skipped.sourceAgent}`);\n }\n }\n if (applyResult.backups.length > 0) {\n lines.push(`\\n📦 Backups created (${applyResult.backups.length}):`);\n for (const b of applyResult.backups) {\n lines.push(` ${b.originalPath} → ${b.backupPath}`);\n }\n }\n // Clean up backups after successful apply\n applier.cleanBackups(applyResult.backups);\n } else {\n lines.push(`❌ Apply failed for ${target}`);\n for (const e of applyResult.errors) {\n lines.push(` Error: ${e}`);\n }\n if (applyResult.backups.length > 0) {\n lines.push(`\\n🔄 Rolled back ${applyResult.backups.length} file(s)`);\n }\n }\n\n return {\n ...applyResult,\n migrationSummary: lines.join('\\n'),\n };\n }\n\n // ---- Private helpers ----\n\n private agentToRuleSource(target: AgentTarget): RuleSource | null {\n const map: Record<AgentTarget, RuleSource> = {\n cursor: 'cursor',\n 'claude-code': 'claude-code',\n codex: 'codex',\n windsurf: 'windsurf',\n copilot: 'copilot',\n antigravity: 'antigravity',\n kiro: 'kiro',\n };\n return map[target] ?? null;\n }\n}\n","/**\n * Hook Installers\n *\n * Auto-detect installed agents and generate hook configurations.\n * Each agent has a different config format but the hook command is the same:\n * memorix hook\n *\n * The hook handler reads stdin JSON from the agent, normalizes it, and auto-stores.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { createRequire } from 'node:module';\nimport type { AgentName, AgentHookConfig } from '../types.js';\n\n/**\n * Resolve the hook command for the current platform.\n * On Windows, 'memorix' resolves to a .ps1 script that non-PowerShell\n * environments (like Windsurf hooks) can't execute.\n * Solution: use 'node /path/to/cli/index.js hook' instead.\n */\nfunction resolveHookCommand(): string {\n if (process.platform === 'win32') {\n // Try to find the CLI script path\n try {\n // 1. Check if running from source (development)\n const devPath = path.resolve(import.meta.dirname ?? __dirname, '../../cli/index.js');\n try {\n const fsStat = require('node:fs');\n if (fsStat.existsSync(devPath)) {\n return `node ${devPath.replace(/\\\\/g, '/')}`;\n }\n } catch { /* ignore */ }\n\n // 2. Find globally installed memorix\n const require_ = createRequire(import.meta.url);\n const pkgPath = require_.resolve('memorix/package.json');\n const cliPath = path.join(path.dirname(pkgPath), 'dist', 'cli', 'index.js');\n return `node ${cliPath.replace(/\\\\/g, '/')}`;\n } catch {\n // 3. Fallback: assume memorix is in PATH via cmd (not .ps1)\n return 'memorix';\n }\n }\n // On Unix, 'memorix' works directly\n return 'memorix';\n}\n\n/**\n * Generate Claude Code / VS Code Copilot hook config.\n * Both use the same format: .claude/settings.json or .github/hooks/*.json\n */\nfunction generateClaudeConfig(): Record<string, unknown> {\n const cmd = `${resolveHookCommand()} hook`;\n const hookEntry = {\n type: 'command',\n command: cmd,\n timeout: 10,\n };\n\n return {\n hooks: {\n SessionStart: [hookEntry],\n PostToolUse: [hookEntry],\n UserPromptSubmit: [hookEntry],\n PreCompact: [hookEntry],\n Stop: [hookEntry],\n },\n };\n}\n\n/**\n * Generate Windsurf Cascade hooks config.\n */\nfunction generateWindsurfConfig(): Record<string, unknown> {\n const cmd = `${resolveHookCommand()} hook`;\n const hookEntry = {\n command: cmd,\n show_output: false,\n };\n\n return {\n hooks: {\n post_write_code: [hookEntry],\n post_run_command: [hookEntry],\n post_mcp_tool_use: [hookEntry],\n pre_user_prompt: [hookEntry],\n post_cascade_response: [hookEntry],\n },\n };\n}\n\n/**\n * Generate Cursor hooks config.\n */\nfunction generateCursorConfig(): Record<string, unknown> {\n const cmd = `${resolveHookCommand()} hook`;\n return {\n hooks: {\n beforeSubmitPrompt: {\n command: cmd,\n },\n afterFileEdit: {\n command: cmd,\n },\n stop: {\n command: cmd,\n },\n },\n };\n}\n\n/**\n * Generate Kiro hooks config (Markdown + YAML format).\n */\nfunction generateKiroHookFile(): string {\n return `---\ntitle: Memorix Auto-Memory\ndescription: Automatically record development context for cross-agent memory sharing\nevent: file_saved\nfilePattern: \"**/*\"\n---\n\nRun the memorix hook command to analyze changes and store relevant memories:\n\n\\`\\`\\`bash\n${resolveHookCommand()} hook\n\\`\\`\\`\n`;\n}\n\n/**\n * Get the config file path for an agent (project-level).\n */\nfunction getProjectConfigPath(agent: AgentName, projectRoot: string): string {\n switch (agent) {\n case 'claude':\n case 'copilot':\n return path.join(projectRoot, '.github', 'hooks', 'memorix.json');\n case 'windsurf':\n return path.join(projectRoot, '.windsurf', 'hooks.json');\n case 'cursor':\n return path.join(projectRoot, '.cursor', 'hooks.json');\n case 'kiro':\n return path.join(projectRoot, '.kiro', 'hooks', 'memorix.hook.md');\n case 'codex':\n return path.join(projectRoot, '.codex', 'hooks.json');\n default:\n return path.join(projectRoot, '.memorix', 'hooks.json');\n }\n}\n\n/**\n * Get the global config file path for an agent.\n */\nfunction getGlobalConfigPath(agent: AgentName): string {\n const home = os.homedir();\n switch (agent) {\n case 'claude':\n case 'copilot':\n return path.join(home, '.claude', 'settings.json');\n case 'windsurf':\n return path.join(home, '.codeium', 'windsurf', 'hooks.json');\n case 'cursor':\n return path.join(home, '.cursor', 'hooks.json');\n default:\n return path.join(home, '.memorix', 'hooks.json');\n }\n}\n\n/**\n * Detect which agents are installed on the system.\n */\nexport async function detectInstalledAgents(): Promise<AgentName[]> {\n const agents: AgentName[] = [];\n const home = os.homedir();\n\n // Check for Claude Code\n const claudeDir = path.join(home, '.claude');\n try {\n await fs.access(claudeDir);\n agents.push('claude');\n } catch { /* not installed */ }\n\n // Check for Windsurf\n const windsurfDir = path.join(home, '.codeium', 'windsurf');\n try {\n await fs.access(windsurfDir);\n agents.push('windsurf');\n } catch { /* not installed */ }\n\n // Check for Cursor\n const cursorDir = path.join(home, '.cursor');\n try {\n await fs.access(cursorDir);\n agents.push('cursor');\n } catch { /* not installed */ }\n\n // Check for VS Code Copilot (if Claude Code is not detected)\n if (!agents.includes('claude')) {\n const vscodeDir = path.join(home, '.vscode');\n try {\n await fs.access(vscodeDir);\n agents.push('copilot');\n } catch { /* not installed */ }\n }\n\n // Check for Kiro\n const kiroConfig = path.join(home, '.kiro');\n try {\n await fs.access(kiroConfig);\n agents.push('kiro');\n } catch { /* not installed */ }\n\n // Check for Codex\n const codexDir = path.join(home, '.codex');\n try {\n await fs.access(codexDir);\n agents.push('codex');\n } catch { /* not installed */ }\n\n // Check for Antigravity (Google Gemini CLI)\n const antigravityDir = path.join(home, '.gemini', 'antigravity');\n try {\n await fs.access(antigravityDir);\n agents.push('antigravity');\n } catch { /* not installed */ }\n\n return agents;\n}\n\n/**\n * Install hooks for a specific agent.\n */\nexport async function installHooks(\n agent: AgentName,\n projectRoot: string,\n global = false,\n): Promise<AgentHookConfig> {\n const configPath = global\n ? getGlobalConfigPath(agent)\n : getProjectConfigPath(agent, projectRoot);\n\n let generated: Record<string, unknown> | string;\n\n switch (agent) {\n case 'claude':\n case 'copilot':\n generated = generateClaudeConfig();\n break;\n case 'windsurf':\n generated = generateWindsurfConfig();\n break;\n case 'cursor':\n generated = generateCursorConfig();\n break;\n case 'kiro':\n generated = generateKiroHookFile();\n break;\n default:\n generated = generateClaudeConfig(); // fallback\n }\n\n // Ensure directory exists\n await fs.mkdir(path.dirname(configPath), { recursive: true });\n\n if (agent === 'kiro') {\n // Kiro uses markdown files\n await fs.writeFile(configPath, generated as string, 'utf-8');\n } else {\n // JSON-based configs: merge with existing if present\n let existing: Record<string, unknown> = {};\n try {\n const content = await fs.readFile(configPath, 'utf-8');\n existing = JSON.parse(content);\n } catch { /* file doesn't exist yet */ }\n\n const merged = {\n ...existing,\n ...(generated as Record<string, unknown>),\n };\n\n await fs.writeFile(configPath, JSON.stringify(merged, null, 2), 'utf-8');\n }\n\n const events: Array<import('../types.js').HookEvent> = [];\n switch (agent) {\n case 'claude':\n case 'copilot':\n events.push('session_start', 'post_tool', 'user_prompt', 'pre_compact', 'session_end');\n break;\n case 'windsurf':\n events.push('post_edit', 'post_command', 'post_tool', 'user_prompt', 'post_response');\n break;\n case 'cursor':\n events.push('user_prompt', 'post_edit', 'session_end');\n break;\n case 'kiro':\n events.push('post_edit');\n break;\n }\n\n // Install agent rules alongside hooks\n await installAgentRules(agent, projectRoot);\n\n return {\n agent,\n configPath,\n events,\n generated: typeof generated === 'string' ? { content: generated } : generated,\n };\n}\n\n/**\n * Install memorix agent rules for a specific agent.\n * Rules instruct the agent to proactively use memorix for context continuity.\n */\nasync function installAgentRules(agent: AgentName, projectRoot: string): Promise<void> {\n const rulesContent = getAgentRulesContent();\n let rulesPath: string;\n\n switch (agent) {\n case 'windsurf':\n rulesPath = path.join(projectRoot, '.windsurf', 'rules', 'memorix.md');\n break;\n case 'cursor':\n rulesPath = path.join(projectRoot, '.cursor', 'rules', 'memorix.mdc');\n break;\n case 'claude':\n case 'copilot':\n rulesPath = path.join(projectRoot, '.github', 'copilot-instructions.md');\n break;\n case 'codex':\n rulesPath = path.join(projectRoot, 'AGENTS.md');\n break;\n case 'kiro':\n rulesPath = path.join(projectRoot, '.kiro', 'steering', 'memorix.md');\n break;\n default:\n // Antigravity and others\n rulesPath = path.join(projectRoot, '.agent', 'rules', 'memorix.md');\n break;\n }\n\n try {\n await fs.mkdir(path.dirname(rulesPath), { recursive: true });\n\n if (agent === 'codex') {\n // For Codex AGENTS.md, append rather than overwrite\n try {\n const existing = await fs.readFile(rulesPath, 'utf-8');\n if (existing.includes('Memorix')) {\n return; // Already contains memorix rules\n }\n // Append to existing AGENTS.md\n await fs.writeFile(rulesPath, existing + '\\n\\n' + rulesContent, 'utf-8');\n } catch {\n // File doesn't exist, create it\n await fs.writeFile(rulesPath, rulesContent, 'utf-8');\n }\n } else {\n // Only write if not already present\n try {\n await fs.access(rulesPath);\n // File exists — don't overwrite user customizations\n } catch {\n await fs.writeFile(rulesPath, rulesContent, 'utf-8');\n }\n }\n } catch { /* silent */ }\n}\n\n/**\n * Get the memorix agent rules content.\n */\nfunction getAgentRulesContent(): string {\n return `# Memorix — Automatic Memory Rules\n\nYou have access to Memorix memory tools. Follow these rules to maintain persistent context across sessions.\n\n## Session Start — Load Context\n\nAt the **beginning of every conversation**, before responding to the user:\n\n1. Call \\`memorix_search\\` with a query related to the user's first message or the current project\n2. If results are found, use \\`memorix_detail\\` to fetch the most relevant ones\n3. Reference relevant memories naturally in your response — the user should feel you \"remember\" them\n\nThis ensures you already know the project context without the user re-explaining.\n\n## During Session — Capture Important Context\n\n**Proactively** call \\`memorix_store\\` whenever any of the following happen:\n\n### Architecture & Decisions\n- Technology choice, framework selection, or design pattern adopted\n- Trade-off discussion with a clear conclusion\n- API design, database schema, or project structure decisions\n\n### Bug Fixes & Problem Solving\n- A bug is identified and resolved — store root cause + fix\n- Workaround applied for a known issue\n- Performance issue diagnosed and optimized\n\n### Gotchas & Pitfalls\n- Something unexpected or tricky is discovered\n- A common mistake is identified and corrected\n- Platform-specific behavior that caused issues\n\n### Configuration & Environment\n- Environment variables, port numbers, paths changed\n- Docker, nginx, Caddy, or reverse proxy config modified\n- Package dependencies added, removed, or version-pinned\n\n### Deployment & Operations\n- Server deployment steps (Docker, VPS, cloud)\n- DNS, SSL/TLS certificate, domain configuration\n- CI/CD pipeline setup or changes\n- Database migration or data transfer procedures\n- Server topology (ports, services, reverse proxy chain)\n- SSH keys, access credentials setup (store pattern, NOT secrets)\n\n### Project Milestones\n- Feature completed or shipped\n- Version released or published to npm/PyPI/etc.\n- Repository made public, README updated, PR submitted\n\nUse appropriate types: \\`decision\\`, \\`problem-solution\\`, \\`gotcha\\`, \\`what-changed\\`, \\`discovery\\`, \\`how-it-works\\`.\n\n## Session End — Store Summary\n\nWhen the conversation is ending or the user says goodbye:\n\n1. Call \\`memorix_store\\` with type \\`session-request\\` to record:\n - What was accomplished in this session\n - Current project state and any blockers\n - Pending tasks or next steps\n - Key files modified\n\nThis creates a \"handoff note\" for the next session (or for another AI agent).\n\n## Guidelines\n\n- **Don't store trivial information** (greetings, acknowledgments, simple file reads, ls/dir output)\n- **Do store anything you'd want to know if you lost all context**\n- **Do store anything a different AI agent would need to continue this work**\n- **Use concise titles** (~5-10 words) and structured facts\n- **Include file paths** in filesModified when relevant\n- **Include related concepts** for better searchability\n- **Prefer storing too much over too little** — the retention system will auto-decay stale memories\n`;\n}\n\n/**\n * Uninstall hooks for a specific agent.\n */\nexport async function uninstallHooks(\n agent: AgentName,\n projectRoot: string,\n global = false,\n): Promise<boolean> {\n const configPath = global\n ? getGlobalConfigPath(agent)\n : getProjectConfigPath(agent, projectRoot);\n\n try {\n if (agent === 'kiro') {\n await fs.unlink(configPath);\n } else {\n // For JSON configs, remove the hooks key\n const content = await fs.readFile(configPath, 'utf-8');\n const config = JSON.parse(content);\n delete config.hooks;\n\n if (Object.keys(config).length === 0) {\n await fs.unlink(configPath);\n } else {\n await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');\n }\n }\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check hook installation status for all agents.\n */\nexport async function getHookStatus(\n projectRoot: string,\n): Promise<Array<{ agent: AgentName; installed: boolean; configPath: string }>> {\n const results: Array<{ agent: AgentName; installed: boolean; configPath: string }> = [];\n const agents: AgentName[] = ['claude', 'copilot', 'windsurf', 'cursor', 'kiro', 'codex', 'antigravity'];\n\n for (const agent of agents) {\n const projectPath = getProjectConfigPath(agent, projectRoot);\n const globalPath = getGlobalConfigPath(agent);\n\n let installed = false;\n let usedPath = projectPath;\n\n try {\n await fs.access(projectPath);\n installed = true;\n } catch {\n try {\n await fs.access(globalPath);\n installed = true;\n usedPath = globalPath;\n } catch { /* not installed */ }\n }\n\n results.push({ agent, installed, configPath: usedPath });\n }\n\n return results;\n}\n","/**\n * Retention & Decay Engine\n *\n * Manages memory relevance over time using exponential decay.\n * Sources:\n * - mcp-memory-service: ExponentialDecayCalculator (importance × decay × access_boost)\n * - MemCP: Active → Archive → Purge lifecycle with immunity rules\n *\n * Relevance formula:\n * score = baseImportance × e^(-ageDays / retentionPeriod) × accessBoost × connectionBoost\n *\n * Immunity: observations with importance=critical, accessCount>=3, or tagged \"keep\"/\"pinned\"\n * are never auto-archived.\n */\n\nimport type { MemorixDocument } from '../types.js';\n\n// ── Importance → Retention Period mapping ────────────────────────────\n\nexport type ImportanceLevel = 'critical' | 'high' | 'medium' | 'low';\n\nconst RETENTION_DAYS: Record<ImportanceLevel, number> = {\n critical: 365,\n high: 180,\n medium: 90,\n low: 30,\n};\n\nconst BASE_IMPORTANCE: Record<ImportanceLevel, number> = {\n critical: 1.0,\n high: 0.8,\n medium: 0.5,\n low: 0.3,\n};\n\n// ── Observation Type → Default Importance ────────────────────────────\n\nconst TYPE_IMPORTANCE: Record<string, ImportanceLevel> = {\n gotcha: 'high',\n decision: 'high',\n 'trade-off': 'high',\n 'problem-solution': 'medium',\n 'how-it-works': 'medium',\n 'what-changed': 'medium',\n 'why-it-exists': 'medium',\n discovery: 'medium',\n 'session-request': 'low',\n};\n\n// ── Immunity ─────────────────────────────────────────────────────────\n\nconst PROTECTED_TAGS = new Set(['keep', 'important', 'pinned', 'critical']);\nconst MIN_ACCESS_FOR_IMMUNITY = 3;\n\n/**\n * Check if an observation is immune from archiving/decay.\n * Immune observations maintain a minimum relevance score.\n */\nexport function isImmune(doc: MemorixDocument): boolean {\n const importance = getImportanceLevel(doc);\n if (importance === 'critical' || importance === 'high') return true;\n if ((doc.accessCount ?? 0) >= MIN_ACCESS_FOR_IMMUNITY) return true;\n\n const concepts = doc.concepts?.split(', ').map((c) => c.toLowerCase()) ?? [];\n return concepts.some((c) => PROTECTED_TAGS.has(c));\n}\n\n// ── Relevance Scoring ────────────────────────────────────────────────\n\nexport interface RelevanceScore {\n observationId: number;\n totalScore: number;\n baseImportance: number;\n decayFactor: number;\n accessBoost: number;\n ageDays: number;\n isImmune: boolean;\n}\n\n/**\n * Get the importance level for an observation based on its type.\n */\nexport function getImportanceLevel(doc: MemorixDocument): ImportanceLevel {\n return TYPE_IMPORTANCE[doc.type] ?? 'medium';\n}\n\n/**\n * Calculate the relevance score for a single observation.\n *\n * Formula (from mcp-memory-service):\n * score = baseImportance × e^(-ageDays / retentionPeriod) × accessBoost\n *\n * Access boost (from mcp-memory-service):\n * 1 + 0.1 × accessCount (10% boost per access, capped at 2.0)\n */\nexport function calculateRelevance(\n doc: MemorixDocument,\n referenceTime?: Date,\n): RelevanceScore {\n const now = referenceTime ?? new Date();\n const importance = getImportanceLevel(doc);\n const base = BASE_IMPORTANCE[importance];\n const retention = RETENTION_DAYS[importance];\n\n // Age in days\n const createdAt = new Date(doc.createdAt);\n const ageDays = Math.max(0, (now.getTime() - createdAt.getTime()) / (1000 * 60 * 60 * 24));\n\n // Exponential decay\n const decayFactor = Math.exp(-ageDays / retention);\n\n // Access boost: 10% per access, capped at 2.0×\n const accessCount = doc.accessCount ?? 0;\n const accessBoost = Math.min(2.0, 1 + 0.1 * accessCount);\n\n let totalScore = base * decayFactor * accessBoost;\n\n // Immune observations get minimum 0.5 relevance\n const immune = isImmune(doc);\n if (immune) {\n totalScore = Math.max(totalScore, 0.5);\n }\n\n return {\n observationId: doc.observationId,\n totalScore,\n baseImportance: base,\n decayFactor,\n accessBoost,\n ageDays,\n isImmune: immune,\n };\n}\n\n/**\n * Score and rank observations by relevance.\n * Returns sorted (highest relevance first) with scores.\n */\nexport function rankByRelevance(\n docs: MemorixDocument[],\n referenceTime?: Date,\n): RelevanceScore[] {\n return docs\n .map((doc) => calculateRelevance(doc, referenceTime))\n .sort((a, b) => b.totalScore - a.totalScore);\n}\n\n// ── Retention Lifecycle ──────────────────────────────────────────────\n\nexport type RetentionZone = 'active' | 'stale' | 'archive-candidate';\n\n/**\n * Classify an observation into a retention zone.\n *\n * Lifecycle (from MemCP):\n * Active: recently accessed or high importance\n * Stale: not accessed, beyond 50% of retention period\n * Archive-candidate: not accessed, beyond 100% of retention period, not immune\n */\nexport function getRetentionZone(doc: MemorixDocument, referenceTime?: Date): RetentionZone {\n const now = referenceTime ?? new Date();\n const importance = getImportanceLevel(doc);\n const retention = RETENTION_DAYS[importance];\n\n const createdAt = new Date(doc.createdAt);\n const ageDays = (now.getTime() - createdAt.getTime()) / (1000 * 60 * 60 * 24);\n\n // Recently accessed = active regardless of age\n if (doc.lastAccessedAt) {\n const lastAccess = new Date(doc.lastAccessedAt);\n const daysSinceAccess = (now.getTime() - lastAccess.getTime()) / (1000 * 60 * 60 * 24);\n if (daysSinceAccess < 7) return 'active';\n }\n\n if (isImmune(doc)) return 'active';\n if (ageDays > retention) return 'archive-candidate';\n if (ageDays > retention * 0.5) return 'stale';\n return 'active';\n}\n\n/**\n * Get archive candidates from a list of observations.\n * Returns observations that are beyond their retention period and not immune.\n */\nexport function getArchiveCandidates(\n docs: MemorixDocument[],\n referenceTime?: Date,\n): MemorixDocument[] {\n return docs.filter((doc) => getRetentionZone(doc, referenceTime) === 'archive-candidate');\n}\n\n/**\n * Get retention summary statistics.\n */\nexport function getRetentionSummary(\n docs: MemorixDocument[],\n referenceTime?: Date,\n): { active: number; stale: number; archiveCandidates: number; immune: number } {\n let active = 0;\n let stale = 0;\n let archiveCandidates = 0;\n let immune = 0;\n\n for (const doc of docs) {\n const zone = getRetentionZone(doc, referenceTime);\n if (zone === 'active') active++;\n else if (zone === 'stale') stale++;\n else archiveCandidates++;\n if (isImmune(doc)) immune++;\n }\n\n return { active, stale, archiveCandidates, immune };\n}\n","/**\r\n * Skills Engine — Memory-Driven Project Skills\r\n *\r\n * Memorix's unique take on agent skills:\r\n * - Discovers existing SKILL.md files across all 7 agents\r\n * - Auto-generates project-specific skills from observation patterns\r\n * - Injects skill content directly into agent context (no file reading needed)\r\n *\r\n * Unlike generic skill marketplaces, these skills are derived from YOUR\r\n * project's actual history—decisions, gotchas, patterns, and solutions\r\n * that make this project unique.\r\n *\r\n * SKILL.md format (industry standard):\r\n * ---\r\n * description: Short description for tool use\r\n * ---\r\n * # Skill Title\r\n * Markdown instructions...\r\n */\r\n\r\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'node:fs';\r\nimport { join } from 'node:path';\r\nimport { homedir } from 'node:os';\r\nimport type { AgentTarget, SkillEntry } from '../types.js';\r\n\r\n// ============================================================\r\n// Types\r\n// ============================================================\r\n\r\n/** A skill with full content (for inject/generate) */\r\nexport interface SkillFull extends SkillEntry {\r\n content: string;\r\n /** Whether this was auto-generated from observations */\r\n generated: boolean;\r\n}\r\n\r\n/** Observation data for skill generation */\r\ninterface ObsData {\r\n id: number;\r\n entityName: string;\r\n type: string;\r\n title: string;\r\n narrative: string;\r\n facts?: string[];\r\n concepts?: string[];\r\n filesModified?: string[];\r\n createdAt?: string;\r\n}\r\n\r\n/** Entity cluster for skill generation */\r\ninterface EntityCluster {\r\n entity: string;\r\n observations: ObsData[];\r\n /** Types present in cluster */\r\n types: Set<string>;\r\n /** Score: higher = more skill-worthy */\r\n score: number;\r\n}\r\n\r\n// ============================================================\r\n// Skills Engine\r\n// ============================================================\r\n\r\n/** Skills directories per agent (same as workspace engine) */\r\nconst SKILLS_DIRS: Record<AgentTarget, string[]> = {\r\n codex: ['.codex/skills', '.agents/skills'],\r\n cursor: ['.cursor/skills', '.cursor/skills-cursor'],\r\n windsurf: ['.windsurf/skills'],\r\n 'claude-code': ['.claude/skills'],\r\n copilot: ['.github/skills', '.copilot/skills'],\r\n antigravity: ['.agent/skills', '.gemini/skills', '.gemini/antigravity/skills'],\r\n kiro: ['.kiro/skills'],\r\n};\r\n\r\n/** Types with high signal for skill generation */\r\nconst SKILL_WORTHY_TYPES = new Set([\r\n 'gotcha', 'decision', 'how-it-works', 'problem-solution', 'trade-off',\r\n]);\r\n\r\n/** Minimum observations needed per entity to generate a skill */\r\nconst MIN_OBS_FOR_SKILL = 3;\r\n\r\n/** Minimum score for skill generation */\r\nconst MIN_SCORE_FOR_SKILL = 5;\r\n\r\nexport class SkillsEngine {\r\n private skipGlobal: boolean;\r\n constructor(private projectRoot: string, options?: { skipGlobal?: boolean }) {\r\n this.skipGlobal = options?.skipGlobal ?? false;\r\n }\r\n\r\n // ============================================================\r\n // List: Discover all available skills\r\n // ============================================================\r\n\r\n /**\r\n * List all available skills from all agents + generated suggestions.\r\n */\r\n listSkills(): SkillFull[] {\r\n const skills: SkillFull[] = [];\r\n const seen = new Set<string>();\r\n const home = homedir();\r\n\r\n for (const [agent, dirs] of Object.entries(SKILLS_DIRS)) {\r\n for (const dir of dirs) {\r\n const paths = [join(this.projectRoot, dir)];\r\n if (!this.skipGlobal) {\r\n paths.push(join(home, dir));\r\n }\r\n\r\n for (const skillsRoot of paths) {\r\n if (!existsSync(skillsRoot)) continue;\r\n\r\n try {\r\n const entries = readdirSync(skillsRoot, { withFileTypes: true });\r\n for (const entry of entries) {\r\n if (!entry.isDirectory()) continue;\r\n const name = entry.name;\r\n if (seen.has(name)) continue;\r\n\r\n const skillMd = join(skillsRoot, name, 'SKILL.md');\r\n if (!existsSync(skillMd)) continue;\r\n\r\n try {\r\n const content = readFileSync(skillMd, 'utf-8');\r\n const description = this.parseDescription(content);\r\n\r\n skills.push({\r\n name,\r\n description,\r\n sourcePath: join(skillsRoot, name),\r\n sourceAgent: agent as AgentTarget,\r\n content,\r\n generated: false,\r\n });\r\n seen.add(name);\r\n } catch { /* skip unreadable */ }\r\n }\r\n } catch { /* skip unreadable dirs */ }\r\n }\r\n }\r\n }\r\n\r\n return skills;\r\n }\r\n\r\n // ============================================================\r\n // Generate: Create skills from observation patterns\r\n // ============================================================\r\n\r\n /**\r\n * Analyze observations and generate SKILL.md content for entities with\r\n * rich knowledge accumulation.\r\n */\r\n generateFromObservations(observations: ObsData[]): SkillFull[] {\r\n // 1. Cluster observations by entity\r\n const clusters = this.clusterByEntity(observations);\r\n\r\n // 2. Score each cluster for skill-worthiness\r\n for (const cluster of clusters.values()) {\r\n cluster.score = this.scoreCluster(cluster);\r\n }\r\n\r\n // 3. Generate skills for top clusters\r\n const results: SkillFull[] = [];\r\n const sortedClusters = [...clusters.values()]\r\n .filter(c => c.score >= MIN_SCORE_FOR_SKILL)\r\n .sort((a, b) => b.score - a.score)\r\n .slice(0, 10); // Max 10 auto-generated skills\r\n\r\n for (const cluster of sortedClusters) {\r\n const skill = this.clusterToSkill(cluster);\r\n if (skill) results.push(skill);\r\n }\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Write a generated skill to the target agent's skills directory.\r\n */\r\n writeSkill(skill: SkillFull, target: AgentTarget): string | null {\r\n const dirs = SKILLS_DIRS[target];\r\n if (!dirs || dirs.length === 0) return null;\r\n\r\n const targetDir = join(this.projectRoot, dirs[0], skill.name);\r\n\r\n try {\r\n mkdirSync(targetDir, { recursive: true });\r\n writeFileSync(join(targetDir, 'SKILL.md'), skill.content, 'utf-8');\r\n return join(dirs[0], skill.name, 'SKILL.md');\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n // ============================================================\r\n // Inject: Return skill content for direct agent consumption\r\n // ============================================================\r\n\r\n /**\r\n * Get full content of a skill by name (for direct injection).\r\n */\r\n injectSkill(name: string): SkillFull | null {\r\n const all = this.listSkills();\r\n return all.find(s => s.name.toLowerCase() === name.toLowerCase()) || null;\r\n }\r\n\r\n // ============================================================\r\n // Internal helpers\r\n // ============================================================\r\n\r\n private parseDescription(content: string): string {\r\n const match = content.match(/^---[\\s\\S]*?description:\\s*[\"']?(.+?)[\"']?\\s*$/m);\r\n return match ? match[1] : '';\r\n }\r\n\r\n private clusterByEntity(observations: ObsData[]): Map<string, EntityCluster> {\r\n const clusters = new Map<string, EntityCluster>();\r\n\r\n for (const obs of observations) {\r\n const entity = obs.entityName || 'unknown';\r\n let cluster = clusters.get(entity);\r\n if (!cluster) {\r\n cluster = { entity, observations: [], types: new Set(), score: 0 };\r\n clusters.set(entity, cluster);\r\n }\r\n cluster.observations.push(obs);\r\n cluster.types.add(obs.type);\r\n }\r\n\r\n return clusters;\r\n }\r\n\r\n private scoreCluster(cluster: EntityCluster): number {\r\n let score = 0;\r\n const obs = cluster.observations;\r\n\r\n // Base: need minimum observations\r\n if (obs.length < MIN_OBS_FOR_SKILL) return 0;\r\n\r\n // Must have at least one skill-worthy type (gotcha/decision/how-it-works/etc.)\r\n let hasSkillWorthyType = false;\r\n for (const type of cluster.types) {\r\n if (SKILL_WORTHY_TYPES.has(type)) {\r\n hasSkillWorthyType = true;\r\n break;\r\n }\r\n }\r\n if (!hasSkillWorthyType) return 0;\r\n\r\n // Volume bonus (1 point per obs, capped at 5)\r\n score += Math.min(obs.length, 5);\r\n\r\n // Type diversity bonus (3 points per unique skill-worthy type)\r\n for (const type of cluster.types) {\r\n if (SKILL_WORTHY_TYPES.has(type)) score += 3;\r\n }\r\n\r\n // Gotcha bonus (critical knowledge that MUST be preserved)\r\n const gotchas = obs.filter(o => o.type === 'gotcha').length;\r\n score += gotchas * 3;\r\n\r\n // Decision bonus (architecture choices that define patterns)\r\n const decisions = obs.filter(o => o.type === 'decision').length;\r\n score += decisions * 2;\r\n\r\n // Facts bonus (structured knowledge)\r\n const totalFacts = obs.reduce((sum, o) => sum + (o.facts?.length || 0), 0);\r\n score += Math.min(totalFacts, 5);\r\n\r\n // Files bonus (indicates real code involvement)\r\n const totalFiles = new Set(obs.flatMap(o => o.filesModified || [])).size;\r\n score += Math.min(totalFiles, 5);\r\n\r\n return score;\r\n }\r\n\r\n private clusterToSkill(cluster: EntityCluster): SkillFull | null {\r\n const { entity, observations } = cluster;\r\n const safeName = entity.replace(/[^a-zA-Z0-9_-]/g, '-').toLowerCase();\r\n\r\n // Group observations by type\r\n const gotchas = observations.filter(o => o.type === 'gotcha');\r\n const decisions = observations.filter(o => o.type === 'decision');\r\n const howItWorks = observations.filter(o => o.type === 'how-it-works');\r\n const problems = observations.filter(o => o.type === 'problem-solution');\r\n const tradeoffs = observations.filter(o => o.type === 'trade-off');\r\n const others = observations.filter(o =>\r\n !['gotcha', 'decision', 'how-it-works', 'problem-solution', 'trade-off'].includes(o.type),\r\n );\r\n\r\n // Collect all facts and concepts\r\n const allFacts = [...new Set(observations.flatMap(o => o.facts || []))];\r\n const allConcepts = [...new Set(observations.flatMap(o => o.concepts || []))];\r\n const allFiles = [...new Set(observations.flatMap(o => o.filesModified || []))];\r\n\r\n // Build SKILL.md content\r\n const lines: string[] = [];\r\n\r\n // Frontmatter\r\n const description = this.generateDescription(cluster);\r\n lines.push('---');\r\n lines.push(`description: ${description}`);\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // Title\r\n lines.push(`# ${entity}`);\r\n lines.push('');\r\n lines.push(`> Auto-generated from ${observations.length} project observations by Memorix.`);\r\n lines.push('> Adapt to your actual project context before relying on this skill.');\r\n lines.push('');\r\n\r\n // Key files\r\n if (allFiles.length > 0) {\r\n lines.push('## Key Files');\r\n lines.push('');\r\n for (const f of allFiles.slice(0, 15)) {\r\n lines.push(`- \\`${f}\\``);\r\n }\r\n lines.push('');\r\n }\r\n\r\n // Critical gotchas (most important — put first)\r\n if (gotchas.length > 0) {\r\n lines.push('## ⚠️ Critical Gotchas');\r\n lines.push('');\r\n for (const g of gotchas) {\r\n lines.push(`### ${g.title}`);\r\n if (g.narrative) lines.push('', g.narrative);\r\n if (g.facts && g.facts.length > 0) {\r\n lines.push('', ...g.facts.map(f => `- ${f}`));\r\n }\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Architecture decisions\r\n if (decisions.length > 0) {\r\n lines.push('## 🏗️ Architecture Decisions');\r\n lines.push('');\r\n for (const d of decisions) {\r\n lines.push(`### ${d.title}`);\r\n if (d.narrative) lines.push('', d.narrative);\r\n if (d.facts && d.facts.length > 0) {\r\n lines.push('', ...d.facts.map(f => `- ${f}`));\r\n }\r\n lines.push('');\r\n }\r\n }\r\n\r\n // How it works\r\n if (howItWorks.length > 0) {\r\n lines.push('## 📖 How It Works');\r\n lines.push('');\r\n for (const h of howItWorks) {\r\n lines.push(`### ${h.title}`);\r\n if (h.narrative) lines.push('', h.narrative);\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Common problems & solutions\r\n if (problems.length > 0) {\r\n lines.push('## 🔧 Common Problems & Solutions');\r\n lines.push('');\r\n for (const p of problems) {\r\n lines.push(`### ${p.title}`);\r\n if (p.narrative) lines.push('', p.narrative);\r\n if (p.facts && p.facts.length > 0) {\r\n lines.push('', ...p.facts.map(f => `- ${f}`));\r\n }\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Trade-offs\r\n if (tradeoffs.length > 0) {\r\n lines.push('## ⚖️ Trade-offs');\r\n lines.push('');\r\n for (const t of tradeoffs) {\r\n lines.push(`### ${t.title}`);\r\n if (t.narrative) lines.push('', t.narrative);\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Other notable observations\r\n if (others.length > 0) {\r\n lines.push('## 📝 Notes');\r\n lines.push('');\r\n for (const o of others.slice(0, 5)) {\r\n lines.push(`- **${o.title}**: ${o.narrative?.split('\\n')[0] || ''}`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n // Key concepts\r\n if (allConcepts.length > 0) {\r\n lines.push('## 🏷️ Related Concepts');\r\n lines.push('');\r\n lines.push(allConcepts.map(c => `\\`${c}\\``).join(', '));\r\n lines.push('');\r\n }\r\n\r\n // Quick facts summary\r\n if (allFacts.length > 0) {\r\n lines.push('## 📌 Quick Facts');\r\n lines.push('');\r\n for (const f of allFacts.slice(0, 15)) {\r\n lines.push(`- ${f}`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n const content = lines.join('\\n');\r\n\r\n return {\r\n name: safeName,\r\n description,\r\n sourcePath: '',\r\n sourceAgent: 'codex' as AgentTarget, // generated skills follow SKILL.md standard\r\n content,\r\n generated: true,\r\n };\r\n }\r\n\r\n private generateDescription(cluster: EntityCluster): string {\r\n const parts: string[] = [];\r\n const typeCounts: Record<string, number> = {};\r\n for (const obs of cluster.observations) {\r\n typeCounts[obs.type] = (typeCounts[obs.type] || 0) + 1;\r\n }\r\n\r\n if (typeCounts['gotcha']) parts.push(`${typeCounts['gotcha']} gotcha(s)`);\r\n if (typeCounts['decision']) parts.push(`${typeCounts['decision']} decision(s)`);\r\n if (typeCounts['how-it-works']) parts.push(`${typeCounts['how-it-works']} explanation(s)`);\r\n if (typeCounts['problem-solution']) parts.push(`${typeCounts['problem-solution']} fix(es)`);\r\n\r\n const summary = parts.length > 0 ? parts.join(', ') : `${cluster.observations.length} observations`;\r\n return `Project patterns for ${cluster.entity}: ${summary}`;\r\n }\r\n}\r\n","/**\r\n * Memorix Dashboard Server\r\n *\r\n * Lightweight HTTP server that serves:\r\n * - REST API endpoints for reading memorix data\r\n * - Static frontend files (SPA)\r\n *\r\n * Zero external dependencies — uses Node.js built-in http module.\r\n */\r\n\r\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\r\nimport { promises as fs } from 'node:fs';\r\nimport path from 'node:path';\r\nimport { exec } from 'node:child_process';\r\n\r\nimport { loadGraphJsonl, loadObservationsJson, saveObservationsJson, loadIdCounter, getBaseDataDir } from '../store/persistence.js';\r\n\r\n// MIME types for static file serving\r\nconst MIME_TYPES: Record<string, string> = {\r\n '.html': 'text/html; charset=utf-8',\r\n '.css': 'text/css; charset=utf-8',\r\n '.js': 'application/javascript; charset=utf-8',\r\n '.json': 'application/json; charset=utf-8',\r\n '.svg': 'image/svg+xml',\r\n '.png': 'image/png',\r\n '.ico': 'image/x-icon',\r\n};\r\n\r\n/**\r\n * Send a JSON response\r\n */\r\nfunction sendJson(res: ServerResponse, data: unknown, status = 200) {\r\n res.writeHead(status, {\r\n 'Content-Type': 'application/json; charset=utf-8',\r\n 'Access-Control-Allow-Origin': '*',\r\n });\r\n res.end(JSON.stringify(data));\r\n}\r\n\r\n/**\r\n * Send an error response\r\n */\r\nfunction sendError(res: ServerResponse, message: string, status = 500) {\r\n sendJson(res, { error: message }, status);\r\n}\r\n\r\n/**\r\n * Filter observations by projectId\r\n */\r\nfunction filterByProject<T extends { projectId?: string }>(items: T[], projectId: string): T[] {\r\n return items.filter(item => item.projectId === projectId);\r\n}\r\n\r\n/**\r\n * API route handlers\r\n */\r\nasync function handleApi(\r\n req: IncomingMessage,\r\n res: ServerResponse,\r\n dataDir: string,\r\n projectId: string,\r\n projectName: string,\r\n baseDir: string,\r\n) {\r\n const url = new URL(req.url || '/', `http://${req.headers.host}`);\r\n const apiPath = url.pathname.replace('/api', '');\r\n\r\n // Support ?project=xxx to switch view to another project\r\n const requestedProject = url.searchParams.get('project');\r\n let effectiveDataDir = dataDir;\r\n let effectiveProjectId = projectId;\r\n let effectiveProjectName = projectName;\r\n if (requestedProject && requestedProject !== projectId) {\r\n const sanitized = requestedProject.replace(/\\//g, '--').replace(/[<>:\"|?*\\\\]/g, '_');\r\n const candidateDir = path.join(baseDir, sanitized);\r\n try {\r\n await fs.access(candidateDir);\r\n effectiveDataDir = candidateDir;\r\n effectiveProjectId = requestedProject;\r\n effectiveProjectName = requestedProject.split('/').pop() || requestedProject;\r\n } catch {\r\n // requested project dir doesn't exist, fall through to default\r\n }\r\n }\r\n\r\n try {\r\n switch (apiPath) {\r\n case '/projects': {\r\n // List all project directories\r\n try {\r\n const entries = await fs.readdir(baseDir, { withFileTypes: true });\r\n const projects = entries\r\n .filter((e: { isDirectory: () => boolean; name: string }) =>\r\n e.isDirectory() && e.name.includes('--') && !e.name.startsWith('local--')) // Only git-based projects, skip local fallback dirs\r\n .map((e: { name: string }) => {\r\n const dirName = e.name;\r\n const id = dirName.replace(/--/g, '/');\r\n return {\r\n id,\r\n name: id.split('/').pop() || id,\r\n dirName,\r\n isCurrent: id === projectId,\r\n };\r\n });\r\n sendJson(res, projects);\r\n } catch {\r\n sendJson(res, []);\r\n }\r\n break;\r\n }\r\n\r\n case '/project': {\r\n sendJson(res, { id: effectiveProjectId, name: effectiveProjectName });\r\n break;\r\n }\r\n\r\n case '/graph': {\r\n const graph = await loadGraphJsonl(effectiveDataDir);\r\n sendJson(res, graph);\r\n break;\r\n }\r\n\r\n case '/observations': {\r\n const allObs = await loadObservationsJson(effectiveDataDir);\r\n const observations = filterByProject(allObs as Array<{ projectId?: string }>, effectiveProjectId);\r\n sendJson(res, observations);\r\n break;\r\n }\r\n\r\n case '/stats': {\r\n const graph = await loadGraphJsonl(effectiveDataDir);\r\n const allObs = await loadObservationsJson(effectiveDataDir);\r\n const observations = filterByProject(allObs as Array<{ projectId?: string; type?: string; id?: number; createdAt?: string; title?: string; entityName?: string }>, effectiveProjectId);\r\n const nextId = await loadIdCounter(effectiveDataDir);\r\n\r\n // Type counts\r\n const typeCounts: Record<string, number> = {};\r\n for (const obs of observations) {\r\n const t = obs.type || 'unknown';\r\n typeCounts[t] = (typeCounts[t] || 0) + 1;\r\n }\r\n\r\n // Recent observations (last 10)\r\n const sorted = [...observations]\r\n .sort((a, b) => (b.id || 0) - (a.id || 0))\r\n .slice(0, 10);\r\n\r\n // Embedding provider status\r\n let embeddingStatus = { enabled: false, provider: '', dimensions: 0 };\r\n try {\r\n const { getEmbeddingProvider } = await import('../embedding/provider.js');\r\n const embProvider = await getEmbeddingProvider();\r\n embeddingStatus = {\r\n enabled: embProvider !== null,\r\n provider: embProvider?.name || '',\r\n dimensions: embProvider?.dimensions || 0,\r\n };\r\n } catch { /* embedding module not available */ }\r\n\r\n sendJson(res, {\r\n entities: graph.entities.length,\r\n relations: graph.relations.length,\r\n observations: observations.length,\r\n nextId,\r\n typeCounts,\r\n recentObservations: sorted,\r\n embedding: embeddingStatus,\r\n });\r\n break;\r\n }\r\n\r\n case '/retention': {\r\n const allObs = await loadObservationsJson(effectiveDataDir) as Array<{\r\n id?: number;\r\n title?: string;\r\n type?: string;\r\n importance?: number;\r\n accessCount?: number;\r\n lastAccessedAt?: string;\r\n createdAt?: string;\r\n entityName?: string;\r\n projectId?: string;\r\n }>;\r\n const observations = filterByProject(allObs, effectiveProjectId);\r\n\r\n const now = Date.now();\r\n const scored = observations.map((obs) => {\r\n const age = now - new Date(obs.createdAt || now).getTime();\r\n const ageHours = age / (1000 * 60 * 60);\r\n const importance = obs.importance ?? 5;\r\n const accessCount = obs.accessCount ?? 0;\r\n\r\n // Exponential decay: score = importance * e^(-λt) + access_bonus\r\n const lambda = 0.01;\r\n const decayScore = importance * Math.exp(-lambda * ageHours);\r\n const accessBonus = Math.min(accessCount * 0.5, 3);\r\n const score = Math.min(decayScore + accessBonus, 10);\r\n\r\n // Immune if importance >= 8 or type is 'gotcha' or 'decision'\r\n const isImmune = importance >= 8 || obs.type === 'gotcha' || obs.type === 'decision';\r\n\r\n return {\r\n id: obs.id,\r\n title: obs.title,\r\n type: obs.type,\r\n entityName: obs.entityName,\r\n score: Math.round(score * 100) / 100,\r\n isImmune,\r\n ageHours: Math.round(ageHours * 10) / 10,\r\n accessCount,\r\n };\r\n });\r\n\r\n // Sort by score descending\r\n scored.sort((a, b) => b.score - a.score);\r\n\r\n const activeCount = scored.filter((s) => s.score >= 3).length;\r\n const staleCount = scored.filter((s) => s.score < 3 && s.score >= 1).length;\r\n const archiveCount = scored.filter((s) => s.score < 1).length;\r\n const immuneCount = scored.filter((s) => s.isImmune).length;\r\n\r\n sendJson(res, {\r\n summary: { active: activeCount, stale: staleCount, archive: archiveCount, immune: immuneCount },\r\n items: scored,\r\n });\r\n break;\r\n }\r\n\r\n default: {\r\n // Handle dynamic routes\r\n const deleteMatch = apiPath.match(/^\\/observations\\/(\\d+)$/);\r\n if (deleteMatch && req.method === 'DELETE') {\r\n const obsId = parseInt(deleteMatch[1], 10);\r\n const allObs = await loadObservationsJson(effectiveDataDir) as Array<{ id?: number;[k: string]: unknown }>;\r\n const idx = allObs.findIndex(o => o.id === obsId);\r\n if (idx === -1) {\r\n sendError(res, 'Observation not found', 404);\r\n } else {\r\n allObs.splice(idx, 1);\r\n await saveObservationsJson(effectiveDataDir, allObs);\r\n sendJson(res, { ok: true, deleted: obsId });\r\n }\r\n break;\r\n }\r\n\r\n if (apiPath === '/export') {\r\n const graph = await loadGraphJsonl(effectiveDataDir);\r\n const allObs = await loadObservationsJson(effectiveDataDir);\r\n const observations = filterByProject(allObs as Array<{ projectId?: string }>, effectiveProjectId);\r\n const nextId = await loadIdCounter(effectiveDataDir);\r\n const exportData = {\r\n project: { id: effectiveProjectId, name: effectiveProjectName },\r\n exportedAt: new Date().toISOString(),\r\n graph,\r\n observations,\r\n nextId,\r\n };\r\n res.writeHead(200, {\r\n 'Content-Type': 'application/json',\r\n 'Content-Disposition': `attachment; filename=\"memorix-${effectiveProjectId.replace(/\\//g, '-')}-export.json\"`,\r\n });\r\n res.end(JSON.stringify(exportData, null, 2));\r\n break;\r\n }\r\n\r\n sendError(res, 'Not found', 404);\r\n }\r\n }\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Unknown error';\r\n sendError(res, message);\r\n }\r\n}\r\n\r\n/**\r\n * Serve static files from the dashboard/static directory\r\n */\r\nasync function serveStatic(req: IncomingMessage, res: ServerResponse, staticDir: string) {\r\n let urlPath = new URL(req.url || '/', `http://${req.headers.host}`).pathname;\r\n\r\n // SPA: serve index.html for all non-file routes\r\n if (urlPath === '/' || !urlPath.includes('.')) {\r\n urlPath = '/index.html';\r\n }\r\n\r\n const filePath = path.join(staticDir, urlPath);\r\n\r\n // Security: prevent directory traversal\r\n if (!filePath.startsWith(staticDir)) {\r\n sendError(res, 'Forbidden', 403);\r\n return;\r\n }\r\n\r\n try {\r\n const data = await fs.readFile(filePath);\r\n const ext = path.extname(filePath);\r\n res.writeHead(200, {\r\n 'Content-Type': MIME_TYPES[ext] || 'application/octet-stream',\r\n 'Cache-Control': 'no-cache',\r\n });\r\n res.end(data);\r\n } catch {\r\n // Fallback to index.html for SPA routing\r\n try {\r\n const indexData = await fs.readFile(path.join(staticDir, 'index.html'));\r\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\r\n res.end(indexData);\r\n } catch {\r\n sendError(res, 'Not found', 404);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Start the dashboard server\r\n */\r\n\r\n/** Cross-platform open URL in default browser */\r\nfunction openBrowser(url: string) {\r\n const cmd =\r\n process.platform === 'win32' ? `start \"\" \"${url}\"` :\r\n process.platform === 'darwin' ? `open \"${url}\"` :\r\n `xdg-open \"${url}\"`;\r\n exec(cmd, () => { /* ignore errors */ });\r\n}\r\n\r\nexport async function startDashboard(\r\n dataDir: string,\r\n port: number,\r\n staticDir: string,\r\n projectId: string,\r\n projectName: string,\r\n autoOpen = true,\r\n): Promise<void> {\r\n const resolvedStaticDir = staticDir;\r\n // Derive baseDir from dataDir (parent directory of project-specific dir)\r\n const baseDir = getBaseDataDir();\r\n\r\n const server = createServer(async (req, res) => {\r\n const url = req.url || '/';\r\n\r\n if (url.startsWith('/api/')) {\r\n await handleApi(req, res, dataDir, projectId, projectName, baseDir);\r\n } else {\r\n await serveStatic(req, res, resolvedStaticDir);\r\n }\r\n });\r\n\r\n return new Promise((resolve, reject) => {\r\n server.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EADDRINUSE') {\r\n console.error(`Port ${port} is already in use. Try: memorix dashboard --port ${port + 1}`);\r\n reject(err);\r\n } else {\r\n reject(err);\r\n }\r\n });\r\n\r\n server.listen(port, () => {\r\n const url = `http://localhost:${port}`;\r\n console.error(`\\n Memorix Dashboard`);\r\n console.error(` ───────────────────────`);\r\n console.error(` Project: ${projectName} (${projectId})`);\r\n console.error(` Local: ${url}`);\r\n console.error(` Data dir: ${dataDir}`);\r\n console.error(`\\n Press Ctrl+C to stop\\n`);\r\n\r\n // Auto-open browser\r\n if (autoOpen) openBrowser(url);\r\n\r\n resolve();\r\n });\r\n });\r\n}\r\n","/**\n * Memorix MCP Server\n *\n * Registers all MCP tools and handles the server lifecycle.\n *\n * Tool sources:\n * - memorix_store / memorix_search / memorix_detail / memorix_timeline:\n * Memorix extensions using claude-mem's 3-layer Progressive Disclosure\n * - create_entities / create_relations / add_observations / delete_entities /\n * delete_observations / delete_relations / search_nodes / open_nodes / read_graph:\n * MCP Official Memory Server compatible interface (P1)\n *\n * Extensibility:\n * - New tools can be registered via server.registerTool()\n * - Rules sync tools will be added in P2\n * - New agent format adapters plug in without changing this file\n */\n\nimport { watch } from 'node:fs';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { KnowledgeGraphManager } from './memory/graph.js';\nimport { storeObservation, initObservations, reindexObservations } from './memory/observations.js';\nimport { resetDb } from './store/orama-store.js';\nimport { createAutoRelations } from './memory/auto-relations.js';\nimport { extractEntities } from './memory/entity-extractor.js';\nimport { compactSearch, compactTimeline, compactDetail } from './compact/engine.js';\nimport { detectProject } from './project/detector.js';\nimport { getProjectDataDir } from './store/persistence.js';\nimport type { ObservationType, RuleSource, AgentTarget, MCPServerEntry } from './types.js';\nimport { RulesSyncer } from './rules/syncer.js';\nimport { WorkspaceSyncEngine } from './workspace/engine.js';\n\n/** Valid observation types for input validation */\nconst OBSERVATION_TYPES: [string, ...string[]] = [\n 'session-request',\n 'gotcha',\n 'problem-solution',\n 'how-it-works',\n 'what-changed',\n 'discovery',\n 'why-it-exists',\n 'decision',\n 'trade-off',\n];\n\n/**\n * Create and configure the Memorix MCP Server.\n */\nexport async function createMemorixServer(cwd?: string): Promise<{\n server: McpServer;\n graphManager: KnowledgeGraphManager;\n projectId: string;\n}> {\n // Detect current project\n const project = detectProject(cwd);\n\n // Migrate legacy global data to project-specific directory (one-time, silent)\n try {\n const { migrateGlobalData } = await import('./store/persistence.js');\n const migrated = await migrateGlobalData(project.id);\n if (migrated) {\n console.error(`[memorix] Migrated legacy data to project directory: ${project.id}`);\n }\n } catch { /* migration is optional */ }\n\n const projectDir = await getProjectDataDir(project.id);\n\n // Initialize components\n const graphManager = new KnowledgeGraphManager(projectDir);\n await graphManager.init();\n await initObservations(projectDir);\n\n // Reindex existing observations into Orama\n const reindexed = await reindexObservations();\n if (reindexed > 0) {\n console.error(`[memorix] Reindexed ${reindexed} observations for project: ${project.id}`);\n }\n\n console.error(`[memorix] Project: ${project.id} (${project.name})`);\n console.error(`[memorix] Data dir: ${projectDir}`);\n\n // Auto-install hooks for newly detected agents (incremental, silent, non-blocking)\n try {\n const { getHookStatus, installHooks, detectInstalledAgents } = await import('./hooks/installers/index.js');\n const workDir = cwd ?? process.cwd();\n const statuses = await getHookStatus(workDir);\n const installedAgents = new Set(statuses.filter((s) => s.installed).map((s) => s.agent));\n const detectedAgents = await detectInstalledAgents();\n\n // Install hooks for each detected agent that isn't already installed\n for (const agent of detectedAgents) {\n if (installedAgents.has(agent)) continue; // already installed\n try {\n const config = await installHooks(agent, workDir);\n console.error(`[memorix] Auto-installed hooks for ${agent} → ${config.configPath}`);\n } catch { /* skip */ }\n }\n } catch { /* hooks install is optional */ }\n\n // Sync advisory: compute once per session, show on first memorix_search\n let syncAdvisoryShown = false;\n let syncAdvisory: string | null = null;\n try {\n const engine = new WorkspaceSyncEngine(project.rootPath);\n const scan = await engine.scan();\n const lines: string[] = [];\n\n // Count what's available from other agents\n const totalMCP = Object.values(scan.mcpConfigs).reduce((sum, arr) => sum + arr.length, 0);\n const totalSkills = scan.skills.length;\n const totalRules = scan.rulesCount;\n const totalWorkflows = scan.workflows.length;\n\n if (totalMCP > 0 || totalSkills > 0 || totalRules > 0 || totalWorkflows > 0) {\n lines.push('', '---', '🔄 **Cross-Agent Sync Available**');\n\n // Detail MCP servers per agent\n for (const [agent, servers] of Object.entries(scan.mcpConfigs)) {\n const list = servers as MCPServerEntry[];\n if (list.length > 0) {\n lines.push(`- **${agent}** MCP: ${list.map(s => s.name).join(', ')}`);\n }\n }\n\n // Detail skills per agent\n if (totalSkills > 0) {\n const byAgent = new Map<string, string[]>();\n for (const sk of scan.skills) {\n const arr = byAgent.get(sk.sourceAgent) || [];\n arr.push(sk.name);\n byAgent.set(sk.sourceAgent, arr);\n }\n for (const [agent, names] of byAgent) {\n lines.push(`- **${agent}** skills: ${names.join(', ')}`);\n }\n }\n if (scan.skillConflicts.length > 0) lines.push(` ⚠️ ${scan.skillConflicts.length} name conflict(s)`);\n if (totalRules > 0) lines.push(`- **${totalRules} rule(s)** found`);\n if (totalWorkflows > 0) lines.push(`- **${totalWorkflows} workflow(s)** found`);\n\n lines.push('');\n lines.push('⚠️ IMPORTANT INSTRUCTIONS FOR AI AGENT:');\n lines.push('1. Tell the user what configs/skills are available from other agents (list them).');\n lines.push('2. Ask which ones they want to sync.');\n lines.push('3. DO NOT manually copy files or run shell commands to sync.');\n lines.push('4. ONLY use `memorix_workspace_sync action=\"apply\" target=\"<agent>\"` to sync all,');\n lines.push(' or add `items=[\"name1\",\"name2\"]` to sync specific items selectively.');\n syncAdvisory = lines.join('\\n');\n }\n console.error(`[memorix] Sync advisory: ${syncAdvisory ? 'available' : 'nothing to sync'}`);\n } catch {\n // Sync scan is optional, don't block startup\n }\n\n // Watch for external writes (e.g., from hook processes) and hot-reload\n const observationsFile = projectDir + '/observations.json';\n let reloadDebounce: ReturnType<typeof setTimeout> | null = null;\n try {\n watch(observationsFile, () => {\n // Debounce: wait 500ms after last change before reloading\n if (reloadDebounce) clearTimeout(reloadDebounce);\n reloadDebounce = setTimeout(async () => {\n try {\n await resetDb(); // Clear Orama before re-inserting\n await initObservations(projectDir);\n const count = await reindexObservations();\n if (count > 0) {\n console.error(`[memorix] Hot-reloaded ${count} observations (external write detected)`);\n }\n } catch {\n // Silent — don't crash the server\n }\n }, 500);\n });\n console.error(`[memorix] Watching for external writes (hooks hot-reload enabled)`);\n } catch {\n console.error(`[memorix] Warning: could not watch observations file for hot-reload`);\n }\n\n // Create MCP server\n const server = new McpServer({\n name: 'memorix',\n version: '0.1.0',\n });\n\n // ================================================================\n // Memorix Extended Tools (3-layer Progressive Disclosure)\n // ================================================================\n\n /**\n * memorix_store — Store a new observation\n *\n * Primary write API. Agents call this to persist knowledge.\n * Auto-assigns ID, counts tokens, indexes for search.\n */\n server.registerTool(\n 'memorix_store',\n {\n title: 'Store Memory',\n description:\n 'Store a new observation/memory. Automatically indexed for search. ' +\n 'Use type to classify: gotcha (🔴 critical pitfall), decision (🟤 architecture choice), ' +\n 'problem-solution (🟡 bug fix), how-it-works (🔵 explanation), what-changed (🟢 change), ' +\n 'discovery (🟣 insight), why-it-exists (🟠 rationale), trade-off (⚖️ compromise), ' +\n 'session-request (🎯 original goal).',\n inputSchema: {\n entityName: z.string().describe('The entity this observation belongs to (e.g., \"auth-module\", \"port-config\")'),\n type: z.enum(OBSERVATION_TYPES).describe('Observation type for classification'),\n title: z.string().describe('Short descriptive title (~5-10 words)'),\n narrative: z.string().describe('Full description of the observation'),\n facts: z.array(z.string()).optional().describe('Structured facts (e.g., \"Default timeout: 60s\")'),\n filesModified: z.array(z.string()).optional().describe('Files involved'),\n concepts: z.array(z.string()).optional().describe('Related concepts/keywords'),\n },\n },\n async ({ entityName, type, title, narrative, facts, filesModified, concepts }) => {\n // Ensure entity exists in knowledge graph\n await graphManager.createEntities([\n { name: entityName, entityType: 'auto', observations: [] },\n ]);\n\n // Store the observation\n const obs = await storeObservation({\n entityName,\n type: type as ObservationType,\n title,\n narrative,\n facts,\n filesModified,\n concepts,\n projectId: project.id,\n });\n\n // Add a reference to the entity's observations\n await graphManager.addObservations([\n { entityName, contents: [`[#${obs.id}] ${title}`] },\n ]);\n\n // Implicit memory: auto-create relations from entity extraction\n const extracted = extractEntities([title, narrative, ...(facts ?? [])].join(' '));\n const autoRelCount = await createAutoRelations(obs, extracted, graphManager);\n\n // Build enrichment summary\n const enrichmentParts: string[] = [];\n const autoFiles = obs.filesModified.filter((f) => !(filesModified ?? []).includes(f));\n const autoConcepts = obs.concepts.filter((c) => !(concepts ?? []).includes(c));\n if (autoFiles.length > 0) enrichmentParts.push(`+${autoFiles.length} files extracted`);\n if (autoConcepts.length > 0) enrichmentParts.push(`+${autoConcepts.length} concepts enriched`);\n if (autoRelCount > 0) enrichmentParts.push(`+${autoRelCount} relations auto-created`);\n if (obs.hasCausalLanguage) enrichmentParts.push('causal language detected');\n const enrichment = enrichmentParts.length > 0 ? `\\nAuto-enriched: ${enrichmentParts.join(', ')}` : '';\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `✅ Stored observation #${obs.id} \"${title}\" (~${obs.tokens} tokens)\\nEntity: ${entityName} | Type: ${type} | Project: ${project.id}${enrichment}`,\n },\n ],\n };\n },\n );\n\n /**\n * memorix_search — Layer 1: Compact index search\n *\n * Returns a lightweight table of matching observations.\n * ~50-100 tokens per result. Agent scans this to decide what to fetch.\n */\n server.registerTool(\n 'memorix_search',\n {\n title: 'Search Memory',\n description:\n 'Search project memory. Returns a compact index (~50-100 tokens/result). ' +\n 'Use memorix_detail to fetch full content for specific IDs. ' +\n 'Use memorix_timeline to see chronological context.',\n inputSchema: {\n query: z.string().describe('Search query (natural language or keywords)'),\n limit: z.number().optional().describe('Max results (default: 20)'),\n type: z.enum(OBSERVATION_TYPES).optional().describe('Filter by observation type'),\n maxTokens: z.number().optional().describe('Token budget — trim results to fit (0 = unlimited)'),\n scope: z.enum(['project', 'global']).optional().describe(\n 'Search scope: \"project\" (default) only searches current project, \"global\" searches all projects',\n ),\n },\n },\n async ({ query, limit, type, maxTokens, scope }) => {\n const result = await compactSearch({\n query,\n limit,\n type: type as ObservationType | undefined,\n maxTokens,\n // Default to current project scope; 'global' removes the project filter\n projectId: scope === 'global' ? undefined : project.id,\n });\n\n // Append sync advisory on first search of the session\n let text = result.formatted;\n if (!syncAdvisoryShown && syncAdvisory) {\n text += syncAdvisory;\n syncAdvisoryShown = true;\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text,\n },\n ],\n };\n },\n );\n\n /**\n * memorix_timeline — Layer 2: Chronological context\n *\n * Shows observations before and after a specific anchor.\n * Helps agents understand the temporal context of an observation.\n */\n server.registerTool(\n 'memorix_timeline',\n {\n title: 'Memory Timeline',\n description:\n 'Get chronological context around a specific observation. ' +\n 'Shows what happened before and after the anchor observation.',\n inputSchema: {\n anchorId: z.number().describe('Observation ID to center the timeline on'),\n depthBefore: z.number().optional().describe('Number of observations before (default: 3)'),\n depthAfter: z.number().optional().describe('Number of observations after (default: 3)'),\n },\n },\n async ({ anchorId, depthBefore, depthAfter }) => {\n const result = await compactTimeline(\n anchorId,\n undefined,\n depthBefore,\n depthAfter,\n );\n\n return {\n content: [\n {\n type: 'text' as const,\n text: result.formatted,\n },\n ],\n };\n },\n );\n\n /**\n * memorix_detail — Layer 3: Full observation details\n *\n * Fetch complete observation content by IDs.\n * Only call after filtering via memorix_search / memorix_timeline.\n * ~500-1000 tokens per observation.\n */\n server.registerTool(\n 'memorix_detail',\n {\n title: 'Memory Details',\n description:\n 'Fetch full observation details by IDs (~500-1000 tokens each). ' +\n 'Always use memorix_search first to find relevant IDs, then fetch only what you need.',\n inputSchema: {\n ids: z.array(z.number()).describe('Observation IDs to fetch (from memorix_search results)'),\n },\n },\n async ({ ids }) => {\n const result = await compactDetail(ids);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: result.documents.length > 0\n ? result.formatted\n : `No observations found for IDs: ${ids.join(', ')}`,\n },\n ],\n };\n },\n );\n\n // ================================================================\n // Memorix Retention & Decay Tools (inspired by mcp-memory-service + MemCP)\n // ================================================================\n\n /**\n * memorix_retention — Memory retention status\n *\n * Shows which observations are active, stale, or candidates for archiving.\n * Uses exponential decay scoring from mcp-memory-service.\n */\n server.registerTool(\n 'memorix_retention',\n {\n title: 'Memory Retention Status',\n description:\n 'Show memory retention status: active/stale/archive-candidate counts, ' +\n 'immune observations, and top stale candidates. ' +\n 'Uses exponential decay scoring based on importance, age, and access patterns.',\n inputSchema: {},\n },\n async () => {\n const { getRetentionSummary, getArchiveCandidates, rankByRelevance } = await import('./memory/retention.js');\n const { search } = await import('@orama/orama');\n\n // Get all observations for this project\n const database = await (await import('./store/orama-store.js')).getDb();\n const allResults = await search(database, {\n term: '',\n where: {},\n limit: 10000,\n });\n const docs = allResults.hits.map((h) => h.document as unknown as import('./types.js').MemorixDocument);\n\n if (docs.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No observations found for this project.' }],\n };\n }\n\n const summary = getRetentionSummary(docs);\n const candidates = getArchiveCandidates(docs);\n const ranked = rankByRelevance(docs);\n\n // Format output\n const lines: string[] = [\n `## Memory Retention Status`,\n ``,\n `| Zone | Count |`,\n `|------|-------|`,\n `| Active | ${summary.active} |`,\n `| Stale | ${summary.stale} |`,\n `| Archive Candidates | ${summary.archiveCandidates} |`,\n `| Immune | ${summary.immune} |`,\n `| **Total** | **${docs.length}** |`,\n ``,\n ];\n\n if (candidates.length > 0) {\n lines.push(`### Archive Candidates (${candidates.length})`);\n lines.push(`| ID | Title | Age (days) | Access |`);\n lines.push(`|----|-------|-----------|--------|`);\n for (const c of candidates.slice(0, 10)) {\n const ageDays = Math.round(\n (Date.now() - new Date(c.createdAt).getTime()) / (1000 * 60 * 60 * 24),\n );\n lines.push(`| ${c.observationId} | ${c.title} | ${ageDays}d | ${c.accessCount ?? 0}× |`);\n }\n lines.push('');\n }\n\n // Top 5 most relevant\n lines.push(`### Top 5 Most Relevant`);\n lines.push(`| ID | Title | Score | Decay | Access Boost |`);\n lines.push(`|----|-------|-------|-------|-------------|`);\n for (const r of ranked.slice(0, 5)) {\n const doc = docs.find((d) => d.observationId === r.observationId);\n lines.push(\n `| ${r.observationId} | ${doc?.title ?? '?'} | ${r.totalScore.toFixed(3)} | ${r.decayFactor.toFixed(3)} | ${r.accessBoost.toFixed(1)}× |`,\n );\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n },\n );\n\n // ================================================================\n // MCP Official Memory Server Compatible Tools\n // ================================================================\n\n /** create_entities — MCP Official compatible */\n server.registerTool(\n 'create_entities',\n {\n title: 'Create Entities',\n description: 'Create multiple new entities in the knowledge graph',\n inputSchema: {\n entities: z.array(z.object({\n name: z.string().describe('The name of the entity'),\n entityType: z.string().describe('The type of the entity'),\n observations: z.array(z.string()).describe('Initial observations'),\n })),\n },\n },\n async ({ entities }) => {\n const result = await graphManager.createEntities(entities);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n\n /** create_relations — MCP Official compatible, enhanced with typed relation suggestions */\n server.registerTool(\n 'create_relations',\n {\n title: 'Create Relations',\n description:\n 'Create multiple new relations between entities in the knowledge graph. Relations should be in active voice. ' +\n 'Recommended relation types (from mcp-memory-service): causes, fixes, supports, opposes, contradicts, ' +\n 'depends_on, implements, extends, replaces, documents',\n inputSchema: {\n relations: z.array(z.object({\n from: z.string().describe('Source entity name'),\n to: z.string().describe('Target entity name'),\n relationType: z.string().describe('Type of relation (e.g., causes, fixes, supports, depends_on, implements)'),\n })),\n },\n },\n async ({ relations }) => {\n const result = await graphManager.createRelations(relations);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n\n /** add_observations — MCP Official compatible */\n server.registerTool(\n 'add_observations',\n {\n title: 'Add Observations',\n description: 'Add new observations to existing entities in the knowledge graph',\n inputSchema: {\n observations: z.array(z.object({\n entityName: z.string().describe('Entity name to add observations to'),\n contents: z.array(z.string()).describe('Observation contents to add'),\n })),\n },\n },\n async ({ observations }) => {\n const result = await graphManager.addObservations(observations);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n\n /** delete_entities — MCP Official compatible */\n server.registerTool(\n 'delete_entities',\n {\n title: 'Delete Entities',\n description: 'Delete multiple entities and their associated relations from the knowledge graph',\n inputSchema: {\n entityNames: z.array(z.string()).describe('Entity names to delete'),\n },\n },\n async ({ entityNames }) => {\n await graphManager.deleteEntities(entityNames);\n return {\n content: [{ type: 'text' as const, text: 'Entities deleted successfully' }],\n };\n },\n );\n\n /** delete_observations — MCP Official compatible */\n server.registerTool(\n 'delete_observations',\n {\n title: 'Delete Observations',\n description: 'Delete specific observations from entities in the knowledge graph',\n inputSchema: {\n deletions: z.array(z.object({\n entityName: z.string().describe('Entity containing the observations'),\n observations: z.array(z.string()).describe('Observations to delete'),\n })),\n },\n },\n async ({ deletions }) => {\n await graphManager.deleteObservations(deletions);\n return {\n content: [{ type: 'text' as const, text: 'Observations deleted successfully' }],\n };\n },\n );\n\n /** delete_relations — MCP Official compatible */\n server.registerTool(\n 'delete_relations',\n {\n title: 'Delete Relations',\n description: 'Delete multiple relations from the knowledge graph',\n inputSchema: {\n relations: z.array(z.object({\n from: z.string(),\n to: z.string(),\n relationType: z.string(),\n })),\n },\n },\n async ({ relations }) => {\n await graphManager.deleteRelations(relations);\n return {\n content: [{ type: 'text' as const, text: 'Relations deleted successfully' }],\n };\n },\n );\n\n /** read_graph — MCP Official compatible */\n server.registerTool(\n 'read_graph',\n {\n title: 'Read Graph',\n description: 'Read the entire knowledge graph',\n inputSchema: {},\n },\n async () => {\n const graph = await graphManager.readGraph();\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(graph, null, 2) }],\n };\n },\n );\n\n /** search_nodes — MCP Official compatible (basic string search) */\n server.registerTool(\n 'search_nodes',\n {\n title: 'Search Nodes',\n description: 'Search for nodes in the knowledge graph based on a query',\n inputSchema: {\n query: z.string().describe('Search query to match against entity names, types, and observations'),\n },\n },\n async ({ query }) => {\n const graph = await graphManager.searchNodes(query);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(graph, null, 2) }],\n };\n },\n );\n\n /** open_nodes — MCP Official compatible */\n server.registerTool(\n 'open_nodes',\n {\n title: 'Open Nodes',\n description: 'Open specific nodes in the knowledge graph by their names',\n inputSchema: {\n names: z.array(z.string()).describe('Entity names to retrieve'),\n },\n },\n async ({ names }) => {\n const graph = await graphManager.openNodes(names);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(graph, null, 2) }],\n };\n },\n );\n\n // ============================================================\n // Rules Sync Tool (P2 — Memorix differentiator)\n // ============================================================\n\n const RULE_SOURCES: [string, ...string[]] = ['cursor', 'claude-code', 'codex', 'windsurf', 'antigravity', 'copilot', 'kiro'];\n\n /** memorix_rules_sync — scan, dedup, and generate rules across agents */\n server.registerTool(\n 'memorix_rules_sync',\n {\n title: 'Rules Sync',\n description:\n 'Scan project for agent rule files (Cursor, Claude Code, Codex, Windsurf, Antigravity, Copilot, Kiro), ' +\n 'deduplicate, detect conflicts, and optionally generate rules for a target agent format. ' +\n 'Without target: returns sync status report. With target: generates converted rule files.',\n inputSchema: {\n action: z.enum(['status', 'generate']).describe('Action: \"status\" for report, \"generate\" to produce target files'),\n target: z.enum(RULE_SOURCES).optional().describe('Target agent format for generation (required when action=generate)'),\n },\n },\n async ({ action, target }) => {\n const syncer = new RulesSyncer(project.rootPath);\n\n if (action === 'status') {\n const status = await syncer.syncStatus();\n const lines = [\n `## Rules Sync Status`,\n ``,\n `**Sources found:** ${status.sources.join(', ') || 'none'}`,\n `**Total rules:** ${status.totalRules}`,\n `**Unique rules:** ${status.uniqueRules}`,\n `**Conflicts:** ${status.conflicts.length}`,\n ];\n\n if (status.conflicts.length > 0) {\n lines.push('', '### Conflicts');\n for (const c of status.conflicts) {\n lines.push(`- **${c.ruleA.source}** \\`${c.ruleA.id}\\` vs **${c.ruleB.source}** \\`${c.ruleB.id}\\`: ${c.reason}`);\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n }\n\n // action === 'generate'\n if (!target) {\n return {\n content: [{ type: 'text' as const, text: 'Error: target is required for generate action' }],\n isError: true,\n };\n }\n\n const rules = await syncer.scanRules();\n const deduped = syncer.deduplicateRules(rules);\n const files = syncer.generateForTarget(deduped, target as RuleSource);\n\n const lines = [\n `## Generated ${files.length} file(s) for ${target}`,\n '',\n ];\n for (const f of files) {\n lines.push(`### \\`${f.filePath}\\``, '```', f.content, '```', '');\n }\n lines.push('> Use these contents to create the rule files in your project.');\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n },\n );\n\n // ============================================================\n // Workspace Sync Tool (P3 — Cross-Agent Workspace Bridge)\n // ============================================================\n\n const AGENT_TARGETS: [string, ...string[]] = ['windsurf', 'cursor', 'claude-code', 'codex', 'copilot', 'antigravity', 'kiro'];\n\n /** memorix_workspace_sync — migrate entire workspace config across agents */\n server.registerTool(\n 'memorix_workspace_sync',\n {\n title: 'Workspace Sync',\n description:\n 'Migrate your entire workspace environment between AI agents. ' +\n 'Syncs MCP server configs, workflows, rules, and skills. ' +\n 'Action \"scan\": detect all workspace configs. ' +\n 'Action \"migrate\": generate configs for target agent (preview only). ' +\n 'Action \"apply\": migrate AND write configs to disk with backup/rollback.',\n inputSchema: {\n action: z.enum(['scan', 'migrate', 'apply']).describe('Action: \"scan\" to detect configs, \"migrate\" to preview, \"apply\" to write to disk'),\n target: z.enum(AGENT_TARGETS).optional().describe('Target agent for migration (required for migrate)'),\n items: z.array(z.string()).optional().describe('Selective sync: list specific MCP server or skill names to sync (e.g. [\"figma-remote-mcp-server\", \"create-subagent\"]). Omit to sync all.'),\n },\n },\n async ({ action, target, items }) => {\n const engine = new WorkspaceSyncEngine(project.rootPath);\n\n if (action === 'scan') {\n const scan = await engine.scan();\n const lines = [\n `## Workspace Scan Report`,\n '',\n `### MCP Server Configs`,\n ];\n\n for (const [agent, servers] of Object.entries(scan.mcpConfigs)) {\n if ((servers as MCPServerEntry[]).length > 0) {\n lines.push(`- **${agent}**: ${(servers as MCPServerEntry[]).length} server(s) — ${(servers as MCPServerEntry[]).map((s: MCPServerEntry) => s.name).join(', ')}`);\n }\n }\n\n lines.push('', `### Workflows`);\n if (scan.workflows.length > 0) {\n for (const wf of scan.workflows) {\n lines.push(`- **${wf.name}** (${wf.source}): ${wf.description || '(no description)'}`);\n }\n } else {\n lines.push('- No workflows found');\n }\n\n lines.push('', `### Rules`);\n lines.push(`- ${scan.rulesCount} rule(s) detected across all agents`);\n\n lines.push('', `### Skills`);\n if (scan.skills.length > 0) {\n for (const sk of scan.skills) {\n lines.push(`- **${sk.name}** (${sk.sourceAgent}): ${sk.description || '(no description)'}`);\n }\n } else {\n lines.push('- No skills found');\n }\n\n if (scan.skillConflicts.length > 0) {\n lines.push('', `### ⚠️ Skill Name Conflicts`);\n for (const c of scan.skillConflicts) {\n lines.push(`- **${c.name}**: kept from ${c.kept.sourceAgent}, duplicate in ${c.skipped.sourceAgent}`);\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n }\n\n // action === 'migrate' or 'apply' — both need target\n if (!target) {\n return {\n content: [{ type: 'text' as const, text: 'Error: target is required for migrate/apply action' }],\n isError: true,\n };\n }\n\n if (action === 'apply') {\n const applyResult = await engine.apply(target as AgentTarget, items);\n return {\n content: [{ type: 'text' as const, text: applyResult.migrationSummary }],\n ...(applyResult.success ? {} : { isError: true }),\n };\n }\n\n // action === 'migrate' (preview only)\n const result = await engine.migrate(target as AgentTarget, items);\n const lines = [\n `## Workspace Migration → ${target}`,\n '',\n ];\n\n if (result.mcpServers.generated.length > 0) {\n lines.push('### MCP Config');\n for (const f of result.mcpServers.generated) {\n lines.push(`#### \\`${f.filePath}\\``, '```', f.content, '```', '');\n }\n }\n\n if (result.workflows.generated.length > 0) {\n lines.push('### Workflows');\n for (const f of result.workflows.generated) {\n lines.push(`#### \\`${f.filePath}\\``, '```', f.content, '```', '');\n }\n }\n\n if (result.rules.generated > 0) {\n lines.push(`### Rules`, `- ${result.rules.generated} rule file(s) generated`);\n }\n\n if (result.skills.scanned.length > 0) {\n lines.push('### Skills', `- ${result.skills.scanned.length} skill(s) found, ready to copy:`);\n for (const sk of result.skills.scanned) {\n lines.push(` - **${sk.name}** (from ${sk.sourceAgent})`);\n }\n }\n\n lines.push('', '> Review the generated configs above. Use action \"apply\" to write them to disk.');\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n },\n );\n\n // ============================================================\n // memorix_skills — Memory-driven project skills\n // ============================================================\n\n server.registerTool(\n 'memorix_skills',\n {\n title: 'Project Skills',\n description:\n 'Memory-driven project skills. ' +\n 'Action \"list\": show all available skills from all agents. ' +\n 'Action \"generate\": auto-generate project-specific skills from observation patterns (gotchas, decisions, how-it-works). ' +\n 'Action \"inject\": return a specific skill\\'s full content for direct use. ' +\n 'Generated skills follow the SKILL.md standard and can be synced across agents.',\n inputSchema: {\n action: z.enum(['list', 'generate', 'inject']).describe('Action: \"list\" to discover skills, \"generate\" to create from memory, \"inject\" to get skill content'),\n name: z.string().optional().describe('Skill name (required for \"inject\")'),\n target: z.enum(AGENT_TARGETS).optional().describe('Target agent to write generated skills to (optional for \"generate\")'),\n write: z.boolean().optional().describe('Whether to write generated skills to disk (default: false, preview only)'),\n },\n },\n async ({ action, name, target, write }) => {\n const { SkillsEngine } = await import('./skills/engine.js');\n const engine = new SkillsEngine(project.rootPath);\n\n if (action === 'list') {\n const skills = engine.listSkills();\n if (skills.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No skills found in any agent directory.\\n\\nSkills are discovered from:\\n- `.cursor/skills/*/SKILL.md`\\n- `.agents/skills/*/SKILL.md`\\n- `.agent/skills/*/SKILL.md`\\n- `.windsurf/skills/*/SKILL.md`\\n- etc.\\n\\nUse action \"generate\" to auto-create skills from your project observations.' }],\n };\n }\n\n const lines = [\n `## Available Skills (${skills.length})`,\n '',\n ];\n for (const sk of skills) {\n lines.push(`- **${sk.name}** (${sk.sourceAgent}): ${sk.description || '(no description)'}`);\n }\n lines.push('', '> Use `action: \"inject\", name: \"<skill-name>\"` to get full skill content.');\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n }\n\n if (action === 'inject') {\n if (!name) {\n return {\n content: [{ type: 'text' as const, text: 'Error: `name` is required for inject action. Use `action: \"list\"` first to see available skills.' }],\n isError: true,\n };\n }\n\n const skill = engine.injectSkill(name);\n if (!skill) {\n return {\n content: [{ type: 'text' as const, text: `Skill \"${name}\" not found. Use \\`action: \"list\"\\` to see available skills.` }],\n isError: true,\n };\n }\n\n return {\n content: [{ type: 'text' as const, text: `## Skill: ${skill.name}\\n**Source**: ${skill.sourceAgent}\\n**Path**: ${skill.sourcePath}\\n\\n---\\n\\n${skill.content}` }],\n };\n }\n\n // action === 'generate'\n const { loadObservationsJson } = await import('./store/persistence.js');\n const allObs = await loadObservationsJson(projectDir) as Array<{\n id?: number; entityName?: string; type?: string; title?: string;\n narrative?: string; facts?: string[]; concepts?: string[];\n filesModified?: string[]; createdAt?: string;\n }>;\n\n const obsData = allObs.map(o => ({\n id: o.id || 0,\n entityName: o.entityName || 'unknown',\n type: o.type || 'discovery',\n title: o.title || '',\n narrative: o.narrative || '',\n facts: o.facts,\n concepts: o.concepts,\n filesModified: o.filesModified,\n createdAt: o.createdAt,\n }));\n\n const generated = engine.generateFromObservations(obsData);\n\n if (generated.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No skill-worthy patterns found yet.\\n\\nSkills are auto-generated when entities accumulate enough observations (3+), especially gotchas, decisions, and how-it-works notes.\\n\\nKeep using memorix_store to build up project knowledge!' }],\n };\n }\n\n const lines = [\n `## Generated Skills (${generated.length})`,\n '',\n 'Based on observation patterns in your project memory:',\n '',\n ];\n\n for (const sk of generated) {\n lines.push(`### ${sk.name}`);\n lines.push(`- **Description**: ${sk.description}`);\n lines.push(`- **Observations**: ${sk.content.split('\\n').length} lines of knowledge`);\n\n if (write && target) {\n const path = engine.writeSkill(sk, target as AgentTarget);\n if (path) {\n lines.push(`- ✅ **Written**: \\`${path}\\``);\n } else {\n lines.push(`- ❌ Failed to write`);\n }\n }\n lines.push('');\n }\n\n if (!write) {\n lines.push('> Preview only. Add `write: true, target: \"<agent>\"` to save skills to disk.');\n }\n\n // Show first generated skill as preview\n if (generated.length > 0) {\n lines.push('', '---', '### Preview: ' + generated[0].name, '', '```markdown', generated[0].content, '```');\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n },\n );\n\n // ============================================================\n // memorix_dashboard — Launch the web dashboard\n // ============================================================\n\n let dashboardRunning = false;\n\n server.registerTool(\n 'memorix_dashboard',\n {\n title: 'Launch Dashboard',\n description:\n 'Launch the Memorix Web Dashboard in the browser. ' +\n 'Shows knowledge graph, observations, retention scores, and project stats in a visual interface.',\n inputSchema: {\n port: z.number().optional().describe('Port to run the dashboard on (default: 3210)'),\n },\n },\n async ({ port: dashboardPort }) => {\n const portNum = (dashboardPort as number) || 3210;\n const url = `http://localhost:${portNum}`;\n\n if (dashboardRunning) {\n const { exec } = await import('node:child_process');\n const cmd =\n process.platform === 'win32' ? `start \"\" \"${url}\"` :\n process.platform === 'darwin' ? `open \"${url}\"` :\n `xdg-open \"${url}\"`;\n exec(cmd, () => { });\n return {\n content: [{ type: 'text' as const, text: `Dashboard is already running at ${url}. Opened in browser.` }],\n };\n }\n\n try {\n const pathMod = await import('node:path');\n const fsMod = await import('node:fs');\n const { fileURLToPath } = await import('node:url');\n const { startDashboard } = await import('./dashboard/server.js');\n\n // Try multiple strategies to find the static files directory\n // When running from CLI (dist/cli/index.js), __dirname = dist/cli/, need to go up\n const candidates = [\n pathMod.default.join(__dirname, '..', 'dashboard', 'static'),\n pathMod.default.join(__dirname, 'dashboard', 'static'),\n pathMod.default.join(pathMod.default.dirname(fileURLToPath(import.meta.url)), '..', 'dashboard', 'static'),\n pathMod.default.join(pathMod.default.dirname(fileURLToPath(import.meta.url)), 'dashboard', 'static'),\n ];\n\n // Log all candidates for debugging\n for (const [i, c] of candidates.entries()) {\n const hasIndex = fsMod.existsSync(pathMod.default.join(c, 'index.html'));\n console.error(`[memorix] candidate[${i}]: ${c} (has index.html: ${hasIndex})`);\n }\n\n let staticDir = candidates[0];\n for (const c of candidates) {\n if (fsMod.existsSync(pathMod.default.join(c, 'index.html'))) {\n staticDir = c;\n break;\n }\n }\n console.error(`[memorix] Dashboard staticDir: ${staticDir}`);\n\n // Start in background (non-blocking), disable auto-open (we'll open it ourselves)\n startDashboard(projectDir, portNum, staticDir, project.id, project.name, false)\n .then(() => { dashboardRunning = true; })\n .catch((err) => { console.error('[memorix] Dashboard error:', err); dashboardRunning = false; });\n\n // Poll until the server is actually listening (up to 5s)\n const { createConnection } = await import('node:net');\n await new Promise<void>(resolve => {\n const deadline = Date.now() + 5000;\n const tryConnect = () => {\n const sock = createConnection(portNum, '127.0.0.1');\n sock.once('connect', () => { sock.destroy(); resolve(); });\n sock.once('error', () => {\n sock.destroy();\n if (Date.now() < deadline) setTimeout(tryConnect, 100);\n else resolve(); // give up, return anyway\n });\n };\n tryConnect();\n });\n dashboardRunning = true;\n\n // Open browser from MCP side\n const { exec: execCmd } = await import('node:child_process');\n const openCmd =\n process.platform === 'win32' ? `start \"\" \"${url}\"` :\n process.platform === 'darwin' ? `open \"${url}\"` :\n `xdg-open \"${url}\"`;\n execCmd(openCmd, () => { });\n\n return {\n content: [{\n type: 'text' as const,\n text: [\n `Memorix Dashboard started!`,\n ``,\n `URL: ${url}`,\n `Project: ${project.name} (${project.id})`,\n `Static: ${staticDir}`,\n ``,\n `The dashboard has been opened in your default browser.`,\n `It shows your knowledge graph, observations, retention scores, and project stats.`,\n ].join('\\n'),\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text' as const, text: `Failed to start dashboard: ${err instanceof Error ? err.message : String(err)}` }],\n };\n }\n },\n );\n\n return { server, graphManager, projectId: project.id };\n}\n","/**\n * memorix serve — Start MCP Server on stdio\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'serve',\n description: 'Start Memorix MCP Server on stdio transport',\n },\n args: {\n cwd: {\n type: 'string',\n description: 'Project working directory (defaults to process.cwd())',\n required: false,\n },\n },\n run: async ({ args }) => {\n const { StdioServerTransport } = await import(\n '@modelcontextprotocol/sdk/server/stdio.js'\n );\n const { createMemorixServer } = await import('../../server.js');\n const { execSync } = await import('node:child_process');\n\n // Priority: explicit --cwd arg > INIT_CWD (npm lifecycle) > process.cwd()\n let projectRoot = args.cwd || process.env.INIT_CWD || process.cwd();\n\n // Verify git is available at the projectRoot; if not, try the script's\n // own directory (useful when memorix runs from a global npm install\n // but the user's project is at a known location).\n try {\n execSync('git rev-parse --show-toplevel', {\n cwd: projectRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n } catch {\n // cwd is not inside a git repo — try the script directory\n const scriptDir = new URL('.', import.meta.url).pathname.replace(/^\\/([A-Z]:)/, '$1');\n try {\n const gitRoot = execSync('git rev-parse --show-toplevel', {\n cwd: scriptDir,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n if (gitRoot) {\n projectRoot = gitRoot;\n console.error(`[memorix] CWD has no git, using script dir: ${projectRoot}`);\n }\n } catch {\n // Neither has git — fall through with original projectRoot\n }\n }\n\n const { server, projectId } = await createMemorixServer(projectRoot);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n console.error(`[memorix] MCP Server running on stdio (project: ${projectId})`);\n console.error(`[memorix] Project root: ${projectRoot}`);\n },\n});\n","/**\n * memorix status — Show project info + rules sync status\n */\n\nimport { defineCommand } from 'citty';\nimport * as p from '@clack/prompts';\n\nexport default defineCommand({\n meta: {\n name: 'status',\n description: 'Show project info and rules sync status',\n },\n run: async () => {\n const { detectProject } = await import('../../project/detector.js');\n const { RulesSyncer } = await import('../../rules/syncer.js');\n const { getProjectDataDir } = await import('../../store/persistence.js');\n\n p.intro('memorix status');\n\n const project = detectProject();\n const dataDir = await getProjectDataDir(project.id);\n const syncer = new RulesSyncer(project.rootPath);\n const status = await syncer.syncStatus();\n\n p.note(\n [\n `Name: ${project.name}`,\n `ID: ${project.id}`,\n `Root: ${project.rootPath}`,\n `Git remote: ${project.gitRemote || 'none'}`,\n `Data dir: ${dataDir}`,\n ].join('\\n'),\n 'Project',\n );\n\n p.note(\n [\n `Sources: ${status.sources.join(', ') || 'none detected'}`,\n `Total rules: ${status.totalRules}`,\n `Unique rules: ${status.uniqueRules}`,\n `Conflicts: ${status.conflicts.length}`,\n ].join('\\n'),\n 'Rules Sync',\n );\n\n if (status.conflicts.length > 0) {\n p.log.warn('Conflicts detected:');\n for (const c of status.conflicts) {\n p.log.warn(` ${c.ruleA.source}:${c.ruleA.id} vs ${c.ruleB.source}:${c.ruleB.id}`);\n p.log.warn(` → ${c.reason}`);\n }\n }\n\n if (status.totalRules === 0) {\n p.log.info('No rule files found. Create .cursorrules, CLAUDE.md, or .windsurfrules to get started.');\n }\n\n p.outro('Done');\n },\n});\n","/**\n * memorix sync — Interactive cross-agent rule sync\n *\n * Uses @clack/prompts for a beautiful interactive wizard.\n */\n\nimport { defineCommand } from 'citty';\nimport * as p from '@clack/prompts';\nimport type { RuleSource } from '../../types.js';\n\nconst SOURCE_LABELS: Record<string, string> = {\n cursor: 'Cursor (.cursor/rules/*.mdc, .cursorrules)',\n 'claude-code': 'Claude Code (CLAUDE.md, .claude/rules/*.md)',\n codex: 'Codex (SKILL.md, AGENTS.md)',\n windsurf: 'Windsurf (.windsurfrules, .windsurf/rules/*.md)',\n antigravity: 'Antigravity (.agent/rules/*.md, GEMINI.md)',\n kiro: 'Kiro (.kiro/steering/*.md, AGENTS.md)',\n};\n\nexport default defineCommand({\n meta: {\n name: 'sync',\n description: 'Interactive cross-agent rule synchronization',\n },\n args: {\n target: {\n type: 'string',\n description: 'Target agent format (cursor, claude-code, codex, windsurf, antigravity, kiro)',\n required: false,\n },\n dry: {\n type: 'boolean',\n description: 'Dry run — show what would be generated without writing files',\n default: false,\n },\n },\n run: async ({ args }) => {\n const { detectProject } = await import('../../project/detector.js');\n const { RulesSyncer } = await import('../../rules/syncer.js');\n const { promises: fs } = await import('node:fs');\n const path = await import('node:path');\n\n p.intro('memorix sync');\n\n // Detect project\n const project = detectProject();\n p.log.info(`Project: ${project.name} (${project.id})`);\n\n // Scan rules\n const syncer = new RulesSyncer(project.rootPath);\n const spin = p.spinner();\n spin.start('Scanning rule files...');\n const rules = await syncer.scanRules();\n spin.stop(`Found ${rules.length} rule(s)`);\n\n if (rules.length === 0) {\n p.log.warn('No rule files found in this project.');\n p.log.info('Create .cursorrules, CLAUDE.md, or .windsurfrules to get started.');\n p.outro('Nothing to sync');\n return;\n }\n\n // Show sources\n const sources = [...new Set(rules.map(r => r.source))];\n p.log.info(`Sources: ${sources.map(s => SOURCE_LABELS[s] || s).join(', ')}`);\n\n // Dedup\n const deduped = syncer.deduplicateRules(rules);\n if (deduped.length < rules.length) {\n p.log.info(`Deduplicated: ${rules.length} → ${deduped.length} unique rule(s)`);\n }\n\n // Conflicts\n const conflicts = syncer.detectConflicts(deduped);\n if (conflicts.length > 0) {\n p.log.warn(`⚠ ${conflicts.length} conflict(s) detected:`);\n for (const c of conflicts) {\n p.log.warn(` ${c.ruleA.source} vs ${c.ruleB.source}: ${c.reason}`);\n }\n }\n\n // Select target\n let target = args.target as RuleSource | undefined;\n\n if (!target) {\n const available = ['cursor', 'claude-code', 'codex', 'windsurf', 'antigravity', 'kiro'].filter(\n t => !sources.includes(t as RuleSource),\n );\n\n if (available.length === 0) {\n // All formats already present, let user pick any\n available.push('cursor', 'claude-code', 'codex', 'windsurf', 'antigravity', 'kiro');\n }\n\n const selected = await p.select({\n message: 'Generate rules for which agent?',\n options: available.map(t => ({\n value: t,\n label: SOURCE_LABELS[t] || t,\n })),\n });\n\n if (p.isCancel(selected)) {\n p.cancel('Sync cancelled');\n process.exit(0);\n }\n\n target = selected as RuleSource;\n }\n\n // Generate\n spin.start(`Generating ${target} rules...`);\n const files = syncer.generateForTarget(deduped, target);\n spin.stop(`Generated ${files.length} file(s)`);\n\n // Show preview\n for (const file of files) {\n p.note(file.content, file.filePath);\n }\n\n // Write or dry run\n if (args.dry) {\n p.log.info('Dry run — no files written');\n p.outro('Done (dry run)');\n return;\n }\n\n const confirm = await p.confirm({\n message: `Write ${files.length} file(s) to project?`,\n });\n\n if (p.isCancel(confirm) || !confirm) {\n p.cancel('Sync cancelled');\n process.exit(0);\n }\n\n for (const file of files) {\n const fullPath = path.join(project.rootPath, file.filePath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n await fs.writeFile(fullPath, file.content, 'utf-8');\n p.log.success(`Written: ${file.filePath}`);\n }\n\n p.outro(`Synced ${files.length} rule(s) to ${target} format`);\n },\n});\n","/**\n * Hook Normalizer\n *\n * Converts agent-specific stdin JSON into a unified NormalizedHookInput.\n * Each agent has a different event naming convention and payload structure,\n * but they all communicate via stdin/stdout JSON.\n */\n\nimport type { AgentName, HookEvent, NormalizedHookInput } from './types.js';\n\n/**\n * Map agent-specific event names → normalized event names.\n */\nconst EVENT_MAP: Record<string, HookEvent> = {\n // Identity mappings — already-normalized event names\n // This allows direct payloads like { event: 'session_start' } to work\n session_start: 'session_start',\n user_prompt: 'user_prompt',\n post_edit: 'post_edit',\n post_command: 'post_command',\n post_tool: 'post_tool',\n pre_compact: 'pre_compact',\n session_end: 'session_end',\n post_response: 'post_response',\n\n // Claude Code / VS Code Copilot\n SessionStart: 'session_start',\n UserPromptSubmit: 'user_prompt',\n PreToolUse: 'post_tool', // we handle pre as post for memory purposes\n PostToolUse: 'post_tool',\n PreCompact: 'pre_compact',\n Stop: 'session_end',\n\n // Windsurf\n pre_user_prompt: 'user_prompt',\n post_write_code: 'post_edit',\n post_read_code: 'post_tool',\n post_run_command: 'post_command',\n pre_mcp_tool_use: 'post_tool',\n post_mcp_tool_use: 'post_tool',\n post_cascade_response: 'post_response',\n\n // Cursor\n beforeSubmitPrompt: 'user_prompt',\n beforeShellExecution: 'post_command',\n beforeMCPExecution: 'post_tool',\n afterFileEdit: 'post_edit',\n stop: 'session_end',\n};\n\n/**\n * Detect which agent sent this hook event based on payload structure.\n */\nfunction detectAgent(payload: Record<string, unknown>): AgentName {\n // Windsurf uses agent_action_name\n if ('agent_action_name' in payload) return 'windsurf';\n\n // Cursor uses hook_event_name (lowercase) + conversation_id\n if ('hook_event_name' in payload && 'conversation_id' in payload) return 'cursor';\n\n // Claude Code / VS Code Copilot use hookEventName (camelCase)\n if ('hookEventName' in payload) {\n // VS Code Copilot has transcript_path; Claude Code also has it\n // They use the same format, so we distinguish by sessionId pattern if needed\n return 'copilot'; // treat as copilot (same format as claude)\n }\n\n // Kiro uses event_type\n if ('event_type' in payload) return 'kiro';\n\n // Codex\n if ('hook_type' in payload) return 'codex';\n\n return 'claude'; // default fallback\n}\n\n/**\n * Extract the raw event name string from agent-specific payload.\n */\nfunction extractEventName(payload: Record<string, unknown>, agent: AgentName): string {\n switch (agent) {\n case 'windsurf':\n return (payload.agent_action_name as string) ?? '';\n case 'cursor':\n return (payload.hook_event_name as string) ?? '';\n case 'copilot':\n case 'claude':\n return (payload.hookEventName as string) ?? '';\n case 'kiro':\n return (payload.event_type as string) ?? '';\n case 'codex':\n return (payload.hook_type as string) ?? '';\n default:\n return '';\n }\n}\n\n/**\n * Normalize a Claude Code / VS Code Copilot payload.\n */\nfunction normalizeClaude(payload: Record<string, unknown>, event: HookEvent): Partial<NormalizedHookInput> {\n const result: Partial<NormalizedHookInput> = {\n sessionId: (payload.sessionId as string) ?? '',\n cwd: (payload.cwd as string) ?? '',\n transcriptPath: payload.transcript_path as string | undefined,\n };\n\n // PostToolUse with write tool → post_edit\n const toolName = (payload.tool_name as string) ?? '';\n if (toolName) {\n result.toolName = toolName;\n result.toolInput = payload.tool_input as Record<string, unknown> | undefined;\n result.toolResult = payload.tool_result as string | undefined;\n\n // Detect file edits\n if (toolName === 'write' || toolName === 'edit' || toolName === 'multi_edit') {\n const input = payload.tool_input as Record<string, unknown> | undefined;\n result.filePath = (input?.file_path as string) ?? (input?.filePath as string);\n }\n }\n\n // UserPromptSubmit\n if (event === 'user_prompt') {\n result.userPrompt = (payload.prompt as string) ?? '';\n }\n\n return result;\n}\n\n/**\n * Normalize a Windsurf payload.\n */\nfunction normalizeWindsurf(payload: Record<string, unknown>, event: HookEvent): Partial<NormalizedHookInput> {\n const toolInfo = (payload.tool_info as Record<string, unknown>) ?? {};\n const result: Partial<NormalizedHookInput> = {\n sessionId: (payload.trajectory_id as string) ?? '',\n cwd: '',\n };\n\n switch (event) {\n case 'post_edit':\n result.filePath = toolInfo.file_path as string | undefined;\n if (Array.isArray(toolInfo.edits)) {\n result.edits = (toolInfo.edits as Array<Record<string, string>>).map((e) => ({\n oldString: e.old_string ?? '',\n newString: e.new_string ?? '',\n }));\n }\n break;\n case 'post_command':\n result.command = toolInfo.command_line as string | undefined;\n result.cwd = (toolInfo.cwd as string) ?? '';\n break;\n case 'post_tool':\n result.toolName = toolInfo.mcp_tool_name as string | undefined;\n result.toolInput = toolInfo.mcp_tool_arguments as Record<string, unknown> | undefined;\n result.toolResult = toolInfo.mcp_result as string | undefined;\n break;\n case 'user_prompt':\n result.userPrompt = toolInfo.user_prompt as string | undefined;\n break;\n case 'post_response':\n result.aiResponse = toolInfo.response as string | undefined;\n break;\n }\n\n return result;\n}\n\n/**\n * Normalize a Cursor payload.\n */\nfunction normalizeCursor(payload: Record<string, unknown>, event: HookEvent): Partial<NormalizedHookInput> {\n const result: Partial<NormalizedHookInput> = {\n sessionId: (payload.conversation_id as string) ?? '',\n cwd: (payload.cwd as string) ?? '',\n };\n\n const roots = payload.workspace_roots as string[] | undefined;\n if (roots?.length && !result.cwd) {\n result.cwd = roots[0];\n }\n\n switch (event) {\n case 'user_prompt':\n result.userPrompt = (payload.prompt as string) ?? '';\n break;\n case 'post_command':\n result.command = (payload.command as string) ?? '';\n break;\n case 'post_edit':\n result.filePath = (payload.file_path as string) ?? '';\n break;\n }\n\n return result;\n}\n\n/**\n * Main normalizer: convert any agent's stdin payload → NormalizedHookInput.\n */\nexport function normalizeHookInput(payload: Record<string, unknown>): NormalizedHookInput {\n // Support direct/standard payloads: { event: 'session_start', cwd: '...' }\n // This is used by MCP server internals, CLI, and testing scenarios.\n const directEvent = typeof payload.event === 'string' ? EVENT_MAP[payload.event] : undefined;\n\n const agent = detectAgent(payload);\n const rawEventName = extractEventName(payload, agent);\n const event: HookEvent = directEvent ?? EVENT_MAP[rawEventName] ?? 'post_tool';\n const timestamp = (payload.timestamp as string) ?? new Date().toISOString();\n\n let agentSpecific: Partial<NormalizedHookInput> = {};\n switch (agent) {\n case 'claude':\n case 'copilot':\n agentSpecific = normalizeClaude(payload, event);\n break;\n case 'windsurf':\n agentSpecific = normalizeWindsurf(payload, event);\n break;\n case 'cursor':\n agentSpecific = normalizeCursor(payload, event);\n break;\n default:\n agentSpecific = { sessionId: '', cwd: '' };\n }\n\n return {\n event,\n agent,\n timestamp,\n sessionId: agentSpecific.sessionId ?? '',\n cwd: agentSpecific.cwd ?? '',\n raw: payload,\n ...agentSpecific,\n };\n}\n","/**\n * Pattern Detector\n *\n * Analyzes text content to detect patterns worth remembering.\n * Inspired by mcp-memory-service's Smart Auto-Capture,\n * but works across all agents via the unified hooks system.\n */\n\nimport type { DetectedPattern, PatternType } from './types.js';\n\n/** Minimum content length to consider for pattern detection */\nconst MIN_CONTENT_LENGTH = 100;\n\n/** Pattern definitions with multilingual keywords */\nconst PATTERNS: Array<{\n type: PatternType;\n keywords: RegExp[];\n minLength: number;\n baseConfidence: number;\n}> = [\n {\n type: 'decision',\n keywords: [\n /\\b(decided|chose|will use|settled on|going with|picked|selected)\\b/i,\n /(决定|选择了|采用|确定用|最终选了)/,\n /\\b(architecture|approach|strategy|pattern|framework)\\b/i,\n ],\n minLength: 100,\n baseConfidence: 0.8,\n },\n {\n type: 'error',\n keywords: [\n /\\b(error|bug|fix(ed)?|resolv(ed|ing)|crash|fail(ed|ure)?|broken)\\b/i,\n /(错误|修复|报错|崩溃|失败|异常|解决了)/,\n /\\b(workaround|hotfix|patch|regression|stack\\s*trace)\\b/i,\n ],\n minLength: 100,\n baseConfidence: 0.75,\n },\n {\n type: 'gotcha',\n keywords: [\n /\\b(gotcha|pitfall|trap|caveat|watch out|careful|beware|warning)\\b/i,\n /(坑|注意|陷阱|小心|踩坑|坑点)/,\n /\\b(don'?t|never|avoid|must not|不要|千万别|切记)\\b/i,\n ],\n minLength: 80,\n baseConfidence: 0.85,\n },\n {\n type: 'configuration',\n keywords: [\n /\\b(config(ured?|uration)?|setting|environment|\\.env)\\b/i,\n /(配置|环境变量|端口配置|设置项|安装配置)/,\n /\\b(gradle|webpack|vite|tsconfig|package\\.json|docker|nginx)\\b/i,\n /\\b(port\\s*[:=]|listen\\s+\\d|bind\\s+\\d|DATABASE_URL|API_KEY)\\b/i,\n ],\n minLength: 80,\n baseConfidence: 0.7,\n },\n {\n type: 'learning',\n keywords: [\n /\\b(learn(ed)?|discover(ed)?|realiz(ed)?|turns?\\s*out|found\\s*out|TIL)\\b/i,\n /(学到|发现|原来|才知道|了解到)/,\n /\\b(insight|understanding|clarif(ied|ication))\\b/i,\n ],\n minLength: 150,\n baseConfidence: 0.65,\n },\n {\n type: 'implementation',\n keywords: [\n /\\b(implement(ed)?|creat(ed|ing)|built|added|integrat(ed|ing))\\b/i,\n /(实现了|创建了|添加了|集成了|完成了)/,\n /\\b(refactor(ed)?|migrat(ed|ing)|upgrad(ed|ing))\\b/i,\n ],\n minLength: 200,\n baseConfidence: 0.5,\n },\n {\n type: 'deployment',\n keywords: [\n /\\b(deploy(ed|ing|ment)?|ship(ped|ping)?|releas(ed|ing)|publish(ed|ing)?)\\b/i,\n /(部署|发布|上线|迁移|运维)/,\n /\\b(docker|compose|container|kubernetes|k8s|helm)\\b/i,\n /\\b(VPS|server|host(ing)?|cloud|AWS|Azure|GCP|Cloudflare)\\b/i,\n /\\b(nginx|caddy|apache|reverse.?proxy|load.?balanc)\\b/i,\n /\\b(SSL|TLS|cert(ificate)?|HTTPS|Let'?s?.?Encrypt|ACME)\\b/i,\n /\\b(DNS|domain|A.?record|CNAME|nameserver|Cloudflare)\\b/i,\n /\\b(CI\\/CD|pipeline|GitHub.?Actions|Jenkins|GitLab.?CI)\\b/i,\n /\\b(scp|rsync|ssh|sftp|systemd|systemctl|service)\\b/i,\n /(服务器|域名|证书|反向代理|负载均衡|镜像|容器)/,\n ],\n minLength: 80,\n baseConfidence: 0.75,\n },\n ];\n\n/**\n * Detect patterns in text content.\n * Returns matched patterns sorted by confidence (highest first).\n */\nexport function detectPatterns(content: string): DetectedPattern[] {\n if (!content || content.length < MIN_CONTENT_LENGTH) {\n return [];\n }\n\n const results: DetectedPattern[] = [];\n\n for (const pattern of PATTERNS) {\n if (content.length < pattern.minLength) continue;\n\n const matchedKeywords: string[] = [];\n let matchCount = 0;\n\n for (const regex of pattern.keywords) {\n const matches = content.match(new RegExp(regex.source, regex.flags + 'g'));\n if (matches) {\n matchCount += matches.length;\n matchedKeywords.push(...matches.map((m) => m.trim()));\n }\n }\n\n if (matchCount > 0) {\n // Confidence increases with more keyword matches (up to 1.0)\n const confidence = Math.min(1.0, pattern.baseConfidence + matchCount * 0.05);\n results.push({\n type: pattern.type,\n confidence,\n matchedKeywords: [...new Set(matchedKeywords)].slice(0, 5),\n });\n }\n }\n\n // Sort by confidence descending\n results.sort((a, b) => b.confidence - a.confidence);\n\n return results;\n}\n\n/**\n * Get the best (highest confidence) pattern from content.\n * Returns null if no pattern is detected or confidence is too low.\n */\nexport function detectBestPattern(\n content: string,\n minConfidence = 0.5,\n): DetectedPattern | null {\n const patterns = detectPatterns(content);\n if (patterns.length === 0) return null;\n if (patterns[0].confidence < minConfidence) return null;\n return patterns[0];\n}\n\n/**\n * Map pattern type → Memorix observation type.\n */\nexport function patternToObservationType(\n pattern: PatternType,\n): string {\n const map: Record<PatternType, string> = {\n decision: 'decision',\n error: 'problem-solution',\n gotcha: 'gotcha',\n configuration: 'what-changed',\n learning: 'discovery',\n implementation: 'what-changed',\n deployment: 'what-changed',\n };\n return map[pattern] ?? 'discovery';\n}\n","/**\n * Hook Handler\n *\n * Unified entry point for all agent hooks.\n * Reads stdin JSON, normalizes it, detects patterns, and auto-stores memories.\n * Outputs JSON to stdout to control agent behavior (e.g., inject context).\n */\n\nimport type { ObservationType } from '../types.js';\nimport { normalizeHookInput } from './normalizer.js';\nimport { detectBestPattern, patternToObservationType } from './pattern-detector.js';\nimport type { HookEvent, HookOutput, NormalizedHookInput } from './types.js';\n\n/** Cooldown tracker: eventType → lastTimestamp */\nconst cooldowns = new Map<string, number>();\n\n/** Cooldown duration in ms (30 seconds) */\nconst COOLDOWN_MS = 30_000;\n\n/** Minimum content length for auto-store */\nconst MIN_STORE_LENGTH = 100;\n\n/** Lower threshold for code edits (file context adds value) */\nconst MIN_EDIT_LENGTH = 30;\n\n/** Trivial commands to skip (diagnostics, navigation, etc.) */\nconst NOISE_COMMANDS = [\n /^(ls|dir|cd|pwd|echo|cat|type|head|tail|wc|find|which|where|whoami)\\b/i,\n /^(Get-Content|Test-Path|Get-Item|Get-ChildItem|Set-Location|Write-Host)\\b/i,\n /^(Start-Sleep|Select-String|Select-Object|Format-Table|Measure-Object)\\b/i,\n /^(mkdir|rm|cp|mv|touch|chmod|chown)\\b/i,\n /^(node -[ep]|python -c)\\b/i,\n];\n\n/** Max content length (truncate beyond this) */\nconst MAX_CONTENT_LENGTH = 4000;\n\n/**\n * Check if an event is in cooldown.\n */\nfunction isInCooldown(eventKey: string): boolean {\n const last = cooldowns.get(eventKey);\n if (!last) return false;\n return Date.now() - last < COOLDOWN_MS;\n}\n\n/**\n * Mark an event as triggered (start cooldown).\n */\nfunction markTriggered(eventKey: string): void {\n cooldowns.set(eventKey, Date.now());\n}\n\n/**\n * Build content string from the normalized input for pattern detection.\n */\nfunction extractContent(input: NormalizedHookInput): string {\n const parts: string[] = [];\n\n if (input.userPrompt) parts.push(input.userPrompt);\n if (input.aiResponse) parts.push(input.aiResponse);\n if (input.toolResult) parts.push(input.toolResult);\n if (input.commandOutput) parts.push(input.commandOutput);\n if (input.command) parts.push(`Command: ${input.command}`);\n if (input.filePath) parts.push(`File: ${input.filePath}`);\n if (input.edits) {\n for (const edit of input.edits) {\n parts.push(`Edit: ${edit.oldString} → ${edit.newString}`);\n }\n }\n\n return parts.join('\\n').slice(0, MAX_CONTENT_LENGTH);\n}\n\n/**\n * Derive an entity name from the hook input.\n */\nfunction deriveEntityName(input: NormalizedHookInput): string {\n // From file path: extract filename without extension\n if (input.filePath) {\n const parts = input.filePath.replace(/\\\\/g, '/').split('/');\n const filename = parts[parts.length - 1];\n return filename.replace(/\\.[^.]+$/, '');\n }\n\n // From tool name\n if (input.toolName) return input.toolName;\n\n // From command: extract first word\n if (input.command) {\n const firstWord = input.command.split(/\\s+/)[0];\n return firstWord.replace(/[^a-zA-Z0-9-_]/g, '');\n }\n\n return 'session';\n}\n\n/**\n * Generate a concise title from the content and pattern.\n */\nfunction generateTitle(input: NormalizedHookInput, patternType: string): string {\n const maxLen = 60;\n\n if (input.filePath) {\n const filename = input.filePath.replace(/\\\\/g, '/').split('/').pop() ?? '';\n const verb =\n patternType === 'problem-solution'\n ? 'Fixed issue in'\n : patternType === 'what-changed'\n ? 'Changed'\n : 'Updated';\n return `${verb} ${filename}`.slice(0, maxLen);\n }\n\n if (input.command) {\n return `Ran: ${input.command}`.slice(0, maxLen);\n }\n\n if (input.userPrompt) {\n return input.userPrompt.slice(0, maxLen);\n }\n\n return `Session activity (${patternType})`;\n}\n\n/**\n * Build a memorix_store-compatible observation payload.\n */\nfunction buildObservation(input: NormalizedHookInput, content: string) {\n const pattern = detectBestPattern(content);\n const obsType = (pattern ? patternToObservationType(pattern.type) : 'discovery') as ObservationType;\n\n return {\n entityName: deriveEntityName(input),\n type: obsType,\n title: generateTitle(input, obsType),\n narrative: content.slice(0, 2000),\n facts: [\n `Agent: ${input.agent}`,\n `Session: ${input.sessionId}`,\n ...(input.filePath ? [`File: ${input.filePath}`] : []),\n ...(input.command ? [`Command: ${input.command}`] : []),\n ],\n concepts: pattern?.matchedKeywords ?? [],\n filesModified: input.filePath ? [input.filePath] : [],\n };\n}\n\n/**\n * Handle a hook event.\n *\n * Returns:\n * - observation payload if content should be stored (caller persists it)\n * - null if nothing to store\n * - HookOutput for stdout response to agent\n */\nexport async function handleHookEvent(input: NormalizedHookInput): Promise<{\n observation: ReturnType<typeof buildObservation> | null;\n output: HookOutput;\n}> {\n const defaultOutput: HookOutput = { continue: true };\n\n // Skip memorix's own MCP calls to avoid recursion\n if (input.toolName === 'memorix_store' || input.toolName === 'memorix_search') {\n return { observation: null, output: defaultOutput };\n }\n\n // Event-specific handling\n switch (input.event) {\n case 'session_start': {\n // Search relevant memories and inject via systemMessage\n let contextSummary = '';\n try {\n const { detectProject } = await import('../project/detector.js');\n const { getProjectDataDir, loadObservationsJson } = await import('../store/persistence.js');\n\n const project = await detectProject(input.cwd || process.cwd());\n const dataDir = await getProjectDataDir(project.id);\n const allObs = await loadObservationsJson(dataDir) as Array<{\n type?: string;\n title?: string;\n narrative?: string;\n facts?: string[];\n timestamp?: string;\n importance?: number;\n }>;\n\n if (allObs.length > 0) {\n // Priority types: gotcha > decision > problem-solution > trade-off > discovery > others\n const PRIORITY_ORDER: Record<string, number> = {\n 'gotcha': 6,\n 'decision': 5,\n 'problem-solution': 4,\n 'trade-off': 3,\n 'discovery': 2,\n 'how-it-works': 1,\n };\n\n // Filter out low-quality auto-generated observations\n // These are hook-generated template titles that don't carry specific knowledge\n const LOW_QUALITY_PATTERNS = [\n /^Session activity/i,\n /^Updated \\S+\\.\\w+$/i, // \"Updated foo.ts\" — too generic\n /^Created \\S+\\.\\w+$/i, // \"Created bar.js\"\n /^Deleted \\S+\\.\\w+$/i,\n /^Modified \\S+\\.\\w+$/i,\n ];\n const isLowQuality = (title: string) =>\n LOW_QUALITY_PATTERNS.some(p => p.test(title));\n\n // Score: priority × quality × recency\n const scored = allObs\n .map((obs, i) => {\n const title = obs.title ?? '';\n const hasFacts = (obs.facts?.length ?? 0) > 0;\n const hasSubstance = title.length > 20 || hasFacts;\n const quality = isLowQuality(title) ? 0.1 : hasSubstance ? 1.0 : 0.5;\n\n return {\n obs,\n priority: PRIORITY_ORDER[obs.type ?? ''] ?? 0,\n quality,\n recency: i, // higher index = more recent\n };\n })\n .sort((a, b) => {\n // Weighted score: priority × quality first, then recency\n const scoreA = a.priority * a.quality;\n const scoreB = b.priority * b.quality;\n if (scoreB !== scoreA) return scoreB - scoreA;\n return b.recency - a.recency;\n });\n\n // Take top 5 most valuable items, budget ~600 tokens\n const top = scored.slice(0, 5);\n const TYPE_EMOJI: Record<string, string> = {\n 'gotcha': '🔴', 'decision': '🟤', 'problem-solution': '🟡',\n 'trade-off': '⚖️', 'discovery': '🟣', 'how-it-works': '🔵',\n 'what-changed': '🟢', 'why-it-exists': '🟠', 'session-request': '🎯',\n };\n\n const lines = top.map(({ obs }) => {\n const emoji = TYPE_EMOJI[obs.type ?? ''] ?? '📌';\n const title = obs.title ?? '(untitled)';\n // Include first fact if available for extra context\n const fact = obs.facts?.[0] ? ` — ${obs.facts[0]}` : '';\n return `${emoji} ${title}${fact}`;\n });\n\n contextSummary = `\\n\\nRecent project memories (${project.name}):\\n${lines.join('\\n')}`;\n }\n } catch {\n // Silent fail — hooks must never break the agent\n }\n\n return {\n observation: null,\n output: {\n continue: true,\n systemMessage:\n `Memorix is active. Your memories from previous sessions are available via memorix_search.${contextSummary}`,\n },\n };\n }\n\n case 'pre_compact':\n // Context is about to be compressed — save what we can\n return {\n observation: buildObservation(input, extractContent(input)),\n output: defaultOutput,\n };\n\n case 'session_end':\n // Always record session end (no cooldown)\n return {\n observation: buildObservation(input, extractContent(input)),\n output: defaultOutput,\n };\n\n case 'post_edit': {\n // Code edits: lower threshold, always worth recording if pattern matches\n const editKey = `post_edit:${input.filePath ?? 'general'}`;\n if (isInCooldown(editKey)) {\n return { observation: null, output: defaultOutput };\n }\n\n const editContent = extractContent(input);\n if (editContent.length < MIN_EDIT_LENGTH) {\n return { observation: null, output: defaultOutput };\n }\n\n const editPattern = detectBestPattern(editContent, 0.6);\n if (!editPattern) {\n return { observation: null, output: defaultOutput };\n }\n\n markTriggered(editKey);\n return {\n observation: buildObservation(input, editContent),\n output: defaultOutput,\n };\n }\n\n case 'post_command': {\n // Filter noise commands\n if (input.command && NOISE_COMMANDS.some((r) => r.test(input.command!))) {\n return { observation: null, output: defaultOutput };\n }\n\n const cmdKey = `post_command:${input.command ?? 'general'}`;\n if (isInCooldown(cmdKey)) {\n return { observation: null, output: defaultOutput };\n }\n\n // Use commandOutput for pattern detection if available, else command\n const cmdContent = input.commandOutput || extractContent(input);\n if (cmdContent.length < MIN_STORE_LENGTH) {\n return { observation: null, output: defaultOutput };\n }\n\n // Pattern detection — store as discovery if no pattern but content is substantial\n detectBestPattern(cmdContent);\n\n markTriggered(cmdKey);\n return {\n observation: buildObservation(input, cmdContent),\n output: defaultOutput,\n };\n }\n\n case 'post_tool': {\n // Tools: still require pattern (avoid memorix's own tool noise)\n const toolKey = `post_tool:${input.toolName ?? 'general'}`;\n if (isInCooldown(toolKey)) {\n return { observation: null, output: defaultOutput };\n }\n\n const toolContent = extractContent(input);\n if (toolContent.length < MIN_STORE_LENGTH) {\n return { observation: null, output: defaultOutput };\n }\n\n const toolPattern = detectBestPattern(toolContent);\n if (!toolPattern) {\n return { observation: null, output: defaultOutput };\n }\n\n markTriggered(toolKey);\n return {\n observation: buildObservation(input, toolContent),\n output: defaultOutput,\n };\n }\n\n case 'post_response':\n case 'user_prompt': {\n // User prompts & AI responses: store more aggressively (safety net)\n const promptKey = `${input.event}:${input.sessionId ?? 'general'}`;\n if (isInCooldown(promptKey)) {\n return { observation: null, output: defaultOutput };\n }\n\n const content = extractContent(input);\n if (content.length < MIN_STORE_LENGTH) {\n return { observation: null, output: defaultOutput };\n }\n\n // Always store — pattern detection is used for classification only\n detectBestPattern(content);\n\n markTriggered(promptKey);\n return {\n observation: buildObservation(input, content),\n output: defaultOutput,\n };\n }\n\n default:\n return { observation: null, output: defaultOutput };\n }\n}\n\n/**\n * Main entry point: read stdin, process, write stdout.\n * Called by the CLI: `memorix hook`\n */\nexport async function runHook(): Promise<void> {\n // Read stdin\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n const rawInput = Buffer.concat(chunks).toString('utf-8').trim();\n\n if (!rawInput) {\n // No input — output default continue\n process.stdout.write(JSON.stringify({ continue: true }));\n return;\n }\n\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(rawInput);\n } catch {\n process.stdout.write(JSON.stringify({ continue: true }));\n return;\n }\n\n // Normalize\n const input = normalizeHookInput(payload);\n\n // Handle\n const { observation, output } = await handleHookEvent(input);\n\n // Store observation if any\n if (observation) {\n try {\n // Dynamic import to avoid circular deps and keep hook handler lightweight\n const { storeObservation, initObservations } = await import('../memory/observations.js');\n const { detectProject } = await import('../project/detector.js');\n const { getProjectDataDir } = await import('../store/persistence.js');\n\n const project = await detectProject(input.cwd || process.cwd());\n const dataDir = await getProjectDataDir(project.id);\n\n // Initialize observations manager (idempotent if already initialized)\n await initObservations(dataDir);\n\n await storeObservation({ ...observation, projectId: project.id });\n } catch {\n // Silent fail — hooks must never break the agent\n }\n }\n\n // Output response to agent\n process.stdout.write(JSON.stringify(output));\n}\n","/**\n * CLI Command: memorix hook\n *\n * Entry point called by agent hooks via stdin/stdout.\n * Reads agent's JSON from stdin, normalizes, auto-stores, outputs response.\n *\n * Usage (called by agent hook configs, not by users directly):\n * memorix hook\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'hook',\n description: 'Handle agent hook event (called by agent hook configs)',\n },\n run: async () => {\n const { runHook } = await import('../../hooks/handler.js');\n await runHook();\n },\n});\n","/**\n * CLI Command: memorix hooks install\n *\n * Auto-detect installed agents and install hook configurations.\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'install',\n description: 'Install automatic memory hooks for agents',\n },\n args: {\n agent: {\n type: 'string',\n description: 'Target agent (claude|copilot|windsurf|cursor|kiro|codex). Auto-detects if omitted.',\n required: false,\n },\n global: {\n type: 'boolean',\n description: 'Install globally instead of per-project',\n required: false,\n },\n },\n run: async ({ args }) => {\n const { detectInstalledAgents, installHooks } = await import('../../hooks/installers/index.js');\n const cwd = process.cwd();\n\n let agents: string[];\n if (args.agent) {\n agents = [args.agent];\n } else {\n agents = await detectInstalledAgents();\n if (agents.length === 0) {\n console.log('No supported agents detected. Use --agent to specify one.');\n return;\n }\n console.log(`Detected agents: ${agents.join(', ')}`);\n }\n\n for (const agent of agents) {\n try {\n const config = await installHooks(\n agent as import('../../hooks/types.js').AgentName,\n cwd,\n args.global ?? false,\n );\n console.log(`✅ ${agent}: hooks installed → ${config.configPath}`);\n console.log(` Events: ${config.events.join(', ')}`);\n } catch (err) {\n console.error(`❌ ${agent}: failed — ${err}`);\n }\n }\n\n console.log('\\nMemory hooks are now active. Restart your agent to apply.');\n },\n});\n","/**\n * CLI Command: memorix hooks uninstall\n *\n * Remove hook configurations for agents.\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'uninstall',\n description: 'Remove automatic memory hooks for agents',\n },\n args: {\n agent: {\n type: 'string',\n description: 'Target agent (claude|copilot|windsurf|cursor|kiro|codex)',\n required: false,\n },\n global: {\n type: 'boolean',\n description: 'Uninstall global hooks',\n required: false,\n },\n },\n run: async ({ args }) => {\n const { detectInstalledAgents, uninstallHooks } = await import('../../hooks/installers/index.js');\n const cwd = process.cwd();\n\n let agents: string[];\n if (args.agent) {\n agents = [args.agent];\n } else {\n agents = await detectInstalledAgents();\n }\n\n for (const agent of agents) {\n const ok = await uninstallHooks(\n agent as import('../../hooks/types.js').AgentName,\n cwd,\n args.global ?? false,\n );\n if (ok) {\n console.log(`✅ ${agent}: hooks removed`);\n } else {\n console.log(`⚠️ ${agent}: no hooks found`);\n }\n }\n },\n});\n","/**\n * CLI Command: memorix hooks status\n *\n * Show hook installation status for all agents.\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'status',\n description: 'Show hook installation status for all agents',\n },\n run: async () => {\n const { getHookStatus } = await import('../../hooks/installers/index.js');\n const cwd = process.cwd();\n\n const statuses = await getHookStatus(cwd);\n\n console.log('\\nMemorix Hooks Status');\n console.log('═'.repeat(50));\n\n for (const { agent, installed, configPath } of statuses) {\n const icon = installed ? '✅' : '⬚';\n const label = agent.charAt(0).toUpperCase() + agent.slice(1);\n console.log(`${icon} ${label.padEnd(12)} ${installed ? configPath : '(not installed)'}`);\n }\n\n console.log('\\nRun `memorix hooks install` to set up hooks for detected agents.');\n },\n});\n","/**\n * CLI Command: memorix hooks\n *\n * Manage hook installations across agents.\n *\n * Usage:\n * memorix hooks install [--agent <name>] [--global]\n * memorix hooks uninstall [--agent <name>] [--global]\n * memorix hooks status\n */\n\nimport { defineCommand } from 'citty';\n\nexport default defineCommand({\n meta: {\n name: 'hooks',\n description: 'Manage automatic memory hooks for agents',\n },\n subCommands: {\n install: () => import('./hooks-install.js').then((m) => m.default),\n uninstall: () => import('./hooks-uninstall.js').then((m) => m.default),\n status: () => import('./hooks-status.js').then((m) => m.default),\n },\n run() {\n // Default: show help\n },\n});\n","/**\r\n * memorix dashboard — Launch the Memorix Web Dashboard\r\n */\r\n\r\nimport { defineCommand } from 'citty';\r\nimport { fileURLToPath } from 'node:url';\r\nimport path from 'node:path';\r\n\r\nexport default defineCommand({\r\n meta: {\r\n name: 'dashboard',\r\n description: 'Launch the Memorix Web Dashboard',\r\n },\r\n args: {\r\n port: {\r\n type: 'string',\r\n description: 'Port to run the dashboard on (default: 3210)',\r\n default: '3210',\r\n },\r\n },\r\n run: async ({ args }) => {\r\n const { detectProject } = await import('../../project/detector.js');\r\n const { getProjectDataDir } = await import('../../store/persistence.js');\r\n const { startDashboard } = await import('../../dashboard/server.js');\r\n\r\n const project = detectProject();\r\n const dataDir = await getProjectDataDir(project.id);\r\n const port = parseInt(args.port as string, 10) || 3210;\r\n\r\n // Resolve static directory relative to the compiled CLI entry point\r\n // CLI is at dist/cli/index.js → static files are at dist/dashboard/static\r\n const cliDir = path.dirname(fileURLToPath(import.meta.url));\r\n const staticDir = path.join(cliDir, '..', 'dashboard', 'static');\r\n\r\n await startDashboard(dataDir, port, staticDir, project.id, project.name);\r\n\r\n // Keep alive\r\n await new Promise(() => { });\r\n },\r\n});\r\n","/**\r\n * CLI Command: memorix cleanup\r\n *\r\n * Identifies and removes low-quality auto-generated observations.\r\n * Inspired by Mem0's memory consolidation and Graphiti's temporal pruning.\r\n *\r\n * Usage:\r\n * memorix cleanup — Interactive: preview & confirm deletion\r\n * memorix cleanup --dry — Preview only, no deletions\r\n * memorix cleanup --force — Delete without confirmation\r\n */\r\n\r\nimport { defineCommand } from 'citty';\r\nimport { detectProject } from '../../project/detector.js';\r\nimport { getProjectDataDir, loadObservationsJson, saveObservationsJson } from '../../store/persistence.js';\r\n\r\n/** Patterns that indicate auto-generated, low-value observations */\r\nconst LOW_QUALITY_PATTERNS = [\r\n /^Session activity/i,\r\n /^Updated \\S+\\.\\w+$/i,\r\n /^Created \\S+\\.\\w+$/i,\r\n /^Deleted \\S+\\.\\w+$/i,\r\n /^Modified \\S+\\.\\w+$/i,\r\n /^Ran command:/i,\r\n /^Read file:/i,\r\n];\r\n\r\n/** Check if an observation title matches low-quality patterns */\r\nfunction isLowQuality(title: string): boolean {\r\n return LOW_QUALITY_PATTERNS.some(p => p.test(title.trim()));\r\n}\r\n\r\nexport default defineCommand({\r\n meta: {\r\n name: 'cleanup',\r\n description: 'Remove low-quality auto-generated observations',\r\n },\r\n args: {\r\n dry: {\r\n type: 'boolean',\r\n description: 'Preview only — do not delete anything',\r\n default: false,\r\n },\r\n force: {\r\n type: 'boolean',\r\n description: 'Delete without confirmation',\r\n default: false,\r\n },\r\n },\r\n async run({ args }) {\r\n const project = detectProject();\r\n\r\n if (project.id === '__invalid__') {\r\n console.error('❌ Not in a valid project directory.');\r\n process.exit(1);\r\n }\r\n\r\n console.log(`\\n📦 Project: ${project.name} (${project.id})\\n`);\r\n\r\n const dataDir = await getProjectDataDir(project.id);\r\n const allObs = await loadObservationsJson(dataDir) as Array<{\r\n id?: number;\r\n type?: string;\r\n title?: string;\r\n narrative?: string;\r\n entityName?: string;\r\n facts?: string[];\r\n timestamp?: string;\r\n }>;\r\n\r\n if (allObs.length === 0) {\r\n console.log('✅ No observations found — nothing to clean up.');\r\n return;\r\n }\r\n\r\n // Categorize\r\n const lowQuality = allObs.filter(o => isLowQuality(o.title ?? ''));\r\n const highQuality = allObs.filter(o => !isLowQuality(o.title ?? ''));\r\n\r\n // Also find duplicates (same title + type + entity)\r\n const seen = new Set<string>();\r\n const duplicates: typeof allObs = [];\r\n const unique: typeof allObs = [];\r\n for (const obs of highQuality) {\r\n const key = `${obs.type}|${obs.title}|${obs.entityName}`;\r\n if (seen.has(key)) {\r\n duplicates.push(obs);\r\n } else {\r\n seen.add(key);\r\n unique.push(obs);\r\n }\r\n }\r\n\r\n const toRemove = [...lowQuality, ...duplicates];\r\n\r\n console.log(`📊 Analysis:`);\r\n console.log(` Total observations: ${allObs.length}`);\r\n console.log(` 🟢 High quality: ${unique.length}`);\r\n console.log(` 🔴 Low quality: ${lowQuality.length}`);\r\n console.log(` 🟡 Duplicates: ${duplicates.length}`);\r\n console.log(` 🗑️ To remove: ${toRemove.length}`);\r\n console.log();\r\n\r\n if (toRemove.length === 0) {\r\n console.log('✅ All observations are high quality — nothing to clean up!');\r\n return;\r\n }\r\n\r\n // Preview\r\n console.log('🔍 Examples of items to remove:');\r\n toRemove.slice(0, 10).forEach(o => {\r\n const tag = isLowQuality(o.title ?? '') ? '(low-quality)' : '(duplicate)';\r\n console.log(` ${tag} #${o.id ?? '?'} \"${o.title}\" [${o.type}]`);\r\n });\r\n if (toRemove.length > 10) {\r\n console.log(` ... and ${toRemove.length - 10} more`);\r\n }\r\n console.log();\r\n\r\n if (args.dry) {\r\n console.log('🔒 Dry run — no changes made.');\r\n return;\r\n }\r\n\r\n if (!args.force) {\r\n // Simple confirmation via stdin\r\n const readline = await import('node:readline');\r\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\r\n const answer = await new Promise<string>(resolve => {\r\n rl.question(`⚠️ Delete ${toRemove.length} observations? (y/N) `, resolve);\r\n });\r\n rl.close();\r\n\r\n if (answer.trim().toLowerCase() !== 'y') {\r\n console.log('❌ Cancelled.');\r\n return;\r\n }\r\n }\r\n\r\n // Remove\r\n const removeIds = new Set(toRemove.map(o => JSON.stringify(o)));\r\n const remaining = allObs.filter(o => !removeIds.has(JSON.stringify(o)));\r\n\r\n await saveObservationsJson(dataDir, remaining);\r\n\r\n console.log(`✅ Removed ${toRemove.length} observations. ${remaining.length} remaining.`);\r\n },\r\n});\r\n","/**\n * Memorix CLI\n *\n * Command-line interface for Memorix management.\n * Built with: citty (1.1K stars, zero-deps) + @clack/prompts (7.4K stars)\n *\n * Commands:\n * memorix serve — Start MCP Server on stdio\n * memorix status — Show project info + rules sync status\n * memorix sync — Interactive cross-agent rule sync\n */\n\nimport { defineCommand, runMain } from 'citty';\nimport { createRequire } from 'node:module';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../../package.json') as { version: string };\n\n// ============================================================\n// Main command\n// ============================================================\n\nconst main = defineCommand({\n meta: {\n name: 'memorix',\n version: pkg.version,\n description: 'Cross-Agent Memory Bridge — Universal memory layer for AI coding agents via MCP',\n },\n subCommands: {\n serve: () => import('./commands/serve.js').then(m => m.default),\n status: () => import('./commands/status.js').then(m => m.default),\n sync: () => import('./commands/sync.js').then(m => m.default),\n hook: () => import('./commands/hook.js').then(m => m.default),\n hooks: () => import('./commands/hooks.js').then(m => m.default),\n dashboard: () => import('./commands/dashboard.js').then(m => m.default),\n cleanup: () => import('./commands/cleanup.js').then(m => m.default),\n },\n run() {\n // Default: show help (citty handles this automatically)\n },\n});\n\nrunMain(main);\n"],"mappings":"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","names":["path","projectDir","observations","nextId","projectDir","observations","cache","MAX_CACHE_SIZE","FastEmbedProvider","TransformersProvider","p","provider","getObservationCount","count","basename","os","path","id","name","basename","matter","matter","matter","matter","matter","p","matter","fs","path","p","init_windsurf","homedir","join","init_cursor","homedir","join","init_codex","homedir","join","init_claude_code","homedir","join","existsSync","init_copilot","homedir","join","init_antigravity","homedir","join","init_kiro","matter","existsSync","readFileSync","existsSync","mkdirSync","join","homedir","init_engine","init_windsurf","init_cursor","init_codex","init_claude_code","init_copilot","init_antigravity","init_kiro","path","fs","path","os","existsSync","readFileSync","writeFileSync","mkdirSync","readdirSync","join","homedir","init_engine","observations","p","fs","path","observations","nextId","getEmbeddingProvider","isImmune","resolve","server_exports","migrateGlobalData","projectDir","getHookStatus","installHooks","detectInstalledAgents","count","getRetentionSummary","getArchiveCandidates","rankByRelevance","search","observations","lines","SkillsEngine","loadObservationsJson","path","exec","fileURLToPath","startDashboard","resolve","init_server","init_engine","createMemorixServer","execSync","defineCommand","detectProject","RulesSyncer","getProjectDataDir","defineCommand","p","detectProject","RulesSyncer","fs","path","confirm","detectProject","getProjectDataDir","loadObservationsJson","LOW_QUALITY_PATTERNS","isLowQuality","p","storeObservation","initObservations","defineCommand","runHook","defineCommand","detectInstalledAgents","installHooks","defineCommand","detectInstalledAgents","uninstallHooks","defineCommand","getHookStatus","defineCommand","defineCommand","fileURLToPath","path","detectProject","getProjectDataDir","startDashboard","defineCommand","p","resolve","defineCommand","createRequire","require"]}