/** * Memory-Based Skill Engine * * Instead of extracting skills from individual sessions (weak), * this engine discovers skills from ACCUMULATED MEMORY across all sessions. * * Key insight: A skill isn't what happened once — it's what happened * REPEATEDLY across different contexts. If the same approach appears * 3+ times in different sessions, it's a genuine reusable pattern. * * Process: * 1. INGEST — All sessions → atomic observations in nexus memory * 2. CLUSTER — Group similar observations using semantic similarity * 3. FREQUENCY — Patterns that appear 3+ times = skill candidates * 4. ABSTRACT — Extract the common principle from the cluster * 5. BRANCH — If same topic has different approaches, find the condition * 6. VALIDATE — Cross-check: does this skill hold across contexts? * * This leverages our BM25 + semantic + knowledge graph memory engine * to do what raw regex/keyword extraction can't. */ import type { ParsedSession } from "../parser/types.js"; import type { Observation } from "../memory-engine/nexus-memory.js"; /** Extract a project label from either POSIX or Windows session paths. */ export declare function sessionDomainFromPaths(cwd?: string, projectPath?: string): string; /** Knowledge tier: skill (complex), tip (quick), fact (reference). */ export type KnowledgeTier = "skill" | "tip" | "fact"; export type LearnedKnowledge = { id: string; tier: KnowledgeTier; name: string; content: string; domains: string[]; tags: string[]; evidenceCount: number; confidence: number; firstSeen: string; lastSeen: string; }; export type Tip = LearnedKnowledge & { tier: "tip"; /** Quick one-liner advice. */ advice: string; /** When this applies. */ trigger: string; }; export type Fact = LearnedKnowledge & { tier: "fact"; /** The fact itself. */ statement: string; /** How often referenced. */ referenceCount: number; }; export type MemorySkill = { id: string; /** Clear, actionable name. */ name: string; /** When to use this skill. */ situation: string; /** The principle / approach. */ principle: string; /** Why this works (derived from evidence). */ reasoning: string; /** Conditions that change the approach. */ conditions: SkillCondition[]; /** What NOT to do (from contradicting observations). */ antiPatterns: string[]; /** How many observations support this. */ evidenceCount: number; /** Source domains (projects/contexts). */ domains: string[]; /** Tools typically involved. */ tools: string[]; /** Confidence 0-1. */ confidence: number; /** When first/last observed. */ firstSeen: string; lastSeen: string; }; export type SkillCondition = { /** When this condition is true... */ when: string; /** ...use this approach instead. */ approach: string; /** Evidence count for this branch. */ evidence: number; }; export type ObservationCluster = { /** Cluster centroid (representative observation). */ centroid: Observation; /** All observations in this cluster. */ members: Observation[]; /** Common keywords across all members. */ commonKeywords: string[]; /** Common tools. */ commonTools: string[]; /** Unique domains represented. */ domains: Set; /** Average confidence. */ avgConfidence: number; }; export type SkillExtractionResult = { /** Complex skills (cross-session, multi-step). */ skills: MemorySkill[]; /** Quick tips (short, actionable). */ tips: Tip[]; /** Reference facts (frequently recalled). */ facts: Fact[]; /** Observations ingested. */ observationsIngested: number; /** Clusters formed. */ clustersFormed: number; /** Duration in ms. */ durationMs: number; }; /** * Full memory-based skill extraction pipeline. * * 1. Ingest all sessions into nexus memory * 2. Cluster similar observations * 3. Promote clusters with 3+ members to skills */ export declare function extractMemorySkills(sessions: ParsedSession[], dataDir: string, minClusterSize?: number): SkillExtractionResult; export declare function renderMemorySkillMarkdown(skill: MemorySkill): string; /** Render all knowledge (skills + tips + facts) as a single Obsidian page. */ export declare function renderKnowledgeBase(result: SkillExtractionResult): string;