diff --git a/docs/coderabbit-PR-41.md b/docs/coderabbit-PR-41.md new file mode 100644 index 00000000..6412f1e6 --- /dev/null +++ b/docs/coderabbit-PR-41.md @@ -0,0 +1,314 @@ +# CodeRabbit Review - Issue Validation + +**Analysis Date:** 2025-11-03 +**Analyzed By:** Claude (Sonnet 4.5) +**Priority:** 🔴 Critical | 🟡 Medium | 🟢 Low + +--- + +## Issue 1: Chroma Search False Positives + +**Location:** `experiment/chroma-search-test.ts:135-166` +**Priority:** 🟢 Low +**Status:** ✅ CONFIRMED - Real bug, correct fix +**Severity:** Low (experiment file only, not production code) + +### Problem +The code marks `chromaFound = true` if the raw text contains the string `'ids'`, even for empty results like `'ids': [[]]`. + +**Current code (line 137):** +```typescript +testResult.chromaFound = resultText.includes('ids') && resultText.length > 50; +``` + +This creates false positives by checking for string containment rather than validating actual result content. + +### Validation +Confirmed by reading the actual code. The logic uses simple string matching which would match both: +- Real results: `'ids': [['obs_123', 'obs_456']]` ✓ +- Empty results: `'ids': [[]]` ✗ (incorrectly marked as success) + +### Recommended Fix +Parse and validate the actual content of the `ids` and/or `documents` arrays: + +```typescript +// Extract and parse the 'ids' array +const idsMatch = resultText.match(/'ids':\s*\[(.*?)\]/s); +if (idsMatch) { + try { + // Check if there's at least one non-empty inner array + const idsContent = idsMatch[1]; + const hasResults = idsContent.includes('[') && + !idsContent.match(/\[\s*\]/); // Not just empty arrays + testResult.chromaFound = hasResults; + } catch { + testResult.chromaFound = false; + } +} +``` + +### Decision +**DEFER** - This is an experiment file, not production code. The bug doesn't affect actual functionality. Can be fixed as a cleanup task when working in this area. + +--- + +## Issue 2: 90-Day Cutoff Units Mismatch + +**Location:** `src/servers/search-server.ts:374-381` (and 3 other hybrid search handlers) +**Priority:** 🔴 Critical +**Status:** ✅ CONFIRMED - Critical bug, MUST FIX IMMEDIATELY +**Severity:** High (breaks 90-day temporal filtering entirely) + +### Problem +The 90-day cutoff is computed in **seconds** but `created_at_epoch` is stored in **milliseconds**, causing the filter to never exclude anything. + +**Current code (line 374):** +```typescript +const ninetyDaysAgo = Math.floor(Date.now() / 1000) - (90 * 24 * 60 * 60); +// ... +return meta && meta.created_at_epoch > ninetyDaysAgo; +``` + +### Validation +**Database verification:** +```bash +$ sqlite3 ~/.claude-mem/claude-mem.db "SELECT created_at_epoch FROM observations LIMIT 1" +1762212399087 # This is in MILLISECONDS +``` + +**Comparison breakdown:** +- `ninetyDaysAgo` = ~1,754,000,000 (seconds, 10 digits) +- `created_at_epoch` = ~1,762,212,399,087 (milliseconds, 13 digits) + +The millisecond value is **ALWAYS** larger than the second value, so the filter `created_at_epoch > ninetyDaysAgo` **ALWAYS** passes, accepting ALL documents regardless of age. + +### Impact +- 90-day temporal boundary completely non-functional +- Performance degradation (processes all historical data) +- Incorrect search results (includes very old observations) +- Affects 4 handlers: `search_observations`, `search_sessions`, `search_user_prompts`, `get_timeline_by_query` + +### Recommended Fix +Keep milliseconds throughout (remove the `/1000` division): + +**File:** `src/servers/search-server.ts` + +**Find and replace in all 4 hybrid search handlers:** +```typescript +// OLD (WRONG - converts to seconds) +const ninetyDaysAgo = Math.floor(Date.now() / 1000) - (90 * 24 * 60 * 60); + +// NEW (CORRECT - stays in milliseconds) +const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000); +``` + +**Locations to fix:** +1. `search_observations` handler (~line 374) +2. `search_sessions` handler +3. `search_user_prompts` handler +4. `get_timeline_by_query` handler + +### Decision +**FIX IMMEDIATELY** - This is a critical bug that breaks core functionality. + +--- + +## Issue 3: Chroma Collection Name Mismatch + +**Location:** `src/services/sync/ChromaSync.ts:77-81` and `src/servers/search-server.ts:26` +**Priority:** 🟡 Medium +**Status:** ⚠️ CURRENTLY WORKS but architectural risk +**Severity:** Medium (maintainability issue, potential future breakage) + +### Problem +ChromaSync builds collection names as `cm__${project}` (parameterized) while search-server uses a hard-coded `'cm__claude-mem'`, creating maintainability risk. + +**ChromaSync.ts (line 79):** +```typescript +this.collectionName = `cm__${project}`; +``` + +**search-server.ts (line 26):** +```typescript +const COLLECTION_NAME = 'cm__claude-mem'; +``` + +**worker-service.ts (line 94):** +```typescript +this.chromaSync = new ChromaSync('claude-mem'); +``` + +### Validation +**Current state:** WORKS (both resolve to `'cm__claude-mem'`) +**Risk:** If anyone changes the ChromaSync instantiation parameter or creates another instance, collections won't match. + +### Recommended Fix +Create a shared constant in a common config location: + +**New file:** `src/shared/config.ts` +```typescript +export const CHROMA_COLLECTION_NAME = 'cm__claude-mem'; +// OR for dynamic project support: +export function getCollectionName(project: string = 'claude-mem'): string { + return `cm__${project}`; +} +``` + +**Update ChromaSync.ts:** +```typescript +import { CHROMA_COLLECTION_NAME } from '../shared/config'; +// ... +this.collectionName = CHROMA_COLLECTION_NAME; +``` + +**Update search-server.ts:** +```typescript +import { CHROMA_COLLECTION_NAME } from '../shared/config'; +// ... +const COLLECTION_NAME = CHROMA_COLLECTION_NAME; +``` + +### Decision +**RECOMMENDED FIX** - Good architectural improvement, prevents future bugs. Not urgent since it currently works, but should be included in the next refactoring pass. + +--- + +## Issue 4: doc_type Value Mismatch in ChromaSync + +**Location:** `src/services/sync/ChromaSync.ts:523-532` (read) vs lines 240, 429 (write) +**Priority:** 🔴 Critical +**Status:** ✅ CONFIRMED - Critical bug, MUST FIX +**Severity:** High (breaks deduplication, causes duplicate insert failures) + +### Problem +Documents are written with `'session_summary'` and `'user_prompt'` but the deduplication logic looks for `'summary'` and `'prompt'`, causing existing documents to not be detected. + +**Write side (formatSummaryDocs, line 240):** +```typescript +doc_type: 'session_summary', +``` + +**Write side (formatUserPromptDoc, line 429):** +```typescript +doc_type: 'user_prompt', +``` + +**Read side (getExistingChromaIds, lines 526-529):** +```typescript +} else if (meta.doc_type === 'summary') { + summaryIds.add(meta.sqlite_id); +} else if (meta.doc_type === 'prompt') { + promptIds.add(meta.sqlite_id); +} +``` + +### Validation +Confirmed by code inspection. The mismatch causes: +1. `getExistingChromaIds` doesn't find existing summaries/prompts +2. They're not added to the deduplication sets +3. System tries to insert them again +4. Chroma rejects with duplicate ID errors + +### Impact +- Deduplication completely broken for summaries and prompts +- Backfill operations fail (see Issue 5) +- Duplicate insert errors in production +- Observations work fine (they use 'observation' consistently) + +### Recommended Fix +**PREFERRED APPROACH:** Fix the read side (backward compatible with existing Chroma data) + +**File:** `src/services/sync/ChromaSync.ts` +**Lines:** 526-529 + +```typescript +} else if (meta.doc_type === 'session_summary') { // Changed from 'summary' + summaryIds.add(meta.sqlite_id); +} else if (meta.doc_type === 'user_prompt') { // Changed from 'prompt' + promptIds.add(meta.sqlite_id); +} +``` + +**Why this approach:** +- ✅ Backward compatible with existing Chroma data +- ✅ No data migration required +- ✅ Safer than changing write side +- ✅ Works immediately + +**Alternative approach (NOT recommended):** Change write side to use 'summary'/'prompt' +- ❌ Requires Chroma data migration +- ❌ Orphans existing documents +- ❌ Higher risk + +### Decision +**FIX IMMEDIATELY** - Critical bug affecting deduplication. Use the backward-compatible fix (change read side). + +--- + +## Issue 5: doc_type Mismatch Causing Backfill Failures + +**Location:** `src/services/worker-service.ts:120-128` (manifestation of Issue 4) +**Priority:** 🔴 Critical +**Status:** ✅ CONFIRMED - Same root cause as Issue 4 +**Severity:** High (duplicate of Issue 4) + +### Problem +Backfill operations fail because of the doc_type mismatch described in Issue 4. + +### Validation +This is not a separate bug - it's a **symptom** of Issue 4. The backfill process: +1. Queries SQLite for summaries/prompts to sync +2. Calls `getExistingChromaIds` to avoid duplicates +3. Due to doc_type mismatch, existing IDs aren't found +4. Tries to insert documents that already exist +5. Chroma rejects with duplicate ID errors +6. Backfill fails + +### Decision +**AUTOMATICALLY RESOLVED** by fixing Issue 4. Not a separate fix needed. + +--- + +## Summary & Action Plan + +### Critical Issues (Fix Immediately) +1. ✅ **Issue 2** - 90-day units mismatch + - Fix: Change all 4 handlers to use milliseconds + - Impact: Restores temporal filtering functionality + +2. ✅ **Issue 4** - doc_type mismatch + - Fix: Change getExistingChromaIds to use 'session_summary'/'user_prompt' + - Impact: Fixes deduplication and backfill + +3. ✅ **Issue 5** - Automatically resolved by fixing Issue 4 + +### Medium Priority (Include in Next Refactor) +4. ⚠️ **Issue 3** - Collection name consistency + - Fix: Create shared constant + - Impact: Better maintainability, prevents future bugs + +### Low Priority (Defer) +5. 🟢 **Issue 1** - False positives in experiment + - Fix: Parse and validate arrays + - Impact: More accurate test results (experiment only) + +### Files Requiring Changes + +**High Priority:** +- `src/servers/search-server.ts` (Issue 2 - 4 locations) +- `src/services/sync/ChromaSync.ts` (Issue 4 - lines 526-529) + +**Medium Priority:** +- `src/shared/config.ts` (Issue 3 - new file) +- `src/services/sync/ChromaSync.ts` (Issue 3 - import) +- `src/servers/search-server.ts` (Issue 3 - import) + +**Low Priority:** +- `experiment/chroma-search-test.ts` (Issue 1) + +### Testing Recommendations +After fixes: +1. Test 90-day filtering with dates before/after cutoff +2. Run backfill operation to verify deduplication +3. Verify no duplicate ID errors in logs +4. Test hybrid search with temporal boundaries diff --git a/plugin/scripts/search-server.mjs b/plugin/scripts/search-server.mjs index 0f1041c3..12651c97 100755 --- a/plugin/scripts/search-server.mjs +++ b/plugin/scripts/search-server.mjs @@ -1,5 +1,5 @@ #!/usr/bin/env node -import{Server as he}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as _e}from"@modelcontextprotocol/sdk/server/stdio.js";import{Client as fe}from"@modelcontextprotocol/sdk/client/index.js";import{StdioClientTransport as Ee}from"@modelcontextprotocol/sdk/client/stdio.js";import{CallToolRequestSchema as be,ListToolsRequestSchema as ge}from"@modelcontextprotocol/sdk/types.js";import{z as i}from"zod";import{zodToJsonSchema as Te}from"zod-to-json-schema";import{basename as Se}from"path";import pe from"better-sqlite3";import{join as L,dirname as ce,basename as xe}from"path";import{homedir as ee}from"os";import{existsSync as De,mkdirSync as de}from"fs";import{fileURLToPath as le}from"url";function ue(){return typeof __dirname<"u"?__dirname:ce(le(import.meta.url))}var $e=ue(),w=process.env.CLAUDE_MEM_DATA_DIR||L(ee(),".claude-mem"),V=process.env.CLAUDE_CONFIG_DIR||L(ee(),".claude"),ke=L(w,"archives"),Fe=L(w,"logs"),Ue=L(w,"trash"),Me=L(w,"backups"),je=L(w,"settings.json"),X=L(w,"claude-mem.db"),te=L(w,"vector-db"),Be=L(V,"settings.json"),Xe=L(V,"commands"),Pe=L(V,"CLAUDE.md");function P(a){de(a,{recursive:!0})}var G=class{db;constructor(e){e||(P(w),e=X),this.db=new pe(e),this.db.pragma("journal_mode = WAL"),this.ensureFTSTables()}ensureFTSTables(){try{if(this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%_fts'").all().some(s=>s.name==="observations_fts"||s.name==="session_summaries_fts"))return;console.error("[SessionSearch] Creating FTS5 tables..."),this.db.exec(` +import{Server as he}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as _e}from"@modelcontextprotocol/sdk/server/stdio.js";import{Client as fe}from"@modelcontextprotocol/sdk/client/index.js";import{StdioClientTransport as Ee}from"@modelcontextprotocol/sdk/client/stdio.js";import{CallToolRequestSchema as be,ListToolsRequestSchema as ge}from"@modelcontextprotocol/sdk/types.js";import{z as i}from"zod";import{zodToJsonSchema as Te}from"zod-to-json-schema";import{basename as Se}from"path";import pe from"better-sqlite3";import{join as L,dirname as ce,basename as xe}from"path";import{homedir as ee}from"os";import{existsSync as De,mkdirSync as de}from"fs";import{fileURLToPath as le}from"url";function ue(){return typeof __dirname<"u"?__dirname:ce(le(import.meta.url))}var $e=ue(),w=process.env.CLAUDE_MEM_DATA_DIR||L(ee(),".claude-mem"),V=process.env.CLAUDE_CONFIG_DIR||L(ee(),".claude"),ke=L(w,"archives"),Fe=L(w,"logs"),Ue=L(w,"trash"),Me=L(w,"backups"),je=L(w,"settings.json"),X=L(w,"claude-mem.db"),te=L(w,"vector-db"),Be=L(V,"settings.json"),Xe=L(V,"commands"),Pe=L(V,"CLAUDE.md");function P(c){de(c,{recursive:!0})}var G=class{db;constructor(e){e||(P(w),e=X),this.db=new pe(e),this.db.pragma("journal_mode = WAL"),this.ensureFTSTables()}ensureFTSTables(){try{if(this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%_fts'").all().some(s=>s.name==="observations_fts"||s.name==="session_summaries_fts"))return;console.error("[SessionSearch] Creating FTS5 tables..."),this.db.exec(` CREATE VIRTUAL TABLE IF NOT EXISTS observations_fts USING fts5( title, subtitle, @@ -63,10 +63,10 @@ import{Server as he}from"@modelcontextprotocol/sdk/server/index.js";import{Stdio INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes) VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes); END; - `),console.error("[SessionSearch] FTS5 tables created successfully")}catch(e){console.error("[SessionSearch] FTS migration error:",e.message)}}escapeFTS5(e){return`"${e.replace(/"/g,'""')}"`}buildFilterClause(e,r,s="o"){let t=[];if(e.project&&(t.push(`${s}.project = ?`),r.push(e.project)),e.type)if(Array.isArray(e.type)){let o=e.type.map(()=>"?").join(",");t.push(`${s}.type IN (${o})`),r.push(...e.type)}else t.push(`${s}.type = ?`),r.push(e.type);if(e.dateRange){let{start:o,end:n}=e.dateRange;if(o){let c=typeof o=="number"?o:new Date(o).getTime();t.push(`${s}.created_at_epoch >= ?`),r.push(c)}if(n){let c=typeof n=="number"?n:new Date(n).getTime();t.push(`${s}.created_at_epoch <= ?`),r.push(c)}}if(e.concepts){let o=Array.isArray(e.concepts)?e.concepts:[e.concepts],n=o.map(()=>`EXISTS (SELECT 1 FROM json_each(${s}.concepts) WHERE value = ?)`);n.length>0&&(t.push(`(${n.join(" OR ")})`),r.push(...o))}if(e.files){let o=Array.isArray(e.files)?e.files:[e.files],n=o.map(()=>`( + `),console.error("[SessionSearch] FTS5 tables created successfully")}catch(e){console.error("[SessionSearch] FTS migration error:",e.message)}}escapeFTS5(e){return`"${e.replace(/"/g,'""')}"`}buildFilterClause(e,r,s="o"){let t=[];if(e.project&&(t.push(`${s}.project = ?`),r.push(e.project)),e.type)if(Array.isArray(e.type)){let o=e.type.map(()=>"?").join(",");t.push(`${s}.type IN (${o})`),r.push(...e.type)}else t.push(`${s}.type = ?`),r.push(e.type);if(e.dateRange){let{start:o,end:n}=e.dateRange;if(o){let a=typeof o=="number"?o:new Date(o).getTime();t.push(`${s}.created_at_epoch >= ?`),r.push(a)}if(n){let a=typeof n=="number"?n:new Date(n).getTime();t.push(`${s}.created_at_epoch <= ?`),r.push(a)}}if(e.concepts){let o=Array.isArray(e.concepts)?e.concepts:[e.concepts],n=o.map(()=>`EXISTS (SELECT 1 FROM json_each(${s}.concepts) WHERE value = ?)`);n.length>0&&(t.push(`(${n.join(" OR ")})`),r.push(...o))}if(e.files){let o=Array.isArray(e.files)?e.files:[e.files],n=o.map(()=>`( EXISTS (SELECT 1 FROM json_each(${s}.files_read) WHERE value LIKE ?) OR EXISTS (SELECT 1 FROM json_each(${s}.files_modified) WHERE value LIKE ?) - )`);n.length>0&&(t.push(`(${n.join(" OR ")})`),o.forEach(c=>{r.push(`%${c}%`,`%${c}%`)}))}return t.length>0?t.join(" AND "):""}buildOrderClause(e="relevance",r=!0,s="observations_fts"){switch(e){case"relevance":return r?`ORDER BY ${s}.rank ASC`:"ORDER BY o.created_at_epoch DESC";case"date_desc":return"ORDER BY o.created_at_epoch DESC";case"date_asc":return"ORDER BY o.created_at_epoch ASC";default:return"ORDER BY o.created_at_epoch DESC"}}searchObservations(e,r={}){let s=[],{limit:t=50,offset:o=0,orderBy:n="relevance",...c}=r,d=this.escapeFTS5(e);s.push(d);let l=this.buildFilterClause(c,s,"o"),u=l?`AND ${l}`:"",p=this.buildOrderClause(n,!0),m=` + )`);n.length>0&&(t.push(`(${n.join(" OR ")})`),o.forEach(a=>{r.push(`%${a}%`,`%${a}%`)}))}return t.length>0?t.join(" AND "):""}buildOrderClause(e="relevance",r=!0,s="observations_fts"){switch(e){case"relevance":return r?`ORDER BY ${s}.rank ASC`:"ORDER BY o.created_at_epoch DESC";case"date_desc":return"ORDER BY o.created_at_epoch DESC";case"date_asc":return"ORDER BY o.created_at_epoch ASC";default:return"ORDER BY o.created_at_epoch DESC"}}searchObservations(e,r={}){let s=[],{limit:t=50,offset:o=0,orderBy:n="relevance",...a}=r,d=this.escapeFTS5(e);s.push(d);let l=this.buildFilterClause(a,s,"o"),u=l?`AND ${l}`:"",p=this.buildOrderClause(n,!0),m=` SELECT o.*, observations_fts.rank as rank @@ -76,7 +76,7 @@ import{Server as he}from"@modelcontextprotocol/sdk/server/index.js";import{Stdio ${u} ${p} LIMIT ? OFFSET ? - `;s.push(t,o);let f=this.db.prepare(m).all(...s);if(f.length>0){let h=Math.min(...f.map(E=>E.rank||0)),_=Math.max(...f.map(E=>E.rank||0))-h||1;f.forEach(E=>{E.rank!==void 0&&(E.score=1-(E.rank-h)/_)})}return f}searchSessions(e,r={}){let s=[],{limit:t=50,offset:o=0,orderBy:n="relevance",...c}=r,d=this.escapeFTS5(e);s.push(d);let l={...c};delete l.type;let u=this.buildFilterClause(l,s,"s"),h=` + `;s.push(t,o);let f=this.db.prepare(m).all(...s);if(f.length>0){let h=Math.min(...f.map(E=>E.rank||0)),_=Math.max(...f.map(E=>E.rank||0))-h||1;f.forEach(E=>{E.rank!==void 0&&(E.score=1-(E.rank-h)/_)})}return f}searchSessions(e,r={}){let s=[],{limit:t=50,offset:o=0,orderBy:n="relevance",...a}=r,d=this.escapeFTS5(e);s.push(d);let l={...a};delete l.type;let u=this.buildFilterClause(l,s,"s"),h=` SELECT s.*, session_summaries_fts.rank as rank @@ -86,19 +86,19 @@ import{Server as he}from"@modelcontextprotocol/sdk/server/index.js";import{Stdio ${(u?`AND ${u}`:"").replace(/files_read/g,"files_read").replace(/files_modified/g,"files_edited")} ${n==="relevance"?"ORDER BY session_summaries_fts.rank ASC":n==="date_asc"?"ORDER BY s.created_at_epoch ASC":"ORDER BY s.created_at_epoch DESC"} LIMIT ? OFFSET ? - `;s.push(t,o);let b=this.db.prepare(h).all(...s);if(b.length>0){let _=Math.min(...b.map(T=>T.rank||0)),x=Math.max(...b.map(T=>T.rank||0))-_||1;b.forEach(T=>{T.rank!==void 0&&(T.score=1-(T.rank-_)/x)})}return b}findByConcept(e,r={}){let s=[],{limit:t=50,offset:o=0,orderBy:n="date_desc",...c}=r,d={...c,concepts:e},l=this.buildFilterClause(d,s,"o"),u=this.buildOrderClause(n,!1),p=` + `;s.push(t,o);let b=this.db.prepare(h).all(...s);if(b.length>0){let _=Math.min(...b.map(T=>T.rank||0)),x=Math.max(...b.map(T=>T.rank||0))-_||1;b.forEach(T=>{T.rank!==void 0&&(T.score=1-(T.rank-_)/x)})}return b}findByConcept(e,r={}){let s=[],{limit:t=50,offset:o=0,orderBy:n="date_desc",...a}=r,d={...a,concepts:e},l=this.buildFilterClause(d,s,"o"),u=this.buildOrderClause(n,!1),p=` SELECT o.* FROM observations o WHERE ${l} ${u} LIMIT ? OFFSET ? - `;return s.push(t,o),this.db.prepare(p).all(...s)}findByFile(e,r={}){let s=[],{limit:t=50,offset:o=0,orderBy:n="date_desc",...c}=r,d={...c,files:e},l=this.buildFilterClause(d,s,"o"),u=this.buildOrderClause(n,!1),p=` + `;return s.push(t,o),this.db.prepare(p).all(...s)}findByFile(e,r={}){let s=[],{limit:t=50,offset:o=0,orderBy:n="date_desc",...a}=r,d={...a,files:e},l=this.buildFilterClause(d,s,"o"),u=this.buildOrderClause(n,!1),p=` SELECT o.* FROM observations o WHERE ${l} ${u} LIMIT ? OFFSET ? - `;s.push(t,o);let m=this.db.prepare(p).all(...s),f=[],h={...c};delete h.type;let b=[];if(h.project&&(b.push("s.project = ?"),f.push(h.project)),h.dateRange){let{start:x,end:T}=h.dateRange;if(x){let g=typeof x=="number"?x:new Date(x).getTime();b.push("s.created_at_epoch >= ?"),f.push(g)}if(T){let g=typeof T=="number"?T:new Date(T).getTime();b.push("s.created_at_epoch <= ?"),f.push(g)}}b.push(`( + `;s.push(t,o);let m=this.db.prepare(p).all(...s),f=[],h={...a};delete h.type;let b=[];if(h.project&&(b.push("s.project = ?"),f.push(h.project)),h.dateRange){let{start:x,end:T}=h.dateRange;if(x){let g=typeof x=="number"?x:new Date(x).getTime();b.push("s.created_at_epoch >= ?"),f.push(g)}if(T){let g=typeof T=="number"?T:new Date(T).getTime();b.push("s.created_at_epoch <= ?"),f.push(g)}}b.push(`( EXISTS (SELECT 1 FROM json_each(s.files_read) WHERE value LIKE ?) OR EXISTS (SELECT 1 FROM json_each(s.files_edited) WHERE value LIKE ?) )`),f.push(`%${e}%`,`%${e}%`);let _=` @@ -107,13 +107,13 @@ import{Server as he}from"@modelcontextprotocol/sdk/server/index.js";import{Stdio WHERE ${b.join(" AND ")} ORDER BY s.created_at_epoch DESC LIMIT ? OFFSET ? - `;f.push(t,o);let E=this.db.prepare(_).all(...f);return{observations:m,sessions:E}}findByType(e,r={}){let s=[],{limit:t=50,offset:o=0,orderBy:n="date_desc",...c}=r,d={...c,type:e},l=this.buildFilterClause(d,s,"o"),u=this.buildOrderClause(n,!1),p=` + `;f.push(t,o);let E=this.db.prepare(_).all(...f);return{observations:m,sessions:E}}findByType(e,r={}){let s=[],{limit:t=50,offset:o=0,orderBy:n="date_desc",...a}=r,d={...a,type:e},l=this.buildFilterClause(d,s,"o"),u=this.buildOrderClause(n,!1),p=` SELECT o.* FROM observations o WHERE ${l} ${u} LIMIT ? OFFSET ? - `;return s.push(t,o),this.db.prepare(p).all(...s)}searchUserPrompts(e,r={}){let s=[],{limit:t=20,offset:o=0,orderBy:n="relevance",...c}=r,d=this.escapeFTS5(e);s.push(d);let l=[];if(c.project&&(l.push("s.project = ?"),s.push(c.project)),c.dateRange){let{start:h,end:b}=c.dateRange;if(h){let _=typeof h=="number"?h:new Date(h).getTime();l.push("up.created_at_epoch >= ?"),s.push(_)}if(b){let _=typeof b=="number"?b:new Date(b).getTime();l.push("up.created_at_epoch <= ?"),s.push(_)}}let m=` + `;return s.push(t,o),this.db.prepare(p).all(...s)}searchUserPrompts(e,r={}){let s=[],{limit:t=20,offset:o=0,orderBy:n="relevance",...a}=r,d=this.escapeFTS5(e);s.push(d);let l=[];if(a.project&&(l.push("s.project = ?"),s.push(a.project)),a.dateRange){let{start:h,end:b}=a.dateRange;if(h){let _=typeof h=="number"?h:new Date(h).getTime();l.push("up.created_at_epoch >= ?"),s.push(_)}if(b){let _=typeof b=="number"?b:new Date(b).getTime();l.push("up.created_at_epoch <= ?"),s.push(_)}}let m=` SELECT up.*, user_prompts_fts.rank as rank @@ -136,8 +136,8 @@ import{Server as he}from"@modelcontextprotocol/sdk/server/index.js";import{Stdio WHERE claude_session_id = ? ORDER BY prompt_number ASC `).all(e)}close(){this.db.close()}};import me from"better-sqlite3";var K=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(K||{}),Q=class{level;useColor;constructor(){let e=process.env.CLAUDE_MEM_LOG_LEVEL?.toUpperCase()||"INFO";this.level=K[e]??1,this.useColor=process.stdout.isTTY??!1}correlationId(e,r){return`obs-${e}-${r}`}sessionId(e){return`session-${e}`}formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return e.toString();if(typeof e=="object"){if(e instanceof Error)return this.level===0?`${e.message} -${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Object.keys(e);return r.length===0?"{}":r.length<=3?JSON.stringify(e):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(e)}formatTool(e,r){if(!r)return e;try{let s=typeof r=="string"?JSON.parse(r):r;if(e==="Bash"&&s.command){let t=s.command.length>50?s.command.substring(0,50)+"...":s.command;return`${e}(${t})`}if(e==="Read"&&s.file_path){let t=s.file_path.split("/").pop()||s.file_path;return`${e}(${t})`}if(e==="Edit"&&s.file_path){let t=s.file_path.split("/").pop()||s.file_path;return`${e}(${t})`}if(e==="Write"&&s.file_path){let t=s.file_path.split("/").pop()||s.file_path;return`${e}(${t})`}return e}catch{return e}}log(e,r,s,t,o){if(e0&&(p=` {${Object.entries(_).map(([x,T])=>`${x}=${T}`).join(", ")}}`)}let m=`[${n}] [${c}] [${d}] ${l}${s}${p}${u}`;e===3?console.error(m):console.log(m)}debug(e,r,s,t){this.log(0,e,r,s,t)}info(e,r,s,t){this.log(1,e,r,s,t)}warn(e,r,s,t){this.log(2,e,r,s,t)}error(e,r,s,t){this.log(3,e,r,s,t)}dataIn(e,r,s,t){this.info(e,`\u2192 ${r}`,s,t)}dataOut(e,r,s,t){this.info(e,`\u2190 ${r}`,s,t)}success(e,r,s,t){this.info(e,`\u2713 ${r}`,s,t)}failure(e,r,s,t){this.error(e,`\u2717 ${r}`,s,t)}timing(e,r,s,t){this.info(e,`\u23F1 ${r}`,t,{duration:`${s}ms`})}},se=new Q;var H=class{db;constructor(){P(w),this.db=new me(X),this.db.pragma("journal_mode = WAL"),this.db.pragma("synchronous = NORMAL"),this.db.pragma("foreign_keys = ON"),this.initializeSchema(),this.ensureWorkerPortColumn(),this.ensurePromptTrackingColumns(),this.removeSessionSummariesUniqueConstraint(),this.addObservationHierarchicalFields(),this.makeObservationsTextNullable(),this.createUserPromptsTable()}initializeSchema(){try{this.db.exec(` +${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Object.keys(e);return r.length===0?"{}":r.length<=3?JSON.stringify(e):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(e)}formatTool(e,r){if(!r)return e;try{let s=typeof r=="string"?JSON.parse(r):r;if(e==="Bash"&&s.command){let t=s.command.length>50?s.command.substring(0,50)+"...":s.command;return`${e}(${t})`}if(e==="Read"&&s.file_path){let t=s.file_path.split("/").pop()||s.file_path;return`${e}(${t})`}if(e==="Edit"&&s.file_path){let t=s.file_path.split("/").pop()||s.file_path;return`${e}(${t})`}if(e==="Write"&&s.file_path){let t=s.file_path.split("/").pop()||s.file_path;return`${e}(${t})`}return e}catch{return e}}log(e,r,s,t,o){if(e0&&(p=` {${Object.entries(_).map(([x,T])=>`${x}=${T}`).join(", ")}}`)}let m=`[${n}] [${a}] [${d}] ${l}${s}${p}${u}`;e===3?console.error(m):console.log(m)}debug(e,r,s,t){this.log(0,e,r,s,t)}info(e,r,s,t){this.log(1,e,r,s,t)}warn(e,r,s,t){this.log(2,e,r,s,t)}error(e,r,s,t){this.log(3,e,r,s,t)}dataIn(e,r,s,t){this.info(e,`\u2192 ${r}`,s,t)}dataOut(e,r,s,t){this.info(e,`\u2190 ${r}`,s,t)}success(e,r,s,t){this.info(e,`\u2713 ${r}`,s,t)}failure(e,r,s,t){this.error(e,`\u2717 ${r}`,s,t)}timing(e,r,s,t){this.info(e,`\u23F1 ${r}`,t,{duration:`${s}ms`})}},se=new Q;var H=class{db;constructor(){P(w),this.db=new me(X),this.db.pragma("journal_mode = WAL"),this.db.pragma("synchronous = NORMAL"),this.db.pragma("foreign_keys = ON"),this.initializeSchema(),this.ensureWorkerPortColumn(),this.ensurePromptTrackingColumns(),this.removeSessionSummariesUniqueConstraint(),this.addObservationHierarchicalFields(),this.makeObservationsTextNullable(),this.createUserPromptsTable()}initializeSchema(){try{this.db.exec(` CREATE TABLE IF NOT EXISTS schema_versions ( id INTEGER PRIMARY KEY, version INTEGER UNIQUE NOT NULL, @@ -350,10 +350,10 @@ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Obje SELECT * FROM observations WHERE id = ? - `).get(e)||null}getObservationsByIds(e,r={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:t}=r,o=s==="date_asc"?"ASC":"DESC",n=t?`LIMIT ${t}`:"",c=e.map(()=>"?").join(",");return this.db.prepare(` + `).get(e)||null}getObservationsByIds(e,r={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:t}=r,o=s==="date_asc"?"ASC":"DESC",n=t?`LIMIT ${t}`:"",a=e.map(()=>"?").join(",");return this.db.prepare(` SELECT * FROM observations - WHERE id IN (${c}) + WHERE id IN (${a}) ORDER BY created_at_epoch ${o} ${n} `).all(...e)}getSummaryForSession(e){return this.db.prepare(` @@ -368,7 +368,7 @@ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Obje SELECT files_read, files_modified FROM observations WHERE sdk_session_id = ? - `).all(e),t=new Set,o=new Set;for(let n of s){if(n.files_read)try{let c=JSON.parse(n.files_read);Array.isArray(c)&&c.forEach(d=>t.add(d))}catch{}if(n.files_modified)try{let c=JSON.parse(n.files_modified);Array.isArray(c)&&c.forEach(d=>o.add(d))}catch{}}return{filesRead:Array.from(t),filesModified:Array.from(o)}}getSessionById(e){return this.db.prepare(` + `).all(e),t=new Set,o=new Set;for(let n of s){if(n.files_read)try{let a=JSON.parse(n.files_read);Array.isArray(a)&&a.forEach(d=>t.add(d))}catch{}if(n.files_modified)try{let a=JSON.parse(n.files_modified);Array.isArray(a)&&a.forEach(d=>o.add(d))}catch{}}return{filesRead:Array.from(t),filesModified:Array.from(o)}}getSessionById(e){return this.db.prepare(` SELECT id, claude_session_id, sdk_session_id, project, user_prompt FROM sdk_sessions WHERE id = ? @@ -395,13 +395,13 @@ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Obje SELECT prompt_counter FROM sdk_sessions WHERE id = ? `).get(e)?.prompt_counter||1}getPromptCounter(e){return this.db.prepare(` SELECT prompt_counter FROM sdk_sessions WHERE id = ? - `).get(e)?.prompt_counter||0}createSDKSession(e,r,s){let t=new Date,o=t.getTime(),c=this.db.prepare(` + `).get(e)?.prompt_counter||0}createSDKSession(e,r,s){let t=new Date,o=t.getTime(),a=this.db.prepare(` INSERT OR IGNORE INTO sdk_sessions (claude_session_id, sdk_session_id, project, user_prompt, started_at, started_at_epoch, status) VALUES (?, ?, ?, ?, ?, ?, 'active') - `).run(e,e,r,s,t.toISOString(),o);return c.lastInsertRowid===0||c.changes===0?this.db.prepare(` + `).run(e,e,r,s,t.toISOString(),o);return a.lastInsertRowid===0||a.changes===0?this.db.prepare(` SELECT id FROM sdk_sessions WHERE claude_session_id = ? LIMIT 1 - `).get(e).id:c.lastInsertRowid}updateSDKSessionId(e,r){return this.db.prepare(` + `).get(e).id:a.lastInsertRowid}updateSDKSessionId(e,r){return this.db.prepare(` UPDATE sdk_sessions SET sdk_session_id = ? WHERE id = ? AND sdk_session_id IS NULL @@ -452,22 +452,22 @@ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Obje UPDATE sdk_sessions SET status = 'failed', completed_at = ?, completed_at_epoch = ? WHERE status = 'active' - `).run(e.toISOString(),r).changes}getSessionSummariesByIds(e,r={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:t}=r,o=s==="date_asc"?"ASC":"DESC",n=t?`LIMIT ${t}`:"",c=e.map(()=>"?").join(",");return this.db.prepare(` + `).run(e.toISOString(),r).changes}getSessionSummariesByIds(e,r={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:t}=r,o=s==="date_asc"?"ASC":"DESC",n=t?`LIMIT ${t}`:"",a=e.map(()=>"?").join(",");return this.db.prepare(` SELECT * FROM session_summaries - WHERE id IN (${c}) + WHERE id IN (${a}) ORDER BY created_at_epoch ${o} ${n} - `).all(...e)}getUserPromptsByIds(e,r={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:t}=r,o=s==="date_asc"?"ASC":"DESC",n=t?`LIMIT ${t}`:"",c=e.map(()=>"?").join(",");return this.db.prepare(` + `).all(...e)}getUserPromptsByIds(e,r={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:t}=r,o=s==="date_asc"?"ASC":"DESC",n=t?`LIMIT ${t}`:"",a=e.map(()=>"?").join(",");return this.db.prepare(` SELECT up.*, s.project, s.sdk_session_id FROM user_prompts up JOIN sdk_sessions s ON up.claude_session_id = s.claude_session_id - WHERE up.id IN (${c}) + WHERE up.id IN (${a}) ORDER BY up.created_at_epoch ${o} ${n} - `).all(...e)}getTimelineAroundTimestamp(e,r=10,s=10,t){return this.getTimelineAroundObservation(null,e,r,s,t)}getTimelineAroundObservation(e,r,s=10,t=10,o){let n=o?"AND project = ?":"",c=o?[o]:[],d,l;if(e!==null){let f=` + `).all(...e)}getTimelineAroundTimestamp(e,r=10,s=10,t){return this.getTimelineAroundObservation(null,e,r,s,t)}getTimelineAroundObservation(e,r,s=10,t=10,o){let n=o?"AND project = ?":"",a=o?[o]:[],d,l;if(e!==null){let f=` SELECT id, created_at_epoch FROM observations WHERE id <= ? ${n} @@ -479,7 +479,7 @@ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Obje WHERE id >= ? ${n} ORDER BY id ASC LIMIT ? - `;try{let b=this.db.prepare(f).all(e,...c,s+1),_=this.db.prepare(h).all(e,...c,t+1);if(b.length===0&&_.length===0)return{observations:[],sessions:[],prompts:[]};d=b.length>0?b[b.length-1].created_at_epoch:r,l=_.length>0?_[_.length-1].created_at_epoch:r}catch(b){return console.error("[SessionStore] Error getting boundary observations:",b.message),{observations:[],sessions:[],prompts:[]}}}else{let f=` + `;try{let b=this.db.prepare(f).all(e,...a,s+1),_=this.db.prepare(h).all(e,...a,t+1);if(b.length===0&&_.length===0)return{observations:[],sessions:[],prompts:[]};d=b.length>0?b[b.length-1].created_at_epoch:r,l=_.length>0?_[_.length-1].created_at_epoch:r}catch(b){return console.error("[SessionStore] Error getting boundary observations:",b.message),{observations:[],sessions:[],prompts:[]}}}else{let f=` SELECT created_at_epoch FROM observations WHERE created_at_epoch <= ? ${n} @@ -491,7 +491,7 @@ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Obje WHERE created_at_epoch >= ? ${n} ORDER BY created_at_epoch ASC LIMIT ? - `;try{let b=this.db.prepare(f).all(r,...c,s),_=this.db.prepare(h).all(r,...c,t+1);if(b.length===0&&_.length===0)return{observations:[],sessions:[],prompts:[]};d=b.length>0?b[b.length-1].created_at_epoch:r,l=_.length>0?_[_.length-1].created_at_epoch:r}catch(b){return console.error("[SessionStore] Error getting boundary timestamps:",b.message),{observations:[],sessions:[],prompts:[]}}}let u=` + `;try{let b=this.db.prepare(f).all(r,...a,s),_=this.db.prepare(h).all(r,...a,t+1);if(b.length===0&&_.length===0)return{observations:[],sessions:[],prompts:[]};d=b.length>0?b[b.length-1].created_at_epoch:r,l=_.length>0?_[_.length-1].created_at_epoch:r}catch(b){return console.error("[SessionStore] Error getting boundary timestamps:",b.message),{observations:[],sessions:[],prompts:[]}}}let u=` SELECT * FROM observations WHERE created_at_epoch >= ? AND created_at_epoch <= ? ${n} @@ -507,7 +507,7 @@ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Obje JOIN sdk_sessions s ON up.claude_session_id = s.claude_session_id WHERE up.created_at_epoch >= ? AND up.created_at_epoch <= ? ${n.replace("project","s.project")} ORDER BY up.created_at_epoch ASC - `;try{let f=this.db.prepare(u).all(d,l,...c),h=this.db.prepare(p).all(d,l,...c),b=this.db.prepare(m).all(d,l,...c);return{observations:f,sessions:h.map(_=>({id:_.id,sdk_session_id:_.sdk_session_id,project:_.project,request:_.request,completed:_.completed,next_steps:_.next_steps,created_at:_.created_at,created_at_epoch:_.created_at_epoch})),prompts:b.map(_=>({id:_.id,claude_session_id:_.claude_session_id,project:_.project,prompt:_.prompt_text,created_at:_.created_at,created_at_epoch:_.created_at_epoch}))}}catch(f){return console.error("[SessionStore] Error querying timeline records:",f.message),{observations:[],sessions:[],prompts:[]}}}close(){this.db.close()}};var $,N,k=null,ye="cm__claude-mem";try{$=new G,N=new H}catch(a){console.error("[search-server] Failed to initialize search:",a.message),process.exit(1)}async function M(a,e,r){if(!k)throw new Error("Chroma client not initialized");let t=(await k.callTool({name:"chroma_query_documents",arguments:{collection_name:ye,query_texts:[a],n_results:e,include:["documents","metadatas","distances"],where:r}})).content[0]?.text||"",o;try{o=JSON.parse(t)}catch(u){return console.error("[search-server] Failed to parse Chroma response as JSON:",u),{ids:[],distances:[],metadatas:[]}}let n=[],c=o.ids?.[0]||[];for(let u of c){let p=u.match(/obs_(\d+)_/),m=u.match(/summary_(\d+)_/),f=u.match(/prompt_(\d+)/),h=null;p?h=parseInt(p[1],10):m?h=parseInt(m[1],10):f&&(h=parseInt(f[1],10)),h!==null&&!n.includes(h)&&n.push(h)}let d=o.distances?.[0]||[],l=o.metadatas?.[0]||[];return{ids:n,distances:d,metadatas:l}}function j(){return` + `;try{let f=this.db.prepare(u).all(d,l,...a),h=this.db.prepare(p).all(d,l,...a),b=this.db.prepare(m).all(d,l,...a);return{observations:f,sessions:h.map(_=>({id:_.id,sdk_session_id:_.sdk_session_id,project:_.project,request:_.request,completed:_.completed,next_steps:_.next_steps,created_at:_.created_at,created_at_epoch:_.created_at_epoch})),prompts:b.map(_=>({id:_.id,claude_session_id:_.claude_session_id,project:_.project,prompt:_.prompt_text,created_at:_.created_at,created_at_epoch:_.created_at_epoch}))}}catch(f){return console.error("[SessionStore] Error querying timeline records:",f.message),{observations:[],sessions:[],prompts:[]}}}close(){this.db.close()}};var $,N,k=null,ye="cm__claude-mem";try{$=new G,N=new H}catch(c){console.error("[search-server] Failed to initialize search:",c.message),process.exit(1)}async function M(c,e,r){if(!k)throw new Error("Chroma client not initialized");let t=(await k.callTool({name:"chroma_query_documents",arguments:{collection_name:ye,query_texts:[c],n_results:e,include:["documents","metadatas","distances"],where:r}})).content[0]?.text||"",o;try{o=JSON.parse(t)}catch(u){return console.error("[search-server] Failed to parse Chroma response as JSON:",u),{ids:[],distances:[],metadatas:[]}}let n=[],a=o.ids?.[0]||[];for(let u of a){let p=u.match(/obs_(\d+)_/),m=u.match(/summary_(\d+)_/),f=u.match(/prompt_(\d+)/),h=null;p?h=parseInt(p[1],10):m?h=parseInt(m[1],10):f&&(h=parseInt(f[1],10)),h!==null&&!n.includes(h)&&n.push(h)}let d=o.distances?.[0]||[],l=o.metadatas?.[0]||[];return{ids:n,distances:d,metadatas:l}}function j(){return` --- \u{1F4A1} Search Strategy: ALWAYS search with index format FIRST to get an overview and identify relevant results. @@ -522,67 +522,67 @@ Search workflow: Other tips: \u2022 To search by concept: Use find_by_concept tool \u2022 To browse by type: Use find_by_type with ["decision", "feature", etc.] -\u2022 To sort by date: Use orderBy: "date_desc" or "date_asc"`}function q(a,e){let r=a.title||`Observation #${a.id}`,s=new Date(a.created_at_epoch).toLocaleString(),t=a.type?`[${a.type}]`:"";return`${e+1}. ${t} ${r} +\u2022 To sort by date: Use orderBy: "date_desc" or "date_asc"`}function q(c,e){let r=c.title||`Observation #${c.id}`,s=new Date(c.created_at_epoch).toLocaleString(),t=c.type?`[${c.type}]`:"";return`${e+1}. ${t} ${r} Date: ${s} - Source: claude-mem://observation/${a.id}`}function re(a,e){let r=a.request||`Session ${a.sdk_session_id.substring(0,8)}`,s=new Date(a.created_at_epoch).toLocaleString();return`${e+1}. ${r} + Source: claude-mem://observation/${c.id}`}function re(c,e){let r=c.request||`Session ${c.sdk_session_id.substring(0,8)}`,s=new Date(c.created_at_epoch).toLocaleString();return`${e+1}. ${r} Date: ${s} - Source: claude-mem://session/${a.sdk_session_id}`}function W(a,e){let r=a.title||`Observation #${a.id}`,s=[];s.push(`## ${r}`),s.push(`*Source: claude-mem://observation/${a.id}*`),s.push(""),a.subtitle&&(s.push(`**${a.subtitle}**`),s.push("")),a.narrative&&(s.push(a.narrative),s.push("")),a.text&&(s.push(a.text),s.push(""));let t=[];if(t.push(`Type: ${a.type}`),a.facts)try{let n=JSON.parse(a.facts);n.length>0&&t.push(`Facts: ${n.join("; ")}`)}catch{}if(a.concepts)try{let n=JSON.parse(a.concepts);n.length>0&&t.push(`Concepts: ${n.join(", ")}`)}catch{}if(a.files_read||a.files_modified){let n=[];if(a.files_read)try{n.push(...JSON.parse(a.files_read))}catch{}if(a.files_modified)try{n.push(...JSON.parse(a.files_modified))}catch{}n.length>0&&t.push(`Files: ${[...new Set(n)].join(", ")}`)}t.length>0&&(s.push("---"),s.push(t.join(" | ")));let o=new Date(a.created_at_epoch).toLocaleString();return s.push(""),s.push("---"),s.push(`Date: ${o}`),s.join(` -`)}function ne(a,e){let r=a.request||`Session ${a.sdk_session_id.substring(0,8)}`,s=[];s.push(`## ${r}`),s.push(`*Source: claude-mem://session/${a.sdk_session_id}*`),s.push(""),a.completed&&(s.push(`**Completed:** ${a.completed}`),s.push("")),a.learned&&(s.push(`**Learned:** ${a.learned}`),s.push("")),a.investigated&&(s.push(`**Investigated:** ${a.investigated}`),s.push("")),a.next_steps&&(s.push(`**Next Steps:** ${a.next_steps}`),s.push("")),a.notes&&(s.push(`**Notes:** ${a.notes}`),s.push(""));let t=[];if(a.files_read||a.files_edited){let n=[];if(a.files_read)try{n.push(...JSON.parse(a.files_read))}catch{}if(a.files_edited)try{n.push(...JSON.parse(a.files_edited))}catch{}n.length>0&&t.push(`Files: ${[...new Set(n)].join(", ")}`)}let o=new Date(a.created_at_epoch).toLocaleDateString();return t.push(`Date: ${o}`),t.length>0&&(s.push("---"),s.push(t.join(" | "))),s.join(` -`)}function Re(a,e){let r=a.prompt.length>100?a.prompt.substring(0,100)+"...":a.prompt,s=new Date(a.created_at_epoch).toLocaleString();return`${e+1}. "${r}" - Date: ${s} | Prompt #${a.prompt_number} - Source: claude-mem://user-prompt/${a.id}`}function ve(a,e){let r=[];r.push(`## User Prompt #${a.prompt_number}`),r.push(`*Source: claude-mem://user-prompt/${a.id}*`),r.push(""),r.push(a.prompt),r.push(""),r.push("---");let s=new Date(a.created_at_epoch).toLocaleString();return r.push(`Date: ${s}`),r.join(` -`)}var Oe=i.object({project:i.string().optional().describe("Filter by project name"),type:i.union([i.enum(["decision","bugfix","feature","refactor","discovery","change"]),i.array(i.enum(["decision","bugfix","feature","refactor","discovery","change"]))]).optional().describe("Filter by observation type"),concepts:i.union([i.string(),i.array(i.string())]).optional().describe("Filter by concept tags"),files:i.union([i.string(),i.array(i.string())]).optional().describe("Filter by file paths (partial match)"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional().describe("Start date (ISO string or epoch)"),end:i.union([i.string(),i.number()]).optional().describe("End date (ISO string or epoch)")}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum number of results"),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),oe=[{name:"search_observations",description:'Search observations using full-text search across titles, narratives, facts, and concepts. IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({query:i.string().describe("Search query for FTS5 full-text search"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'),...Oe.shape}),handler:async a=>{try{let{query:e,format:r="index",...s}=a,t=[];if(k)try{console.error("[search-server] Using hybrid semantic search (Chroma + SQLite)");let n=await M(e,100);if(console.error(`[search-server] Chroma returned ${n.ids.length} semantic matches`),n.ids.length>0){let c=Math.floor(Date.now()/1e3)-7776e3,d=n.ids.filter((l,u)=>{let p=n.metadatas[u];return p&&p.created_at_epoch>c});if(console.error(`[search-server] ${d.length} results within 90-day window`),d.length>0){let l=s.limit||20;t=N.getObservationsByIds(d,{orderBy:"date_desc",limit:l}),console.error(`[search-server] Hydrated ${t.length} observations from SQLite`)}}}catch(n){console.error("[search-server] Chroma query failed, falling back to FTS5:",n.message)}if(t.length===0&&(console.error("[search-server] Using FTS5 keyword search"),t=$.searchObservations(e,s)),t.length===0)return{content:[{type:"text",text:`No observations found matching "${e}"`}]};let o;if(r==="index"){let n=`Found ${t.length} observation(s) matching "${e}": + Source: claude-mem://session/${c.sdk_session_id}`}function W(c,e){let r=c.title||`Observation #${c.id}`,s=[];s.push(`## ${r}`),s.push(`*Source: claude-mem://observation/${c.id}*`),s.push(""),c.subtitle&&(s.push(`**${c.subtitle}**`),s.push("")),c.narrative&&(s.push(c.narrative),s.push("")),c.text&&(s.push(c.text),s.push(""));let t=[];if(t.push(`Type: ${c.type}`),c.facts)try{let n=JSON.parse(c.facts);n.length>0&&t.push(`Facts: ${n.join("; ")}`)}catch{}if(c.concepts)try{let n=JSON.parse(c.concepts);n.length>0&&t.push(`Concepts: ${n.join(", ")}`)}catch{}if(c.files_read||c.files_modified){let n=[];if(c.files_read)try{n.push(...JSON.parse(c.files_read))}catch{}if(c.files_modified)try{n.push(...JSON.parse(c.files_modified))}catch{}n.length>0&&t.push(`Files: ${[...new Set(n)].join(", ")}`)}t.length>0&&(s.push("---"),s.push(t.join(" | ")));let o=new Date(c.created_at_epoch).toLocaleString();return s.push(""),s.push("---"),s.push(`Date: ${o}`),s.join(` +`)}function ne(c,e){let r=c.request||`Session ${c.sdk_session_id.substring(0,8)}`,s=[];s.push(`## ${r}`),s.push(`*Source: claude-mem://session/${c.sdk_session_id}*`),s.push(""),c.completed&&(s.push(`**Completed:** ${c.completed}`),s.push("")),c.learned&&(s.push(`**Learned:** ${c.learned}`),s.push("")),c.investigated&&(s.push(`**Investigated:** ${c.investigated}`),s.push("")),c.next_steps&&(s.push(`**Next Steps:** ${c.next_steps}`),s.push("")),c.notes&&(s.push(`**Notes:** ${c.notes}`),s.push(""));let t=[];if(c.files_read||c.files_edited){let n=[];if(c.files_read)try{n.push(...JSON.parse(c.files_read))}catch{}if(c.files_edited)try{n.push(...JSON.parse(c.files_edited))}catch{}n.length>0&&t.push(`Files: ${[...new Set(n)].join(", ")}`)}let o=new Date(c.created_at_epoch).toLocaleDateString();return t.push(`Date: ${o}`),t.length>0&&(s.push("---"),s.push(t.join(" | "))),s.join(` +`)}function Re(c,e){let r=new Date(c.created_at_epoch).toLocaleString();return`${e+1}. "${c.prompt_text}" + Date: ${r} | Prompt #${c.prompt_number} + Source: claude-mem://user-prompt/${c.id}`}function ve(c,e){let r=[];r.push(`## User Prompt #${c.prompt_number}`),r.push(`*Source: claude-mem://user-prompt/${c.id}*`),r.push(""),r.push(c.prompt_text),r.push(""),r.push("---");let s=new Date(c.created_at_epoch).toLocaleString();return r.push(`Date: ${s}`),r.join(` +`)}var Oe=i.object({project:i.string().optional().describe("Filter by project name"),type:i.union([i.enum(["decision","bugfix","feature","refactor","discovery","change"]),i.array(i.enum(["decision","bugfix","feature","refactor","discovery","change"]))]).optional().describe("Filter by observation type"),concepts:i.union([i.string(),i.array(i.string())]).optional().describe("Filter by concept tags"),files:i.union([i.string(),i.array(i.string())]).optional().describe("Filter by file paths (partial match)"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional().describe("Start date (ISO string or epoch)"),end:i.union([i.string(),i.number()]).optional().describe("End date (ISO string or epoch)")}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum number of results"),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),oe=[{name:"search_observations",description:'Search observations using full-text search across titles, narratives, facts, and concepts. IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({query:i.string().describe("Search query for FTS5 full-text search"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'),...Oe.shape}),handler:async c=>{try{let{query:e,format:r="index",...s}=c,t=[];if(k)try{console.error("[search-server] Using hybrid semantic search (Chroma + SQLite)");let n=await M(e,100);if(console.error(`[search-server] Chroma returned ${n.ids.length} semantic matches`),n.ids.length>0){let a=Date.now()-7776e6,d=n.ids.filter((l,u)=>{let p=n.metadatas[u];return p&&p.created_at_epoch>a});if(console.error(`[search-server] ${d.length} results within 90-day window`),d.length>0){let l=s.limit||20;t=N.getObservationsByIds(d,{orderBy:"date_desc",limit:l}),console.error(`[search-server] Hydrated ${t.length} observations from SQLite`)}}}catch(n){console.error("[search-server] Chroma query failed, falling back to FTS5:",n.message)}if(t.length===0&&(console.error("[search-server] Using FTS5 keyword search"),t=$.searchObservations(e,s)),t.length===0)return{content:[{type:"text",text:`No observations found matching "${e}"`}]};let o;if(r==="index"){let n=`Found ${t.length} observation(s) matching "${e}": -`,c=t.map((d,l)=>q(d,l));o=n+c.join(` +`,a=t.map((d,l)=>q(d,l));o=n+a.join(` -`)+j()}else o=t.map((c,d)=>W(c,d)).join(` +`)+j()}else o=t.map((a,d)=>W(a,d)).join(` --- -`);return{content:[{type:"text",text:o}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"search_sessions",description:'Search session summaries using full-text search across requests, completions, learnings, and notes. IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({query:i.string().describe("Search query for FTS5 full-text search"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'),project:i.string().optional().describe("Filter by project name"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional(),end:i.union([i.string(),i.number()]).optional()}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum number of results"),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),handler:async a=>{try{let{query:e,format:r="index",...s}=a,t=[];if(k)try{console.error("[search-server] Using hybrid semantic search for sessions");let n=await M(e,100,{doc_type:"session_summary"});if(console.error(`[search-server] Chroma returned ${n.ids.length} semantic matches`),n.ids.length>0){let c=Math.floor(Date.now()/1e3)-7776e3,d=n.ids.filter((l,u)=>{let p=n.metadatas[u];return p&&p.created_at_epoch>c});if(console.error(`[search-server] ${d.length} results within 90-day window`),d.length>0){let l=s.limit||20;t=N.getSessionSummariesByIds(d,{orderBy:"date_desc",limit:l}),console.error(`[search-server] Hydrated ${t.length} sessions from SQLite`)}}}catch(n){console.error("[search-server] Chroma query failed, falling back to FTS5:",n.message)}if(t.length===0&&(console.error("[search-server] Using FTS5 keyword search"),t=$.searchSessions(e,s)),t.length===0)return{content:[{type:"text",text:`No sessions found matching "${e}"`}]};let o;if(r==="index"){let n=`Found ${t.length} session(s) matching "${e}": +`);return{content:[{type:"text",text:o}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"search_sessions",description:'Search session summaries using full-text search across requests, completions, learnings, and notes. IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({query:i.string().describe("Search query for FTS5 full-text search"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'),project:i.string().optional().describe("Filter by project name"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional(),end:i.union([i.string(),i.number()]).optional()}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum number of results"),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),handler:async c=>{try{let{query:e,format:r="index",...s}=c,t=[];if(k)try{console.error("[search-server] Using hybrid semantic search for sessions");let n=await M(e,100,{doc_type:"session_summary"});if(console.error(`[search-server] Chroma returned ${n.ids.length} semantic matches`),n.ids.length>0){let a=Date.now()-7776e6,d=n.ids.filter((l,u)=>{let p=n.metadatas[u];return p&&p.created_at_epoch>a});if(console.error(`[search-server] ${d.length} results within 90-day window`),d.length>0){let l=s.limit||20;t=N.getSessionSummariesByIds(d,{orderBy:"date_desc",limit:l}),console.error(`[search-server] Hydrated ${t.length} sessions from SQLite`)}}}catch(n){console.error("[search-server] Chroma query failed, falling back to FTS5:",n.message)}if(t.length===0&&(console.error("[search-server] Using FTS5 keyword search"),t=$.searchSessions(e,s)),t.length===0)return{content:[{type:"text",text:`No sessions found matching "${e}"`}]};let o;if(r==="index"){let n=`Found ${t.length} session(s) matching "${e}": -`,c=t.map((d,l)=>re(d,l));o=n+c.join(` +`,a=t.map((d,l)=>re(d,l));o=n+a.join(` -`)+j()}else o=t.map((c,d)=>ne(c,d)).join(` +`)+j()}else o=t.map((a,d)=>ne(a,d)).join(` --- -`);return{content:[{type:"text",text:o}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"find_by_concept",description:'Find observations tagged with a specific concept. IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({concept:i.string().describe("Concept tag to search for"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'),project:i.string().optional().describe("Filter by project name"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional(),end:i.union([i.string(),i.number()]).optional()}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum results. IMPORTANT: Start with 3-5 to avoid exceeding MCP token limits, even in index mode."),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),handler:async a=>{try{let{concept:e,format:r="index",...s}=a,t=[];if(k)try{console.error("[search-server] Using metadata-first + semantic ranking for concept search");let n=$.findByConcept(e,s);if(console.error(`[search-server] Found ${n.length} observations with concept "${e}"`),n.length>0){let c=n.map(u=>u.id),d=await M(e,Math.min(c.length,100)),l=[];for(let u of d.ids)c.includes(u)&&!l.includes(u)&&l.push(u);console.error(`[search-server] Chroma ranked ${l.length} results by semantic relevance`),l.length>0&&(t=N.getObservationsByIds(l,{limit:s.limit||20}),t.sort((u,p)=>l.indexOf(u.id)-l.indexOf(p.id)))}}catch(n){console.error("[search-server] Chroma ranking failed, using SQLite order:",n.message)}if(t.length===0&&(console.error("[search-server] Using SQLite-only concept search"),t=$.findByConcept(e,s)),t.length===0)return{content:[{type:"text",text:`No observations found with concept "${e}"`}]};let o;if(r==="index"){let n=`Found ${t.length} observation(s) with concept "${e}": +`);return{content:[{type:"text",text:o}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"find_by_concept",description:'Find observations tagged with a specific concept. Available concepts: "discovery", "problem-solution", "what-changed", "how-it-works", "pattern", "gotcha", "change". IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({concept:i.string().describe("Concept tag to search for. Available: discovery, problem-solution, what-changed, how-it-works, pattern, gotcha, change"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'),project:i.string().optional().describe("Filter by project name"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional(),end:i.union([i.string(),i.number()]).optional()}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum results. IMPORTANT: Start with 3-5 to avoid exceeding MCP token limits, even in index mode."),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),handler:async c=>{try{let{concept:e,format:r="index",...s}=c,t=[];if(k)try{console.error("[search-server] Using metadata-first + semantic ranking for concept search");let n=$.findByConcept(e,s);if(console.error(`[search-server] Found ${n.length} observations with concept "${e}"`),n.length>0){let a=n.map(u=>u.id),d=await M(e,Math.min(a.length,100)),l=[];for(let u of d.ids)a.includes(u)&&!l.includes(u)&&l.push(u);console.error(`[search-server] Chroma ranked ${l.length} results by semantic relevance`),l.length>0&&(t=N.getObservationsByIds(l,{limit:s.limit||20}),t.sort((u,p)=>l.indexOf(u.id)-l.indexOf(p.id)))}}catch(n){console.error("[search-server] Chroma ranking failed, using SQLite order:",n.message)}if(t.length===0&&(console.error("[search-server] Using SQLite-only concept search"),t=$.findByConcept(e,s)),t.length===0)return{content:[{type:"text",text:`No observations found with concept "${e}"`}]};let o;if(r==="index"){let n=`Found ${t.length} observation(s) with concept "${e}": -`,c=t.map((d,l)=>q(d,l));o=n+c.join(` +`,a=t.map((d,l)=>q(d,l));o=n+a.join(` -`)+j()}else o=t.map((c,d)=>W(c,d)).join(` +`)+j()}else o=t.map((a,d)=>W(a,d)).join(` --- -`);return{content:[{type:"text",text:o}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"find_by_file",description:'Find observations and sessions that reference a specific file path. IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({filePath:i.string().describe("File path to search for (supports partial matching)"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'),project:i.string().optional().describe("Filter by project name"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional(),end:i.union([i.string(),i.number()]).optional()}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum results. IMPORTANT: Start with 3-5 to avoid exceeding MCP token limits, even in index mode."),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),handler:async a=>{try{let{filePath:e,format:r="index",...s}=a,t=[],o=[];if(k)try{console.error("[search-server] Using metadata-first + semantic ranking for file search");let d=$.findByFile(e,s);if(console.error(`[search-server] Found ${d.observations.length} observations, ${d.sessions.length} sessions for file "${e}"`),o=d.sessions,d.observations.length>0){let l=d.observations.map(m=>m.id),u=await M(e,Math.min(l.length,100)),p=[];for(let m of u.ids)l.includes(m)&&!p.includes(m)&&p.push(m);console.error(`[search-server] Chroma ranked ${p.length} observations by semantic relevance`),p.length>0&&(t=N.getObservationsByIds(p,{limit:s.limit||20}),t.sort((m,f)=>p.indexOf(m.id)-p.indexOf(f.id)))}}catch(d){console.error("[search-server] Chroma ranking failed, using SQLite order:",d.message)}if(t.length===0&&o.length===0){console.error("[search-server] Using SQLite-only file search");let d=$.findByFile(e,s);t=d.observations,o=d.sessions}let n=t.length+o.length;if(n===0)return{content:[{type:"text",text:`No results found for file "${e}"`}]};let c;if(r==="index"){let d=`Found ${n} result(s) for file "${e}": +`);return{content:[{type:"text",text:o}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"find_by_file",description:'Find observations and sessions that reference a specific file path. IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({filePath:i.string().describe("File path to search for (supports partial matching)"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'),project:i.string().optional().describe("Filter by project name"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional(),end:i.union([i.string(),i.number()]).optional()}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum results. IMPORTANT: Start with 3-5 to avoid exceeding MCP token limits, even in index mode."),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),handler:async c=>{try{let{filePath:e,format:r="index",...s}=c,t=[],o=[];if(k)try{console.error("[search-server] Using metadata-first + semantic ranking for file search");let d=$.findByFile(e,s);if(console.error(`[search-server] Found ${d.observations.length} observations, ${d.sessions.length} sessions for file "${e}"`),o=d.sessions,d.observations.length>0){let l=d.observations.map(m=>m.id),u=await M(e,Math.min(l.length,100)),p=[];for(let m of u.ids)l.includes(m)&&!p.includes(m)&&p.push(m);console.error(`[search-server] Chroma ranked ${p.length} observations by semantic relevance`),p.length>0&&(t=N.getObservationsByIds(p,{limit:s.limit||20}),t.sort((m,f)=>p.indexOf(m.id)-p.indexOf(f.id)))}}catch(d){console.error("[search-server] Chroma ranking failed, using SQLite order:",d.message)}if(t.length===0&&o.length===0){console.error("[search-server] Using SQLite-only file search");let d=$.findByFile(e,s);t=d.observations,o=d.sessions}let n=t.length+o.length;if(n===0)return{content:[{type:"text",text:`No results found for file "${e}"`}]};let a;if(r==="index"){let d=`Found ${n} result(s) for file "${e}": -`,l=[];t.forEach((u,p)=>{l.push(q(u,p))}),o.forEach((u,p)=>{l.push(re(u,p+t.length))}),c=d+l.join(` +`,l=[];t.forEach((u,p)=>{l.push(q(u,p))}),o.forEach((u,p)=>{l.push(re(u,p+t.length))}),a=d+l.join(` -`)+j()}else{let d=[];t.forEach((l,u)=>{d.push(W(l,u))}),o.forEach((l,u)=>{d.push(ne(l,u+t.length))}),c=d.join(` +`)+j()}else{let d=[];t.forEach((l,u)=>{d.push(W(l,u))}),o.forEach((l,u)=>{d.push(ne(l,u+t.length))}),a=d.join(` --- -`)}return{content:[{type:"text",text:c}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"find_by_type",description:'Find observations of a specific type (decision, bugfix, feature, refactor, discovery, change). IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({type:i.union([i.enum(["decision","bugfix","feature","refactor","discovery","change"]),i.array(i.enum(["decision","bugfix","feature","refactor","discovery","change"]))]).describe("Observation type(s) to filter by"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'),project:i.string().optional().describe("Filter by project name"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional(),end:i.union([i.string(),i.number()]).optional()}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum results. IMPORTANT: Start with 3-5 to avoid exceeding MCP token limits, even in index mode."),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),handler:async a=>{try{let{type:e,format:r="index",...s}=a,t=Array.isArray(e)?e.join(", "):e,o=[];if(k)try{console.error("[search-server] Using metadata-first + semantic ranking for type search");let c=$.findByType(e,s);if(console.error(`[search-server] Found ${c.length} observations with type "${t}"`),c.length>0){let d=c.map(p=>p.id),l=await M(t,Math.min(d.length,100)),u=[];for(let p of l.ids)d.includes(p)&&!u.includes(p)&&u.push(p);console.error(`[search-server] Chroma ranked ${u.length} results by semantic relevance`),u.length>0&&(o=N.getObservationsByIds(u,{limit:s.limit||20}),o.sort((p,m)=>u.indexOf(p.id)-u.indexOf(m.id)))}}catch(c){console.error("[search-server] Chroma ranking failed, using SQLite order:",c.message)}if(o.length===0&&(console.error("[search-server] Using SQLite-only type search"),o=$.findByType(e,s)),o.length===0)return{content:[{type:"text",text:`No observations found with type "${t}"`}]};let n;if(r==="index"){let c=`Found ${o.length} observation(s) with type "${t}": +`)}return{content:[{type:"text",text:a}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"find_by_type",description:'Find observations of a specific type (decision, bugfix, feature, refactor, discovery, change). IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({type:i.union([i.enum(["decision","bugfix","feature","refactor","discovery","change"]),i.array(i.enum(["decision","bugfix","feature","refactor","discovery","change"]))]).describe("Observation type(s) to filter by"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'),project:i.string().optional().describe("Filter by project name"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional(),end:i.union([i.string(),i.number()]).optional()}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum results. IMPORTANT: Start with 3-5 to avoid exceeding MCP token limits, even in index mode."),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),handler:async c=>{try{let{type:e,format:r="index",...s}=c,t=Array.isArray(e)?e.join(", "):e,o=[];if(k)try{console.error("[search-server] Using metadata-first + semantic ranking for type search");let a=$.findByType(e,s);if(console.error(`[search-server] Found ${a.length} observations with type "${t}"`),a.length>0){let d=a.map(p=>p.id),l=await M(t,Math.min(d.length,100)),u=[];for(let p of l.ids)d.includes(p)&&!u.includes(p)&&u.push(p);console.error(`[search-server] Chroma ranked ${u.length} results by semantic relevance`),u.length>0&&(o=N.getObservationsByIds(u,{limit:s.limit||20}),o.sort((p,m)=>u.indexOf(p.id)-u.indexOf(m.id)))}}catch(a){console.error("[search-server] Chroma ranking failed, using SQLite order:",a.message)}if(o.length===0&&(console.error("[search-server] Using SQLite-only type search"),o=$.findByType(e,s)),o.length===0)return{content:[{type:"text",text:`No observations found with type "${t}"`}]};let n;if(r==="index"){let a=`Found ${o.length} observation(s) with type "${t}": -`,d=o.map((l,u)=>q(l,u));n=c+d.join(` +`,d=o.map((l,u)=>q(l,u));n=a+d.join(` `)+j()}else n=o.map((d,l)=>W(d,l)).join(` --- -`);return{content:[{type:"text",text:n}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"get_recent_context",description:"Get recent session context including summaries and observations for a project",inputSchema:i.object({project:i.string().optional().describe("Project name (defaults to current working directory basename)"),limit:i.number().min(1).max(10).default(3).describe("Number of recent sessions to retrieve")}),handler:async a=>{try{let e=a.project||Se(process.cwd()),r=a.limit||3,s=N.getRecentSessionsWithStatus(e,r);if(s.length===0)return{content:[{type:"text",text:`# Recent Session Context +`);return{content:[{type:"text",text:n}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"get_recent_context",description:"Get recent session context including summaries and observations for a project",inputSchema:i.object({project:i.string().optional().describe("Project name (defaults to current working directory basename)"),limit:i.number().min(1).max(10).default(3).describe("Number of recent sessions to retrieve")}),handler:async c=>{try{let e=c.project||Se(process.cwd()),r=c.limit||3,s=N.getRecentSessionsWithStatus(e,r);if(s.length===0)return{content:[{type:"text",text:`# Recent Session Context -No previous sessions found for project "${e}".`}]};let t=[];t.push("# Recent Session Context"),t.push(""),t.push(`Showing last ${s.length} session(s) for **${e}**:`),t.push("");for(let o of s)if(o.sdk_session_id){if(t.push("---"),t.push(""),o.has_summary){let n=N.getSummaryForSession(o.sdk_session_id);if(n){let c=n.prompt_number?` (Prompt #${n.prompt_number})`:"";if(t.push(`**Summary${c}**`),t.push(""),n.request&&t.push(`**Request:** ${n.request}`),n.completed&&t.push(`**Completed:** ${n.completed}`),n.learned&&t.push(`**Learned:** ${n.learned}`),n.next_steps&&t.push(`**Next Steps:** ${n.next_steps}`),n.files_read)try{let l=JSON.parse(n.files_read);Array.isArray(l)&&l.length>0&&t.push(`**Files Read:** ${l.join(", ")}`)}catch{n.files_read.trim()&&t.push(`**Files Read:** ${n.files_read}`)}if(n.files_edited)try{let l=JSON.parse(n.files_edited);Array.isArray(l)&&l.length>0&&t.push(`**Files Edited:** ${l.join(", ")}`)}catch{n.files_edited.trim()&&t.push(`**Files Edited:** ${n.files_edited}`)}let d=new Date(n.created_at).toLocaleString();t.push(`**Date:** ${d}`)}}else if(o.status==="active"){t.push("**In Progress**"),t.push(""),o.user_prompt&&t.push(`**Request:** ${o.user_prompt}`);let n=N.getObservationsForSession(o.sdk_session_id);if(n.length>0){t.push(""),t.push(`**Observations (${n.length}):**`);for(let d of n)t.push(`- ${d.title}`)}else t.push(""),t.push("*No observations yet*");t.push(""),t.push("**Status:** Active - summary pending");let c=new Date(o.started_at).toLocaleString();t.push(`**Date:** ${c}`)}else{t.push(`**${o.status.charAt(0).toUpperCase()+o.status.slice(1)}**`),t.push(""),o.user_prompt&&t.push(`**Request:** ${o.user_prompt}`),t.push(""),t.push(`**Status:** ${o.status} - no summary available`);let n=new Date(o.started_at).toLocaleString();t.push(`**Date:** ${n}`)}t.push("")}return{content:[{type:"text",text:t.join(` -`)}]}}catch(e){return{content:[{type:"text",text:`Failed to get recent context: ${e.message}`}],isError:!0}}}},{name:"search_user_prompts",description:'Search raw user prompts with full-text search. Use this to find what the user actually said/requested across all sessions. IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({query:i.string().describe("Search query for FTS5 full-text search"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for truncated prompts/dates (default, RECOMMENDED for initial search), "full" for complete prompt text (use only after reviewing index results)'),project:i.string().optional().describe("Filter by project name"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional(),end:i.union([i.string(),i.number()]).optional()}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum number of results"),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),handler:async a=>{try{let{query:e,format:r="index",...s}=a,t=[];if(k)try{console.error("[search-server] Using hybrid semantic search for user prompts");let n=await M(e,100,{doc_type:"user_prompt"});if(console.error(`[search-server] Chroma returned ${n.ids.length} semantic matches`),n.ids.length>0){let c=Math.floor(Date.now()/1e3)-7776e3,d=n.ids.filter((l,u)=>{let p=n.metadatas[u];return p&&p.created_at_epoch>c});if(console.error(`[search-server] ${d.length} results within 90-day window`),d.length>0){let l=s.limit||20;t=N.getUserPromptsByIds(d,{orderBy:"date_desc",limit:l}),console.error(`[search-server] Hydrated ${t.length} user prompts from SQLite`)}}}catch(n){console.error("[search-server] Chroma query failed, falling back to FTS5:",n.message)}if(t.length===0&&(console.error("[search-server] Using FTS5 keyword search"),t=$.searchUserPrompts(e,s)),t.length===0)return{content:[{type:"text",text:`No user prompts found matching "${e}"`}]};let o;if(r==="index"){let n=`Found ${t.length} user prompt(s) matching "${e}": +No previous sessions found for project "${e}".`}]};let t=[];t.push("# Recent Session Context"),t.push(""),t.push(`Showing last ${s.length} session(s) for **${e}**:`),t.push("");for(let o of s)if(o.sdk_session_id){if(t.push("---"),t.push(""),o.has_summary){let n=N.getSummaryForSession(o.sdk_session_id);if(n){let a=n.prompt_number?` (Prompt #${n.prompt_number})`:"";if(t.push(`**Summary${a}**`),t.push(""),n.request&&t.push(`**Request:** ${n.request}`),n.completed&&t.push(`**Completed:** ${n.completed}`),n.learned&&t.push(`**Learned:** ${n.learned}`),n.next_steps&&t.push(`**Next Steps:** ${n.next_steps}`),n.files_read)try{let l=JSON.parse(n.files_read);Array.isArray(l)&&l.length>0&&t.push(`**Files Read:** ${l.join(", ")}`)}catch{n.files_read.trim()&&t.push(`**Files Read:** ${n.files_read}`)}if(n.files_edited)try{let l=JSON.parse(n.files_edited);Array.isArray(l)&&l.length>0&&t.push(`**Files Edited:** ${l.join(", ")}`)}catch{n.files_edited.trim()&&t.push(`**Files Edited:** ${n.files_edited}`)}let d=new Date(n.created_at).toLocaleString();t.push(`**Date:** ${d}`)}}else if(o.status==="active"){t.push("**In Progress**"),t.push(""),o.user_prompt&&t.push(`**Request:** ${o.user_prompt}`);let n=N.getObservationsForSession(o.sdk_session_id);if(n.length>0){t.push(""),t.push(`**Observations (${n.length}):**`);for(let d of n)t.push(`- ${d.title}`)}else t.push(""),t.push("*No observations yet*");t.push(""),t.push("**Status:** Active - summary pending");let a=new Date(o.started_at).toLocaleString();t.push(`**Date:** ${a}`)}else{t.push(`**${o.status.charAt(0).toUpperCase()+o.status.slice(1)}**`),t.push(""),o.user_prompt&&t.push(`**Request:** ${o.user_prompt}`),t.push(""),t.push(`**Status:** ${o.status} - no summary available`);let n=new Date(o.started_at).toLocaleString();t.push(`**Date:** ${n}`)}t.push("")}return{content:[{type:"text",text:t.join(` +`)}]}}catch(e){return{content:[{type:"text",text:`Failed to get recent context: ${e.message}`}],isError:!0}}}},{name:"search_user_prompts",description:'Search raw user prompts with full-text search. Use this to find what the user actually said/requested across all sessions. IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.',inputSchema:i.object({query:i.string().describe("Search query for FTS5 full-text search"),format:i.enum(["index","full"]).default("index").describe('Output format: "index" for truncated prompts/dates (default, RECOMMENDED for initial search), "full" for complete prompt text (use only after reviewing index results)'),project:i.string().optional().describe("Filter by project name"),dateRange:i.object({start:i.union([i.string(),i.number()]).optional(),end:i.union([i.string(),i.number()]).optional()}).optional().describe("Filter by date range"),limit:i.number().min(1).max(100).default(20).describe("Maximum number of results"),offset:i.number().min(0).default(0).describe("Number of results to skip"),orderBy:i.enum(["relevance","date_desc","date_asc"]).default("date_desc").describe("Sort order")}),handler:async c=>{try{let{query:e,format:r="index",...s}=c,t=[];if(k)try{console.error("[search-server] Using hybrid semantic search for user prompts");let n=await M(e,100,{doc_type:"user_prompt"});if(console.error(`[search-server] Chroma returned ${n.ids.length} semantic matches`),n.ids.length>0){let a=Date.now()-7776e6,d=n.ids.filter((l,u)=>{let p=n.metadatas[u];return p&&p.created_at_epoch>a});if(console.error(`[search-server] ${d.length} results within 90-day window`),d.length>0){let l=s.limit||20;t=N.getUserPromptsByIds(d,{orderBy:"date_desc",limit:l}),console.error(`[search-server] Hydrated ${t.length} user prompts from SQLite`)}}}catch(n){console.error("[search-server] Chroma query failed, falling back to FTS5:",n.message)}if(t.length===0&&(console.error("[search-server] Using FTS5 keyword search"),t=$.searchUserPrompts(e,s)),t.length===0)return{content:[{type:"text",text:`No user prompts found matching "${e}"`}]};let o;if(r==="index"){let n=`Found ${t.length} user prompt(s) matching "${e}": -`,c=t.map((d,l)=>Re(d,l));o=n+c.join(` +`,a=t.map((d,l)=>Re(d,l));o=n+a.join(` -`)+j()}else o=t.map((c,d)=>ve(c,d)).join(` +`)+j()}else o=t.map((a,d)=>ve(a,d)).join(` --- -`);return{content:[{type:"text",text:o}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"get_context_timeline",description:'Get a unified timeline of context (observations, sessions, and prompts) around a specific point in time. All record types are interleaved chronologically. Useful for understanding "what was happening when X occurred". Returns depth_before records before anchor + anchor + depth_after records after (total: depth_before + 1 + depth_after mixed records).',inputSchema:i.object({anchor:i.union([i.number().describe("Observation ID to center timeline around"),i.string().describe("Session ID (format: S123) or ISO timestamp to center timeline around")]).describe('Anchor point: observation ID, session ID (e.g., "S123"), or ISO timestamp'),depth_before:i.number().min(0).max(50).default(10).describe("Number of records to retrieve before anchor, not including anchor (default: 10)"),depth_after:i.number().min(0).max(50).default(10).describe("Number of records to retrieve after anchor, not including anchor (default: 10)"),project:i.string().optional().describe("Filter by project name")}),handler:async a=>{try{let f=function(g){return new Date(g).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})},h=function(g){return new Date(g).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})},b=function(g){return new Date(g).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})},_=function(g){return g?Math.ceil(g.length/4):0};var e=f,r=h,s=b,t=_;let{anchor:o,depth_before:n=10,depth_after:c=10,project:d}=a,l,u=o,p;if(typeof o=="number"){let g=N.getObservationById(o);if(!g)return{content:[{type:"text",text:`Observation #${o} not found`}],isError:!0};l=g.created_at_epoch,p=N.getTimelineAroundObservation(o,l,n,c,d)}else if(typeof o=="string")if(o.startsWith("S")||o.startsWith("#S")){let g=o.replace(/^#?S/,""),I=parseInt(g,10),S=N.getSessionSummariesByIds([I]);if(S.length===0)return{content:[{type:"text",text:`Session #${I} not found`}],isError:!0};l=S[0].created_at_epoch,u=`S${I}`,p=N.getTimelineAroundTimestamp(l,n,c,d)}else{let g=new Date(o);if(isNaN(g.getTime()))return{content:[{type:"text",text:`Invalid timestamp: ${o}`}],isError:!0};l=g.getTime(),p=N.getTimelineAroundTimestamp(l,n,c,d)}else return{content:[{type:"text",text:'Invalid anchor: must be observation ID (number), session ID (e.g., "S123"), or ISO timestamp'}],isError:!0};let m=[...p.observations.map(g=>({type:"observation",data:g,epoch:g.created_at_epoch})),...p.sessions.map(g=>({type:"session",data:g,epoch:g.created_at_epoch})),...p.prompts.map(g=>({type:"prompt",data:g,epoch:g.created_at_epoch}))];if(m.sort((g,I)=>g.epoch-I.epoch),m.length===0)return{content:[{type:"text",text:`No context found around ${new Date(l).toLocaleString()} (${n} records before, ${c} records after)`}]};let E=[];E.push(`# Timeline around anchor: ${u}`),E.push(`**Window:** ${n} records before \u2192 ${c} records after | **Items:** ${m.length} (${p.observations.length} obs, ${p.sessions.length} sessions, ${p.prompts.length} prompts)`),E.push(""),E.push("**Legend:** \u{1F3AF} session-request | \u{1F534} bugfix | \u{1F7E3} feature | \u{1F504} refactor | \u2705 change | \u{1F535} discovery | \u{1F9E0} decision"),E.push("");let x=new Map;for(let g of m){let I=f(g.epoch);x.has(I)||x.set(I,[]),x.get(I).push(g)}let T=Array.from(x.entries()).sort((g,I)=>{let S=new Date(g[0]).getTime(),O=new Date(I[0]).getTime();return S-O});for(let[g,I]of T){E.push(`### ${g}`),E.push("");let S=null,O="",C=!1;for(let v of I){let F=typeof u=="number"&&v.type==="observation"&&v.data.id===u||typeof u=="string"&&u.startsWith("S")&&v.type==="session"&&`S${v.data.id}`===u;if(v.type==="session"){C&&(E.push(""),C=!1,S=null,O="");let y=v.data,U=y.request||"Session summary",R=`claude-mem://session-summary/${y.id}`,A=F?" \u2190 **ANCHOR**":"";E.push(`**\u{1F3AF} #S${y.id}** ${U} (${b(v.epoch)}) [\u2192](${R})${A}`),E.push("")}else if(v.type==="prompt"){C&&(E.push(""),C=!1,S=null,O="");let y=v.data,U=y.prompt.length>100?y.prompt.substring(0,100)+"...":y.prompt;E.push(`**\u{1F4AC} User Prompt #${y.prompt_number}** (${b(v.epoch)})`),E.push(`> ${U}`),E.push("")}else if(v.type==="observation"){let y=v.data,U="General";U!==S&&(C&&E.push(""),E.push(`**${U}**`),E.push("| ID | Time | T | Title | Tokens |"),E.push("|----|------|---|-------|--------|"),S=U,C=!0,O="");let R="\u2022";switch(y.type){case"bugfix":R="\u{1F534}";break;case"feature":R="\u{1F7E3}";break;case"refactor":R="\u{1F504}";break;case"change":R="\u2705";break;case"discovery":R="\u{1F535}";break;case"decision":R="\u{1F9E0}";break}let A=h(v.epoch),D=y.title||"Untitled",B=_(y.narrative),Y=A!==O?A:"\u2033";O=A;let Z=F?" \u2190 **ANCHOR**":"";E.push(`| #${y.id} | ${Y} | ${R} | ${D}${Z} | ~${B} |`)}}C&&E.push("")}return{content:[{type:"text",text:E.join(` -`)}]}}catch(o){return{content:[{type:"text",text:`Timeline query failed: ${o.message}`}],isError:!0}}}},{name:"get_timeline_by_query",description:'Search for observations using natural language and get timeline context around the best match. Two modes: "auto" (default) automatically uses top result as timeline anchor; "interactive" returns top matches for you to choose from. This combines search + timeline into a single operation for faster context discovery.',inputSchema:i.object({query:i.string().describe("Natural language search query to find relevant observations"),mode:i.enum(["auto","interactive"]).default("auto").describe("auto: Automatically use top search result as timeline anchor. interactive: Show top N search results for manual anchor selection."),depth_before:i.number().min(0).max(50).default(10).describe("Number of timeline records before anchor (default: 10)"),depth_after:i.number().min(0).max(50).default(10).describe("Number of timeline records after anchor (default: 10)"),limit:i.number().min(1).max(20).default(5).describe("For interactive mode: number of top search results to display (default: 5)"),project:i.string().optional().describe("Filter by project name")}),handler:async a=>{try{let{query:o,mode:n="auto",depth_before:c=10,depth_after:d=10,limit:l=5,project:u}=a,p=[];if(k)try{console.error("[search-server] Using hybrid semantic search for timeline query");let m=await M(o,100);if(console.error(`[search-server] Chroma returned ${m.ids.length} semantic matches`),m.ids.length>0){let f=Math.floor(Date.now()/1e3)-7776e3,h=m.ids.filter((b,_)=>{let E=m.metadatas[_];return E&&E.created_at_epoch>f});console.error(`[search-server] ${h.length} results within 90-day window`),h.length>0&&(p=N.getObservationsByIds(h,{orderBy:"date_desc",limit:n==="auto"?1:l}),console.error(`[search-server] Hydrated ${p.length} observations from SQLite`))}}catch(m){console.error("[search-server] Chroma query failed, falling back to FTS5:",m.message)}if(p.length===0&&(console.error("[search-server] Using FTS5 keyword search"),p=$.searchObservations(o,{orderBy:"relevance",limit:n==="auto"?1:l,project:u})),p.length===0)return{content:[{type:"text",text:`No observations found matching "${o}". Try a different search query.`}]};if(n==="interactive"){let m=[];m.push("# Timeline Anchor Search Results"),m.push(""),m.push(`Found ${p.length} observation(s) matching "${o}"`),m.push(""),m.push("To get timeline context around any of these observations, use the `get_context_timeline` tool with the observation ID as the anchor."),m.push(""),m.push(`**Top ${p.length} matches:**`),m.push("");for(let f=0;f({type:"observation",data:S,epoch:S.created_at_epoch})),...f.sessions.map(S=>({type:"session",data:S,epoch:S.created_at_epoch})),...f.prompts.map(S=>({type:"prompt",data:S,epoch:S.created_at_epoch}))];if(h.sort((S,O)=>S.epoch-O.epoch),h.length===0)return{content:[{type:"text",text:`Found observation #${m.id} matching "${o}", but no timeline context available (${c} records before, ${d} records after).`}]};let T=[];T.push(`# Timeline for query: "${o}"`),T.push(`**Anchor:** Observation #${m.id} - ${m.title||"Untitled"}`),T.push(`**Window:** ${c} records before \u2192 ${d} records after | **Items:** ${h.length} (${f.observations.length} obs, ${f.sessions.length} sessions, ${f.prompts.length} prompts)`),T.push(""),T.push("**Legend:** \u{1F3AF} session-request | \u{1F534} bugfix | \u{1F7E3} feature | \u{1F504} refactor | \u2705 change | \u{1F535} discovery | \u{1F9E0} decision"),T.push("");let g=new Map;for(let S of h){let O=b(S.epoch);g.has(O)||g.set(O,[]),g.get(O).push(S)}let I=Array.from(g.entries()).sort((S,O)=>{let C=new Date(S[0]).getTime(),v=new Date(O[0]).getTime();return C-v});for(let[S,O]of I){T.push(`### ${S}`),T.push("");let C=null,v="",F=!1;for(let y of O){let U=y.type==="observation"&&y.data.id===m.id;if(y.type==="session"){F&&(T.push(""),F=!1,C=null,v="");let R=y.data,A=R.request||"Session summary",D=`claude-mem://session-summary/${R.id}`;T.push(`**\u{1F3AF} #S${R.id}** ${A} (${E(y.epoch)}) [\u2192](${D})`),T.push("")}else if(y.type==="prompt"){F&&(T.push(""),F=!1,C=null,v="");let R=y.data,A=R.prompt.length>100?R.prompt.substring(0,100)+"...":R.prompt;T.push(`**\u{1F4AC} User Prompt #${R.prompt_number}** (${E(y.epoch)})`),T.push(`> ${A}`),T.push("")}else if(y.type==="observation"){let R=y.data,A="General";A!==C&&(F&&T.push(""),T.push(`**${A}**`),T.push("| ID | Time | T | Title | Tokens |"),T.push("|----|------|---|-------|--------|"),C=A,F=!0,v="");let D="\u2022";switch(R.type){case"bugfix":D="\u{1F534}";break;case"feature":D="\u{1F7E3}";break;case"refactor":D="\u{1F504}";break;case"change":D="\u2705";break;case"discovery":D="\u{1F535}";break;case"decision":D="\u{1F9E0}";break}let B=_(y.epoch),z=R.title||"Untitled",Y=x(R.narrative),ie=B!==v?B:"\u2033";v=B;let ae=U?" \u2190 **ANCHOR**":"";T.push(`| #${R.id} | ${ie} | ${D} | ${z}${ae} | ~${Y} |`)}}F&&T.push("")}return{content:[{type:"text",text:T.join(` -`)}]}}}catch(o){return{content:[{type:"text",text:`Timeline query failed: ${o.message}`}],isError:!0}}}}],J=new he({name:"claude-mem-search",version:"1.0.0"},{capabilities:{tools:{}}});J.setRequestHandler(ge,async()=>({tools:oe.map(a=>({name:a.name,description:a.description,inputSchema:Te(a.inputSchema)}))}));J.setRequestHandler(be,async a=>{let e=oe.find(r=>r.name===a.params.name);if(!e)throw new Error(`Unknown tool: ${a.params.name}`);try{return await e.handler(a.params.arguments||{})}catch(r){return{content:[{type:"text",text:`Tool execution failed: ${r.message}`}],isError:!0}}});async function Ie(){let a=new _e;await J.connect(a),console.error("[search-server] Claude-mem search server started"),setTimeout(async()=>{try{console.error("[search-server] Initializing Chroma client...");let e=new Ee({command:"uvx",args:["chroma-mcp","--client-type","persistent","--data-dir",te],stderr:"ignore"}),r=new fe({name:"claude-mem-search-chroma-client",version:"1.0.0"},{capabilities:{}});await r.connect(e),k=r,console.error("[search-server] Chroma client connected successfully")}catch(e){console.error("[search-server] Failed to initialize Chroma client:",e.message),console.error("[search-server] Falling back to FTS5-only search"),k=null}},0)}Ie().catch(a=>{console.error("[search-server] Fatal error:",a),process.exit(1)}); +`);return{content:[{type:"text",text:o}]}}catch(e){return{content:[{type:"text",text:`Search failed: ${e.message}`}],isError:!0}}}},{name:"get_context_timeline",description:'Get a unified timeline of context (observations, sessions, and prompts) around a specific point in time. All record types are interleaved chronologically. Useful for understanding "what was happening when X occurred". Returns depth_before records before anchor + anchor + depth_after records after (total: depth_before + 1 + depth_after mixed records).',inputSchema:i.object({anchor:i.union([i.number().describe("Observation ID to center timeline around"),i.string().describe("Session ID (format: S123) or ISO timestamp to center timeline around")]).describe('Anchor point: observation ID, session ID (e.g., "S123"), or ISO timestamp'),depth_before:i.number().min(0).max(50).default(10).describe("Number of records to retrieve before anchor, not including anchor (default: 10)"),depth_after:i.number().min(0).max(50).default(10).describe("Number of records to retrieve after anchor, not including anchor (default: 10)"),project:i.string().optional().describe("Filter by project name")}),handler:async c=>{try{let f=function(g){return new Date(g).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})},h=function(g){return new Date(g).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})},b=function(g){return new Date(g).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})},_=function(g){return g?Math.ceil(g.length/4):0};var e=f,r=h,s=b,t=_;let{anchor:o,depth_before:n=10,depth_after:a=10,project:d}=c,l,u=o,p;if(typeof o=="number"){let g=N.getObservationById(o);if(!g)return{content:[{type:"text",text:`Observation #${o} not found`}],isError:!0};l=g.created_at_epoch,p=N.getTimelineAroundObservation(o,l,n,a,d)}else if(typeof o=="string")if(o.startsWith("S")||o.startsWith("#S")){let g=o.replace(/^#?S/,""),I=parseInt(g,10),S=N.getSessionSummariesByIds([I]);if(S.length===0)return{content:[{type:"text",text:`Session #${I} not found`}],isError:!0};l=S[0].created_at_epoch,u=`S${I}`,p=N.getTimelineAroundTimestamp(l,n,a,d)}else{let g=new Date(o);if(isNaN(g.getTime()))return{content:[{type:"text",text:`Invalid timestamp: ${o}`}],isError:!0};l=g.getTime(),p=N.getTimelineAroundTimestamp(l,n,a,d)}else return{content:[{type:"text",text:'Invalid anchor: must be observation ID (number), session ID (e.g., "S123"), or ISO timestamp'}],isError:!0};let m=[...p.observations.map(g=>({type:"observation",data:g,epoch:g.created_at_epoch})),...p.sessions.map(g=>({type:"session",data:g,epoch:g.created_at_epoch})),...p.prompts.map(g=>({type:"prompt",data:g,epoch:g.created_at_epoch}))];if(m.sort((g,I)=>g.epoch-I.epoch),m.length===0)return{content:[{type:"text",text:`No context found around ${new Date(l).toLocaleString()} (${n} records before, ${a} records after)`}]};let E=[];E.push(`# Timeline around anchor: ${u}`),E.push(`**Window:** ${n} records before \u2192 ${a} records after | **Items:** ${m.length} (${p.observations.length} obs, ${p.sessions.length} sessions, ${p.prompts.length} prompts)`),E.push(""),E.push("**Legend:** \u{1F3AF} session-request | \u{1F534} bugfix | \u{1F7E3} feature | \u{1F504} refactor | \u2705 change | \u{1F535} discovery | \u{1F9E0} decision"),E.push("");let x=new Map;for(let g of m){let I=f(g.epoch);x.has(I)||x.set(I,[]),x.get(I).push(g)}let T=Array.from(x.entries()).sort((g,I)=>{let S=new Date(g[0]).getTime(),O=new Date(I[0]).getTime();return S-O});for(let[g,I]of T){E.push(`### ${g}`),E.push("");let S=null,O="",C=!1;for(let v of I){let F=typeof u=="number"&&v.type==="observation"&&v.data.id===u||typeof u=="string"&&u.startsWith("S")&&v.type==="session"&&`S${v.data.id}`===u;if(v.type==="session"){C&&(E.push(""),C=!1,S=null,O="");let y=v.data,U=y.request||"Session summary",R=`claude-mem://session-summary/${y.id}`,A=F?" \u2190 **ANCHOR**":"";E.push(`**\u{1F3AF} #S${y.id}** ${U} (${b(v.epoch)}) [\u2192](${R})${A}`),E.push("")}else if(v.type==="prompt"){C&&(E.push(""),C=!1,S=null,O="");let y=v.data,U=y.prompt.length>100?y.prompt.substring(0,100)+"...":y.prompt;E.push(`**\u{1F4AC} User Prompt #${y.prompt_number}** (${b(v.epoch)})`),E.push(`> ${U}`),E.push("")}else if(v.type==="observation"){let y=v.data,U="General";U!==S&&(C&&E.push(""),E.push(`**${U}**`),E.push("| ID | Time | T | Title | Tokens |"),E.push("|----|------|---|-------|--------|"),S=U,C=!0,O="");let R="\u2022";switch(y.type){case"bugfix":R="\u{1F534}";break;case"feature":R="\u{1F7E3}";break;case"refactor":R="\u{1F504}";break;case"change":R="\u2705";break;case"discovery":R="\u{1F535}";break;case"decision":R="\u{1F9E0}";break}let A=h(v.epoch),D=y.title||"Untitled",B=_(y.narrative),Y=A!==O?A:"\u2033";O=A;let Z=F?" \u2190 **ANCHOR**":"";E.push(`| #${y.id} | ${Y} | ${R} | ${D}${Z} | ~${B} |`)}}C&&E.push("")}return{content:[{type:"text",text:E.join(` +`)}]}}catch(o){return{content:[{type:"text",text:`Timeline query failed: ${o.message}`}],isError:!0}}}},{name:"get_timeline_by_query",description:'Search for observations using natural language and get timeline context around the best match. Two modes: "auto" (default) automatically uses top result as timeline anchor; "interactive" returns top matches for you to choose from. This combines search + timeline into a single operation for faster context discovery.',inputSchema:i.object({query:i.string().describe("Natural language search query to find relevant observations"),mode:i.enum(["auto","interactive"]).default("auto").describe("auto: Automatically use top search result as timeline anchor. interactive: Show top N search results for manual anchor selection."),depth_before:i.number().min(0).max(50).default(10).describe("Number of timeline records before anchor (default: 10)"),depth_after:i.number().min(0).max(50).default(10).describe("Number of timeline records after anchor (default: 10)"),limit:i.number().min(1).max(20).default(5).describe("For interactive mode: number of top search results to display (default: 5)"),project:i.string().optional().describe("Filter by project name")}),handler:async c=>{try{let{query:o,mode:n="auto",depth_before:a=10,depth_after:d=10,limit:l=5,project:u}=c,p=[];if(k)try{console.error("[search-server] Using hybrid semantic search for timeline query");let m=await M(o,100);if(console.error(`[search-server] Chroma returned ${m.ids.length} semantic matches`),m.ids.length>0){let f=Date.now()-7776e6,h=m.ids.filter((b,_)=>{let E=m.metadatas[_];return E&&E.created_at_epoch>f});console.error(`[search-server] ${h.length} results within 90-day window`),h.length>0&&(p=N.getObservationsByIds(h,{orderBy:"date_desc",limit:n==="auto"?1:l}),console.error(`[search-server] Hydrated ${p.length} observations from SQLite`))}}catch(m){console.error("[search-server] Chroma query failed, falling back to FTS5:",m.message)}if(p.length===0&&(console.error("[search-server] Using FTS5 keyword search"),p=$.searchObservations(o,{orderBy:"relevance",limit:n==="auto"?1:l,project:u})),p.length===0)return{content:[{type:"text",text:`No observations found matching "${o}". Try a different search query.`}]};if(n==="interactive"){let m=[];m.push("# Timeline Anchor Search Results"),m.push(""),m.push(`Found ${p.length} observation(s) matching "${o}"`),m.push(""),m.push("To get timeline context around any of these observations, use the `get_context_timeline` tool with the observation ID as the anchor."),m.push(""),m.push(`**Top ${p.length} matches:**`),m.push("");for(let f=0;f({type:"observation",data:S,epoch:S.created_at_epoch})),...f.sessions.map(S=>({type:"session",data:S,epoch:S.created_at_epoch})),...f.prompts.map(S=>({type:"prompt",data:S,epoch:S.created_at_epoch}))];if(h.sort((S,O)=>S.epoch-O.epoch),h.length===0)return{content:[{type:"text",text:`Found observation #${m.id} matching "${o}", but no timeline context available (${a} records before, ${d} records after).`}]};let T=[];T.push(`# Timeline for query: "${o}"`),T.push(`**Anchor:** Observation #${m.id} - ${m.title||"Untitled"}`),T.push(`**Window:** ${a} records before \u2192 ${d} records after | **Items:** ${h.length} (${f.observations.length} obs, ${f.sessions.length} sessions, ${f.prompts.length} prompts)`),T.push(""),T.push("**Legend:** \u{1F3AF} session-request | \u{1F534} bugfix | \u{1F7E3} feature | \u{1F504} refactor | \u2705 change | \u{1F535} discovery | \u{1F9E0} decision"),T.push("");let g=new Map;for(let S of h){let O=b(S.epoch);g.has(O)||g.set(O,[]),g.get(O).push(S)}let I=Array.from(g.entries()).sort((S,O)=>{let C=new Date(S[0]).getTime(),v=new Date(O[0]).getTime();return C-v});for(let[S,O]of I){T.push(`### ${S}`),T.push("");let C=null,v="",F=!1;for(let y of O){let U=y.type==="observation"&&y.data.id===m.id;if(y.type==="session"){F&&(T.push(""),F=!1,C=null,v="");let R=y.data,A=R.request||"Session summary",D=`claude-mem://session-summary/${R.id}`;T.push(`**\u{1F3AF} #S${R.id}** ${A} (${E(y.epoch)}) [\u2192](${D})`),T.push("")}else if(y.type==="prompt"){F&&(T.push(""),F=!1,C=null,v="");let R=y.data,A=R.prompt.length>100?R.prompt.substring(0,100)+"...":R.prompt;T.push(`**\u{1F4AC} User Prompt #${R.prompt_number}** (${E(y.epoch)})`),T.push(`> ${A}`),T.push("")}else if(y.type==="observation"){let R=y.data,A="General";A!==C&&(F&&T.push(""),T.push(`**${A}**`),T.push("| ID | Time | T | Title | Tokens |"),T.push("|----|------|---|-------|--------|"),C=A,F=!0,v="");let D="\u2022";switch(R.type){case"bugfix":D="\u{1F534}";break;case"feature":D="\u{1F7E3}";break;case"refactor":D="\u{1F504}";break;case"change":D="\u2705";break;case"discovery":D="\u{1F535}";break;case"decision":D="\u{1F9E0}";break}let B=_(y.epoch),z=R.title||"Untitled",Y=x(R.narrative),ie=B!==v?B:"\u2033";v=B;let ae=U?" \u2190 **ANCHOR**":"";T.push(`| #${R.id} | ${ie} | ${D} | ${z}${ae} | ~${Y} |`)}}F&&T.push("")}return{content:[{type:"text",text:T.join(` +`)}]}}}catch(o){return{content:[{type:"text",text:`Timeline query failed: ${o.message}`}],isError:!0}}}}],J=new he({name:"claude-mem-search",version:"1.0.0"},{capabilities:{tools:{}}});J.setRequestHandler(ge,async()=>({tools:oe.map(c=>({name:c.name,description:c.description,inputSchema:Te(c.inputSchema)}))}));J.setRequestHandler(be,async c=>{let e=oe.find(r=>r.name===c.params.name);if(!e)throw new Error(`Unknown tool: ${c.params.name}`);try{return await e.handler(c.params.arguments||{})}catch(r){return{content:[{type:"text",text:`Tool execution failed: ${r.message}`}],isError:!0}}});async function Ie(){let c=new _e;await J.connect(c),console.error("[search-server] Claude-mem search server started"),setTimeout(async()=>{try{console.error("[search-server] Initializing Chroma client...");let e=new Ee({command:"uvx",args:["chroma-mcp","--client-type","persistent","--data-dir",te],stderr:"ignore"}),r=new fe({name:"claude-mem-search-chroma-client",version:"1.0.0"},{capabilities:{}});await r.connect(e),k=r,console.error("[search-server] Chroma client connected successfully")}catch(e){console.error("[search-server] Failed to initialize Chroma client:",e.message),console.error("[search-server] Falling back to FTS5-only search"),k=null}},0)}Ie().catch(c=>{console.error("[search-server] Fatal error:",c),process.exit(1)}); diff --git a/plugin/scripts/worker-service.cjs b/plugin/scripts/worker-service.cjs index bf3e9a8b..fe2e0e63 100755 --- a/plugin/scripts/worker-service.cjs +++ b/plugin/scripts/worker-service.cjs @@ -432,7 +432,7 @@ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let a=Obje ORDER BY up.created_at_epoch ASC `;try{let d=this.db.prepare(u).all(l,c,...o),v=this.db.prepare(p).all(l,c,...o),m=this.db.prepare(f).all(l,c,...o);return{observations:d,sessions:v.map(h=>({id:h.id,sdk_session_id:h.sdk_session_id,project:h.project,request:h.request,completed:h.completed,next_steps:h.next_steps,created_at:h.created_at,created_at_epoch:h.created_at_epoch})),prompts:m.map(h=>({id:h.id,claude_session_id:h.claude_session_id,project:h.project,prompt:h.prompt_text,created_at:h.created_at,created_at_epoch:h.created_at_epoch}))}}catch(d){return console.error("[SessionStore] Error querying timeline records:",d.message),{observations:[],sessions:[],prompts:[]}}}close(){this.db.close()}};var x={};Pd(x,{BRAND:()=>eD,DIRTY:()=>ps,EMPTY_PATH:()=>Aj,INVALID:()=>_e,NEVER:()=>FD,OK:()=>Tr,ParseStatus:()=>br,Schema:()=>Me,ZodAny:()=>Sa,ZodArray:()=>ta,ZodBigInt:()=>fs,ZodBoolean:()=>ms,ZodBranded:()=>Ei,ZodCatch:()=>Ps,ZodDate:()=>hs,ZodDefault:()=>Ss,ZodDiscriminatedUnion:()=>ic,ZodEffects:()=>lt,ZodEnum:()=>ws,ZodError:()=>Lr,ZodFirstPartyTypeKind:()=>Pe,ZodFunction:()=>cc,ZodIntersection:()=>xs,ZodIssueCode:()=>X,ZodLazy:()=>bs,ZodLiteral:()=>_s,ZodMap:()=>En,ZodNaN:()=>Pn,ZodNativeEnum:()=>Es,ZodNever:()=>wt,ZodNull:()=>gs,ZodNullable:()=>qt,ZodNumber:()=>ds,ZodObject:()=>Mr,ZodOptional:()=>ot,ZodParsedType:()=>oe,ZodPipeline:()=>Si,ZodPromise:()=>Pa,ZodReadonly:()=>Ts,ZodRecord:()=>oc,ZodSchema:()=>Me,ZodSet:()=>Sn,ZodString:()=>Ea,ZodSymbol:()=>_n,ZodTransformer:()=>lt,ZodTuple:()=>$t,ZodType:()=>Me,ZodUndefined:()=>vs,ZodUnion:()=>ys,ZodUnknown:()=>ra,ZodVoid:()=>wn,addIssueToContext:()=>ae,any:()=>lD,array:()=>fD,bigint:()=>sD,boolean:()=>Gb,coerce:()=>qD,custom:()=>Bb,date:()=>nD,datetimeRegex:()=>Ub,defaultErrorMap:()=>Yt,discriminatedUnion:()=>gD,effect:()=>OD,enum:()=>TD,function:()=>ED,getErrorMap:()=>yn,getParsedType:()=>Nt,instanceof:()=>tD,intersection:()=>yD,isAborted:()=>sc,isAsync:()=>xn,isDirty:()=>nc,isValid:()=>wa,late:()=>rD,lazy:()=>SD,literal:()=>PD,makeIssue:()=>wi,map:()=>_D,nan:()=>aD,nativeEnum:()=>RD,never:()=>pD,null:()=>cD,nullable:()=>ID,number:()=>Zb,object:()=>mD,objectUtil:()=>Tp,oboolean:()=>$D,onumber:()=>ND,optional:()=>CD,ostring:()=>DD,pipeline:()=>jD,preprocess:()=>AD,promise:()=>kD,quotelessJson:()=>Oj,record:()=>bD,set:()=>wD,setErrorMap:()=>Ij,strictObject:()=>hD,string:()=>Vb,symbol:()=>iD,transformer:()=>OD,tuple:()=>xD,undefined:()=>oD,union:()=>vD,unknown:()=>uD,util:()=>He,void:()=>dD});var He;(function(r){r.assertEqual=s=>{};function e(s){}r.assertIs=e;function a(s){throw new Error}r.assertNever=a,r.arrayToEnum=s=>{let i={};for(let n of s)i[n]=n;return i},r.getValidEnumValues=s=>{let i=r.objectKeys(s).filter(o=>typeof s[s[o]]!="number"),n={};for(let o of i)n[o]=s[o];return r.objectValues(n)},r.objectValues=s=>r.objectKeys(s).map(function(i){return s[i]}),r.objectKeys=typeof Object.keys=="function"?s=>Object.keys(s):s=>{let i=[];for(let n in s)Object.prototype.hasOwnProperty.call(s,n)&&i.push(n);return i},r.find=(s,i)=>{for(let n of s)if(i(n))return n},r.isInteger=typeof Number.isInteger=="function"?s=>Number.isInteger(s):s=>typeof s=="number"&&Number.isFinite(s)&&Math.floor(s)===s;function t(s,i=" | "){return s.map(n=>typeof n=="string"?`'${n}'`:n).join(i)}r.joinValues=t,r.jsonStringifyReplacer=(s,i)=>typeof i=="bigint"?i.toString():i})(He||(He={}));var Tp;(function(r){r.mergeShapes=(e,a)=>({...e,...a})})(Tp||(Tp={}));var oe=He.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]),Nt=r=>{switch(typeof r){case"undefined":return oe.undefined;case"string":return oe.string;case"number":return Number.isNaN(r)?oe.nan:oe.number;case"boolean":return oe.boolean;case"function":return oe.function;case"bigint":return oe.bigint;case"symbol":return oe.symbol;case"object":return Array.isArray(r)?oe.array:r===null?oe.null:r.then&&typeof r.then=="function"&&r.catch&&typeof r.catch=="function"?oe.promise:typeof Map<"u"&&r instanceof Map?oe.map:typeof Set<"u"&&r instanceof Set?oe.set:typeof Date<"u"&&r instanceof Date?oe.date:oe.object;default:return oe.unknown}};var X=He.arrayToEnum(["invalid_type","invalid_literal","custom","invalid_union","invalid_union_discriminator","invalid_enum_value","unrecognized_keys","invalid_arguments","invalid_return_type","invalid_date","invalid_string","too_small","too_big","invalid_intersection_types","not_multiple_of","not_finite"]),Oj=r=>JSON.stringify(r,null,2).replace(/"([^"]+)":/g,"$1:"),Lr=class r extends Error{get errors(){return this.issues}constructor(e){super(),this.issues=[],this.addIssue=t=>{this.issues=[...this.issues,t]},this.addIssues=(t=[])=>{this.issues=[...this.issues,...t]};let a=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,a):this.__proto__=a,this.name="ZodError",this.issues=e}format(e){let a=e||function(i){return i.message},t={_errors:[]},s=i=>{for(let n of i.issues)if(n.code==="invalid_union")n.unionErrors.map(s);else if(n.code==="invalid_return_type")s(n.returnTypeError);else if(n.code==="invalid_arguments")s(n.argumentsError);else if(n.path.length===0)t._errors.push(a(n));else{let o=t,l=0;for(;la.message){let a={},t=[];for(let s of this.issues)if(s.path.length>0){let i=s.path[0];a[i]=a[i]||[],a[i].push(e(s))}else t.push(e(s));return{formErrors:t,fieldErrors:a}}get formErrors(){return this.flatten()}};Lr.create=r=>new Lr(r);var Cj=(r,e)=>{let a;switch(r.code){case X.invalid_type:r.received===oe.undefined?a="Required":a=`Expected ${r.expected}, received ${r.received}`;break;case X.invalid_literal:a=`Invalid literal value, expected ${JSON.stringify(r.expected,He.jsonStringifyReplacer)}`;break;case X.unrecognized_keys:a=`Unrecognized key(s) in object: ${He.joinValues(r.keys,", ")}`;break;case X.invalid_union:a="Invalid input";break;case X.invalid_union_discriminator:a=`Invalid discriminator value. Expected ${He.joinValues(r.options)}`;break;case X.invalid_enum_value:a=`Invalid enum value. Expected ${He.joinValues(r.options)}, received '${r.received}'`;break;case X.invalid_arguments:a="Invalid function arguments";break;case X.invalid_return_type:a="Invalid function return type";break;case X.invalid_date:a="Invalid date";break;case X.invalid_string:typeof r.validation=="object"?"includes"in r.validation?(a=`Invalid input: must include "${r.validation.includes}"`,typeof r.validation.position=="number"&&(a=`${a} at one or more positions greater than or equal to ${r.validation.position}`)):"startsWith"in r.validation?a=`Invalid input: must start with "${r.validation.startsWith}"`:"endsWith"in r.validation?a=`Invalid input: must end with "${r.validation.endsWith}"`:He.assertNever(r.validation):r.validation!=="regex"?a=`Invalid ${r.validation}`:a="Invalid";break;case X.too_small:r.type==="array"?a=`Array must contain ${r.exact?"exactly":r.inclusive?"at least":"more than"} ${r.minimum} element(s)`:r.type==="string"?a=`String must contain ${r.exact?"exactly":r.inclusive?"at least":"over"} ${r.minimum} character(s)`:r.type==="number"?a=`Number must be ${r.exact?"exactly equal to ":r.inclusive?"greater than or equal to ":"greater than "}${r.minimum}`:r.type==="bigint"?a=`Number must be ${r.exact?"exactly equal to ":r.inclusive?"greater than or equal to ":"greater than "}${r.minimum}`:r.type==="date"?a=`Date must be ${r.exact?"exactly equal to ":r.inclusive?"greater than or equal to ":"greater than "}${new Date(Number(r.minimum))}`:a="Invalid input";break;case X.too_big:r.type==="array"?a=`Array must contain ${r.exact?"exactly":r.inclusive?"at most":"less than"} ${r.maximum} element(s)`:r.type==="string"?a=`String must contain ${r.exact?"exactly":r.inclusive?"at most":"under"} ${r.maximum} character(s)`:r.type==="number"?a=`Number must be ${r.exact?"exactly":r.inclusive?"less than or equal to":"less than"} ${r.maximum}`:r.type==="bigint"?a=`BigInt must be ${r.exact?"exactly":r.inclusive?"less than or equal to":"less than"} ${r.maximum}`:r.type==="date"?a=`Date must be ${r.exact?"exactly":r.inclusive?"smaller than or equal to":"smaller than"} ${new Date(Number(r.maximum))}`:a="Invalid input";break;case X.custom:a="Invalid input";break;case X.invalid_intersection_types:a="Intersection results could not be merged";break;case X.not_multiple_of:a=`Number must be a multiple of ${r.multipleOf}`;break;case X.not_finite:a="Number must be finite";break;default:a=e.defaultError,He.assertNever(r)}return{message:a}},Yt=Cj;var qb=Yt;function Ij(r){qb=r}function yn(){return qb}var wi=r=>{let{data:e,path:a,errorMaps:t,issueData:s}=r,i=[...a,...s.path||[]],n={...s,path:i};if(s.message!==void 0)return{...s,path:i,message:s.message};let o="",l=t.filter(c=>!!c).slice().reverse();for(let c of l)o=c(n,{data:e,defaultError:o}).message;return{...s,path:i,message:o}},Aj=[];function ae(r,e){let a=yn(),t=wi({issueData:e,data:r.data,path:r.path,errorMaps:[r.common.contextualErrorMap,r.schemaErrorMap,a,a===Yt?void 0:Yt].filter(s=>!!s)});r.common.issues.push(t)}var br=class r{constructor(){this.value="valid"}dirty(){this.value==="valid"&&(this.value="dirty")}abort(){this.value!=="aborted"&&(this.value="aborted")}static mergeArray(e,a){let t=[];for(let s of a){if(s.status==="aborted")return _e;s.status==="dirty"&&e.dirty(),t.push(s.value)}return{status:e.value,value:t}}static async mergeObjectAsync(e,a){let t=[];for(let s of a){let i=await s.key,n=await s.value;t.push({key:i,value:n})}return r.mergeObjectSync(e,t)}static mergeObjectSync(e,a){let t={};for(let s of a){let{key:i,value:n}=s;if(i.status==="aborted"||n.status==="aborted")return _e;i.status==="dirty"&&e.dirty(),n.status==="dirty"&&e.dirty(),i.value!=="__proto__"&&(typeof n.value<"u"||s.alwaysSet)&&(t[i.value]=n.value)}return{status:e.value,value:t}}},_e=Object.freeze({status:"aborted"}),ps=r=>({status:"dirty",value:r}),Tr=r=>({status:"valid",value:r}),sc=r=>r.status==="aborted",nc=r=>r.status==="dirty",wa=r=>r.status==="valid",xn=r=>typeof Promise<"u"&&r instanceof Promise;var fe;(function(r){r.errToObj=e=>typeof e=="string"?{message:e}:e||{},r.toString=e=>typeof e=="string"?e:e?.message})(fe||(fe={}));var ct=class{constructor(e,a,t,s){this._cachedPath=[],this.parent=e,this.data=a,this._path=t,this._key=s}get path(){return this._cachedPath.length||(Array.isArray(this._key)?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}},Fb=(r,e)=>{if(wa(e))return{success:!0,data:e.value};if(!r.common.issues.length)throw new Error("Validation failed but no issues detected.");return{success:!1,get error(){if(this._error)return this._error;let a=new Lr(r.common.issues);return this._error=a,this._error}}};function $e(r){if(!r)return{};let{errorMap:e,invalid_type_error:a,required_error:t,description:s}=r;if(e&&(a||t))throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);return e?{errorMap:e,description:s}:{errorMap:(n,o)=>{let{message:l}=r;return n.code==="invalid_enum_value"?{message:l??o.defaultError}:typeof o.data>"u"?{message:l??t??o.defaultError}:n.code!=="invalid_type"?{message:o.defaultError}:{message:l??a??o.defaultError}},description:s}}var Me=class{get description(){return this._def.description}_getType(e){return Nt(e.data)}_getOrReturnCtx(e,a){return a||{common:e.parent.common,data:e.data,parsedType:Nt(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}_processInputParams(e){return{status:new br,ctx:{common:e.parent.common,data:e.data,parsedType:Nt(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}}_parseSync(e){let a=this._parse(e);if(xn(a))throw new Error("Synchronous parse encountered promise.");return a}_parseAsync(e){let a=this._parse(e);return Promise.resolve(a)}parse(e,a){let t=this.safeParse(e,a);if(t.success)return t.data;throw t.error}safeParse(e,a){let t={common:{issues:[],async:a?.async??!1,contextualErrorMap:a?.errorMap},path:a?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:Nt(e)},s=this._parseSync({data:e,path:t.path,parent:t});return Fb(t,s)}"~validate"(e){let a={common:{issues:[],async:!!this["~standard"].async},path:[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:Nt(e)};if(!this["~standard"].async)try{let t=this._parseSync({data:e,path:[],parent:a});return wa(t)?{value:t.value}:{issues:a.common.issues}}catch(t){t?.message?.toLowerCase()?.includes("encountered")&&(this["~standard"].async=!0),a.common={issues:[],async:!0}}return this._parseAsync({data:e,path:[],parent:a}).then(t=>wa(t)?{value:t.value}:{issues:a.common.issues})}async parseAsync(e,a){let t=await this.safeParseAsync(e,a);if(t.success)return t.data;throw t.error}async safeParseAsync(e,a){let t={common:{issues:[],contextualErrorMap:a?.errorMap,async:!0},path:a?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:Nt(e)},s=this._parse({data:e,path:t.path,parent:t}),i=await(xn(s)?s:Promise.resolve(s));return Fb(t,i)}refine(e,a){let t=s=>typeof a=="string"||typeof a>"u"?{message:a}:typeof a=="function"?a(s):a;return this._refinement((s,i)=>{let n=e(s),o=()=>i.addIssue({code:X.custom,...t(s)});return typeof Promise<"u"&&n instanceof Promise?n.then(l=>l?!0:(o(),!1)):n?!0:(o(),!1)})}refinement(e,a){return this._refinement((t,s)=>e(t)?!0:(s.addIssue(typeof a=="function"?a(t,s):a),!1))}_refinement(e){return new lt({schema:this,typeName:Pe.ZodEffects,effect:{type:"refinement",refinement:e}})}superRefine(e){return this._refinement(e)}constructor(e){this.spa=this.safeParseAsync,this._def=e,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this),this["~standard"]={version:1,vendor:"zod",validate:a=>this["~validate"](a)}}optional(){return ot.create(this,this._def)}nullable(){return qt.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return ta.create(this)}promise(){return Pa.create(this,this._def)}or(e){return ys.create([this,e],this._def)}and(e){return xs.create(this,e,this._def)}transform(e){return new lt({...$e(this._def),schema:this,typeName:Pe.ZodEffects,effect:{type:"transform",transform:e}})}default(e){let a=typeof e=="function"?e:()=>e;return new Ss({...$e(this._def),innerType:this,defaultValue:a,typeName:Pe.ZodDefault})}brand(){return new Ei({typeName:Pe.ZodBranded,type:this,...$e(this._def)})}catch(e){let a=typeof e=="function"?e:()=>e;return new Ps({...$e(this._def),innerType:this,catchValue:a,typeName:Pe.ZodCatch})}describe(e){let a=this.constructor;return new a({...this._def,description:e})}pipe(e){return Si.create(this,e)}readonly(){return Ts.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}},jj=/^c[^\s-]{8,}$/i,Dj=/^[0-9a-z]+$/,Nj=/^[0-9A-HJKMNP-TV-Z]{26}$/i,$j=/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i,qj=/^[a-z0-9_-]{21}$/i,Fj=/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/,Lj=/^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/,Mj=/^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i,zj="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$",Rp,Uj=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,Hj=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,Bj=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,Vj=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,Zj=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,Gj=/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,Mb="((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))",Wj=new RegExp(`^${Mb}$`);function zb(r){let e="[0-5]\\d";r.precision?e=`${e}\\.\\d{${r.precision}}`:r.precision==null&&(e=`${e}(\\.\\d+)?`);let a=r.precision?"+":"?";return`([01]\\d|2[0-3]):[0-5]\\d(:${e})${a}`}function Qj(r){return new RegExp(`^${zb(r)}$`)}function Ub(r){let e=`${Mb}T${zb(r)}`,a=[];return a.push(r.local?"Z?":"Z"),r.offset&&a.push("([+-]\\d{2}:?\\d{2})"),e=`${e}(${a.join("|")})`,new RegExp(`^${e}$`)}function Kj(r,e){return!!((e==="v4"||!e)&&Uj.test(r)||(e==="v6"||!e)&&Bj.test(r))}function Xj(r,e){if(!Fj.test(r))return!1;try{let[a]=r.split(".");if(!a)return!1;let t=a.replace(/-/g,"+").replace(/_/g,"/").padEnd(a.length+(4-a.length%4)%4,"="),s=JSON.parse(atob(t));return!(typeof s!="object"||s===null||"typ"in s&&s?.typ!=="JWT"||!s.alg||e&&s.alg!==e)}catch{return!1}}function Jj(r,e){return!!((e==="v4"||!e)&&Hj.test(r)||(e==="v6"||!e)&&Vj.test(r))}var Ea=class r extends Me{_parse(e){if(this._def.coerce&&(e.data=String(e.data)),this._getType(e)!==oe.string){let i=this._getOrReturnCtx(e);return ae(i,{code:X.invalid_type,expected:oe.string,received:i.parsedType}),_e}let t=new br,s;for(let i of this._def.checks)if(i.kind==="min")e.data.lengthi.value&&(s=this._getOrReturnCtx(e,s),ae(s,{code:X.too_big,maximum:i.value,type:"string",inclusive:!0,exact:!1,message:i.message}),t.dirty());else if(i.kind==="length"){let n=e.data.length>i.value,o=e.data.lengthe.test(s),{validation:a,code:X.invalid_string,...fe.errToObj(t)})}_addCheck(e){return new r({...this._def,checks:[...this._def.checks,e]})}email(e){return this._addCheck({kind:"email",...fe.errToObj(e)})}url(e){return this._addCheck({kind:"url",...fe.errToObj(e)})}emoji(e){return this._addCheck({kind:"emoji",...fe.errToObj(e)})}uuid(e){return this._addCheck({kind:"uuid",...fe.errToObj(e)})}nanoid(e){return this._addCheck({kind:"nanoid",...fe.errToObj(e)})}cuid(e){return this._addCheck({kind:"cuid",...fe.errToObj(e)})}cuid2(e){return this._addCheck({kind:"cuid2",...fe.errToObj(e)})}ulid(e){return this._addCheck({kind:"ulid",...fe.errToObj(e)})}base64(e){return this._addCheck({kind:"base64",...fe.errToObj(e)})}base64url(e){return this._addCheck({kind:"base64url",...fe.errToObj(e)})}jwt(e){return this._addCheck({kind:"jwt",...fe.errToObj(e)})}ip(e){return this._addCheck({kind:"ip",...fe.errToObj(e)})}cidr(e){return this._addCheck({kind:"cidr",...fe.errToObj(e)})}datetime(e){return typeof e=="string"?this._addCheck({kind:"datetime",precision:null,offset:!1,local:!1,message:e}):this._addCheck({kind:"datetime",precision:typeof e?.precision>"u"?null:e?.precision,offset:e?.offset??!1,local:e?.local??!1,...fe.errToObj(e?.message)})}date(e){return this._addCheck({kind:"date",message:e})}time(e){return typeof e=="string"?this._addCheck({kind:"time",precision:null,message:e}):this._addCheck({kind:"time",precision:typeof e?.precision>"u"?null:e?.precision,...fe.errToObj(e?.message)})}duration(e){return this._addCheck({kind:"duration",...fe.errToObj(e)})}regex(e,a){return this._addCheck({kind:"regex",regex:e,...fe.errToObj(a)})}includes(e,a){return this._addCheck({kind:"includes",value:e,position:a?.position,...fe.errToObj(a?.message)})}startsWith(e,a){return this._addCheck({kind:"startsWith",value:e,...fe.errToObj(a)})}endsWith(e,a){return this._addCheck({kind:"endsWith",value:e,...fe.errToObj(a)})}min(e,a){return this._addCheck({kind:"min",value:e,...fe.errToObj(a)})}max(e,a){return this._addCheck({kind:"max",value:e,...fe.errToObj(a)})}length(e,a){return this._addCheck({kind:"length",value:e,...fe.errToObj(a)})}nonempty(e){return this.min(1,fe.errToObj(e))}trim(){return new r({...this._def,checks:[...this._def.checks,{kind:"trim"}]})}toLowerCase(){return new r({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]})}toUpperCase(){return new r({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}get isDatetime(){return!!this._def.checks.find(e=>e.kind==="datetime")}get isDate(){return!!this._def.checks.find(e=>e.kind==="date")}get isTime(){return!!this._def.checks.find(e=>e.kind==="time")}get isDuration(){return!!this._def.checks.find(e=>e.kind==="duration")}get isEmail(){return!!this._def.checks.find(e=>e.kind==="email")}get isURL(){return!!this._def.checks.find(e=>e.kind==="url")}get isEmoji(){return!!this._def.checks.find(e=>e.kind==="emoji")}get isUUID(){return!!this._def.checks.find(e=>e.kind==="uuid")}get isNANOID(){return!!this._def.checks.find(e=>e.kind==="nanoid")}get isCUID(){return!!this._def.checks.find(e=>e.kind==="cuid")}get isCUID2(){return!!this._def.checks.find(e=>e.kind==="cuid2")}get isULID(){return!!this._def.checks.find(e=>e.kind==="ulid")}get isIP(){return!!this._def.checks.find(e=>e.kind==="ip")}get isCIDR(){return!!this._def.checks.find(e=>e.kind==="cidr")}get isBase64(){return!!this._def.checks.find(e=>e.kind==="base64")}get isBase64url(){return!!this._def.checks.find(e=>e.kind==="base64url")}get minLength(){let e=null;for(let a of this._def.checks)a.kind==="min"&&(e===null||a.value>e)&&(e=a.value);return e}get maxLength(){let e=null;for(let a of this._def.checks)a.kind==="max"&&(e===null||a.valuenew Ea({checks:[],typeName:Pe.ZodString,coerce:r?.coerce??!1,...$e(r)});function Yj(r,e){let a=(r.toString().split(".")[1]||"").length,t=(e.toString().split(".")[1]||"").length,s=a>t?a:t,i=Number.parseInt(r.toFixed(s).replace(".","")),n=Number.parseInt(e.toFixed(s).replace(".",""));return i%n/10**s}var ds=class r extends Me{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(e){if(this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!==oe.number){let i=this._getOrReturnCtx(e);return ae(i,{code:X.invalid_type,expected:oe.number,received:i.parsedType}),_e}let t,s=new br;for(let i of this._def.checks)i.kind==="int"?He.isInteger(e.data)||(t=this._getOrReturnCtx(e,t),ae(t,{code:X.invalid_type,expected:"integer",received:"float",message:i.message}),s.dirty()):i.kind==="min"?(i.inclusive?e.datai.value:e.data>=i.value)&&(t=this._getOrReturnCtx(e,t),ae(t,{code:X.too_big,maximum:i.value,type:"number",inclusive:i.inclusive,exact:!1,message:i.message}),s.dirty()):i.kind==="multipleOf"?Yj(e.data,i.value)!==0&&(t=this._getOrReturnCtx(e,t),ae(t,{code:X.not_multiple_of,multipleOf:i.value,message:i.message}),s.dirty()):i.kind==="finite"?Number.isFinite(e.data)||(t=this._getOrReturnCtx(e,t),ae(t,{code:X.not_finite,message:i.message}),s.dirty()):He.assertNever(i);return{status:s.value,value:e.data}}gte(e,a){return this.setLimit("min",e,!0,fe.toString(a))}gt(e,a){return this.setLimit("min",e,!1,fe.toString(a))}lte(e,a){return this.setLimit("max",e,!0,fe.toString(a))}lt(e,a){return this.setLimit("max",e,!1,fe.toString(a))}setLimit(e,a,t,s){return new r({...this._def,checks:[...this._def.checks,{kind:e,value:a,inclusive:t,message:fe.toString(s)}]})}_addCheck(e){return new r({...this._def,checks:[...this._def.checks,e]})}int(e){return this._addCheck({kind:"int",message:fe.toString(e)})}positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,message:fe.toString(e)})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,message:fe.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,message:fe.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,message:fe.toString(e)})}multipleOf(e,a){return this._addCheck({kind:"multipleOf",value:e,message:fe.toString(a)})}finite(e){return this._addCheck({kind:"finite",message:fe.toString(e)})}safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:fe.toString(e)})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:fe.toString(e)})}get minValue(){let e=null;for(let a of this._def.checks)a.kind==="min"&&(e===null||a.value>e)&&(e=a.value);return e}get maxValue(){let e=null;for(let a of this._def.checks)a.kind==="max"&&(e===null||a.valuee.kind==="int"||e.kind==="multipleOf"&&He.isInteger(e.value))}get isFinite(){let e=null,a=null;for(let t of this._def.checks){if(t.kind==="finite"||t.kind==="int"||t.kind==="multipleOf")return!0;t.kind==="min"?(a===null||t.value>a)&&(a=t.value):t.kind==="max"&&(e===null||t.valuenew ds({checks:[],typeName:Pe.ZodNumber,coerce:r?.coerce||!1,...$e(r)});var fs=class r extends Me{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(e){if(this._def.coerce)try{e.data=BigInt(e.data)}catch{return this._getInvalidInput(e)}if(this._getType(e)!==oe.bigint)return this._getInvalidInput(e);let t,s=new br;for(let i of this._def.checks)i.kind==="min"?(i.inclusive?e.datai.value:e.data>=i.value)&&(t=this._getOrReturnCtx(e,t),ae(t,{code:X.too_big,type:"bigint",maximum:i.value,inclusive:i.inclusive,message:i.message}),s.dirty()):i.kind==="multipleOf"?e.data%i.value!==BigInt(0)&&(t=this._getOrReturnCtx(e,t),ae(t,{code:X.not_multiple_of,multipleOf:i.value,message:i.message}),s.dirty()):He.assertNever(i);return{status:s.value,value:e.data}}_getInvalidInput(e){let a=this._getOrReturnCtx(e);return ae(a,{code:X.invalid_type,expected:oe.bigint,received:a.parsedType}),_e}gte(e,a){return this.setLimit("min",e,!0,fe.toString(a))}gt(e,a){return this.setLimit("min",e,!1,fe.toString(a))}lte(e,a){return this.setLimit("max",e,!0,fe.toString(a))}lt(e,a){return this.setLimit("max",e,!1,fe.toString(a))}setLimit(e,a,t,s){return new r({...this._def,checks:[...this._def.checks,{kind:e,value:a,inclusive:t,message:fe.toString(s)}]})}_addCheck(e){return new r({...this._def,checks:[...this._def.checks,e]})}positive(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!1,message:fe.toString(e)})}negative(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!1,message:fe.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!0,message:fe.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!0,message:fe.toString(e)})}multipleOf(e,a){return this._addCheck({kind:"multipleOf",value:e,message:fe.toString(a)})}get minValue(){let e=null;for(let a of this._def.checks)a.kind==="min"&&(e===null||a.value>e)&&(e=a.value);return e}get maxValue(){let e=null;for(let a of this._def.checks)a.kind==="max"&&(e===null||a.valuenew fs({checks:[],typeName:Pe.ZodBigInt,coerce:r?.coerce??!1,...$e(r)});var ms=class extends Me{_parse(e){if(this._def.coerce&&(e.data=!!e.data),this._getType(e)!==oe.boolean){let t=this._getOrReturnCtx(e);return ae(t,{code:X.invalid_type,expected:oe.boolean,received:t.parsedType}),_e}return Tr(e.data)}};ms.create=r=>new ms({typeName:Pe.ZodBoolean,coerce:r?.coerce||!1,...$e(r)});var hs=class r extends Me{_parse(e){if(this._def.coerce&&(e.data=new Date(e.data)),this._getType(e)!==oe.date){let i=this._getOrReturnCtx(e);return ae(i,{code:X.invalid_type,expected:oe.date,received:i.parsedType}),_e}if(Number.isNaN(e.data.getTime())){let i=this._getOrReturnCtx(e);return ae(i,{code:X.invalid_date}),_e}let t=new br,s;for(let i of this._def.checks)i.kind==="min"?e.data.getTime()i.value&&(s=this._getOrReturnCtx(e,s),ae(s,{code:X.too_big,message:i.message,inclusive:!0,exact:!1,maximum:i.value,type:"date"}),t.dirty()):He.assertNever(i);return{status:t.value,value:new Date(e.data.getTime())}}_addCheck(e){return new r({...this._def,checks:[...this._def.checks,e]})}min(e,a){return this._addCheck({kind:"min",value:e.getTime(),message:fe.toString(a)})}max(e,a){return this._addCheck({kind:"max",value:e.getTime(),message:fe.toString(a)})}get minDate(){let e=null;for(let a of this._def.checks)a.kind==="min"&&(e===null||a.value>e)&&(e=a.value);return e!=null?new Date(e):null}get maxDate(){let e=null;for(let a of this._def.checks)a.kind==="max"&&(e===null||a.valuenew hs({checks:[],coerce:r?.coerce||!1,typeName:Pe.ZodDate,...$e(r)});var _n=class extends Me{_parse(e){if(this._getType(e)!==oe.symbol){let t=this._getOrReturnCtx(e);return ae(t,{code:X.invalid_type,expected:oe.symbol,received:t.parsedType}),_e}return Tr(e.data)}};_n.create=r=>new _n({typeName:Pe.ZodSymbol,...$e(r)});var vs=class extends Me{_parse(e){if(this._getType(e)!==oe.undefined){let t=this._getOrReturnCtx(e);return ae(t,{code:X.invalid_type,expected:oe.undefined,received:t.parsedType}),_e}return Tr(e.data)}};vs.create=r=>new vs({typeName:Pe.ZodUndefined,...$e(r)});var gs=class extends Me{_parse(e){if(this._getType(e)!==oe.null){let t=this._getOrReturnCtx(e);return ae(t,{code:X.invalid_type,expected:oe.null,received:t.parsedType}),_e}return Tr(e.data)}};gs.create=r=>new gs({typeName:Pe.ZodNull,...$e(r)});var Sa=class extends Me{constructor(){super(...arguments),this._any=!0}_parse(e){return Tr(e.data)}};Sa.create=r=>new Sa({typeName:Pe.ZodAny,...$e(r)});var ra=class extends Me{constructor(){super(...arguments),this._unknown=!0}_parse(e){return Tr(e.data)}};ra.create=r=>new ra({typeName:Pe.ZodUnknown,...$e(r)});var wt=class extends Me{_parse(e){let a=this._getOrReturnCtx(e);return ae(a,{code:X.invalid_type,expected:oe.never,received:a.parsedType}),_e}};wt.create=r=>new wt({typeName:Pe.ZodNever,...$e(r)});var wn=class extends Me{_parse(e){if(this._getType(e)!==oe.undefined){let t=this._getOrReturnCtx(e);return ae(t,{code:X.invalid_type,expected:oe.void,received:t.parsedType}),_e}return Tr(e.data)}};wn.create=r=>new wn({typeName:Pe.ZodVoid,...$e(r)});var ta=class r extends Me{_parse(e){let{ctx:a,status:t}=this._processInputParams(e),s=this._def;if(a.parsedType!==oe.array)return ae(a,{code:X.invalid_type,expected:oe.array,received:a.parsedType}),_e;if(s.exactLength!==null){let n=a.data.length>s.exactLength.value,o=a.data.lengths.maxLength.value&&(ae(a,{code:X.too_big,maximum:s.maxLength.value,type:"array",inclusive:!0,exact:!1,message:s.maxLength.message}),t.dirty()),a.common.async)return Promise.all([...a.data].map((n,o)=>s.type._parseAsync(new ct(a,n,a.path,o)))).then(n=>br.mergeArray(t,n));let i=[...a.data].map((n,o)=>s.type._parseSync(new ct(a,n,a.path,o)));return br.mergeArray(t,i)}get element(){return this._def.type}min(e,a){return new r({...this._def,minLength:{value:e,message:fe.toString(a)}})}max(e,a){return new r({...this._def,maxLength:{value:e,message:fe.toString(a)}})}length(e,a){return new r({...this._def,exactLength:{value:e,message:fe.toString(a)}})}nonempty(e){return this.min(1,e)}};ta.create=(r,e)=>new ta({type:r,minLength:null,maxLength:null,exactLength:null,typeName:Pe.ZodArray,...$e(e)});function bn(r){if(r instanceof Mr){let e={};for(let a in r.shape){let t=r.shape[a];e[a]=ot.create(bn(t))}return new Mr({...r._def,shape:()=>e})}else return r instanceof ta?new ta({...r._def,type:bn(r.element)}):r instanceof ot?ot.create(bn(r.unwrap())):r instanceof qt?qt.create(bn(r.unwrap())):r instanceof $t?$t.create(r.items.map(e=>bn(e))):r}var Mr=class r extends Me{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(this._cached!==null)return this._cached;let e=this._def.shape(),a=He.objectKeys(e);return this._cached={shape:e,keys:a},this._cached}_parse(e){if(this._getType(e)!==oe.object){let c=this._getOrReturnCtx(e);return ae(c,{code:X.invalid_type,expected:oe.object,received:c.parsedType}),_e}let{status:t,ctx:s}=this._processInputParams(e),{shape:i,keys:n}=this._getCached(),o=[];if(!(this._def.catchall instanceof wt&&this._def.unknownKeys==="strip"))for(let c in s.data)n.includes(c)||o.push(c);let l=[];for(let c of n){let u=i[c],p=s.data[c];l.push({key:{status:"valid",value:c},value:u._parse(new ct(s,p,s.path,c)),alwaysSet:c in s.data})}if(this._def.catchall instanceof wt){let c=this._def.unknownKeys;if(c==="passthrough")for(let u of o)l.push({key:{status:"valid",value:u},value:{status:"valid",value:s.data[u]}});else if(c==="strict")o.length>0&&(ae(s,{code:X.unrecognized_keys,keys:o}),t.dirty());else if(c!=="strip")throw new Error("Internal ZodObject error: invalid unknownKeys value.")}else{let c=this._def.catchall;for(let u of o){let p=s.data[u];l.push({key:{status:"valid",value:u},value:c._parse(new ct(s,p,s.path,u)),alwaysSet:u in s.data})}}return s.common.async?Promise.resolve().then(async()=>{let c=[];for(let u of l){let p=await u.key,f=await u.value;c.push({key:p,value:f,alwaysSet:u.alwaysSet})}return c}).then(c=>br.mergeObjectSync(t,c)):br.mergeObjectSync(t,l)}get shape(){return this._def.shape()}strict(e){return fe.errToObj,new r({...this._def,unknownKeys:"strict",...e!==void 0?{errorMap:(a,t)=>{let s=this._def.errorMap?.(a,t).message??t.defaultError;return a.code==="unrecognized_keys"?{message:fe.errToObj(e).message??s}:{message:s}}}:{}})}strip(){return new r({...this._def,unknownKeys:"strip"})}passthrough(){return new r({...this._def,unknownKeys:"passthrough"})}extend(e){return new r({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){return new r({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:Pe.ZodObject})}setKey(e,a){return this.augment({[e]:a})}catchall(e){return new r({...this._def,catchall:e})}pick(e){let a={};for(let t of He.objectKeys(e))e[t]&&this.shape[t]&&(a[t]=this.shape[t]);return new r({...this._def,shape:()=>a})}omit(e){let a={};for(let t of He.objectKeys(this.shape))e[t]||(a[t]=this.shape[t]);return new r({...this._def,shape:()=>a})}deepPartial(){return bn(this)}partial(e){let a={};for(let t of He.objectKeys(this.shape)){let s=this.shape[t];e&&!e[t]?a[t]=s:a[t]=s.optional()}return new r({...this._def,shape:()=>a})}required(e){let a={};for(let t of He.objectKeys(this.shape))if(e&&!e[t])a[t]=this.shape[t];else{let i=this.shape[t];for(;i instanceof ot;)i=i._def.innerType;a[t]=i}return new r({...this._def,shape:()=>a})}keyof(){return Hb(He.objectKeys(this.shape))}};Mr.create=(r,e)=>new Mr({shape:()=>r,unknownKeys:"strip",catchall:wt.create(),typeName:Pe.ZodObject,...$e(e)});Mr.strictCreate=(r,e)=>new Mr({shape:()=>r,unknownKeys:"strict",catchall:wt.create(),typeName:Pe.ZodObject,...$e(e)});Mr.lazycreate=(r,e)=>new Mr({shape:r,unknownKeys:"strip",catchall:wt.create(),typeName:Pe.ZodObject,...$e(e)});var ys=class extends Me{_parse(e){let{ctx:a}=this._processInputParams(e),t=this._def.options;function s(i){for(let o of i)if(o.result.status==="valid")return o.result;for(let o of i)if(o.result.status==="dirty")return a.common.issues.push(...o.ctx.common.issues),o.result;let n=i.map(o=>new Lr(o.ctx.common.issues));return ae(a,{code:X.invalid_union,unionErrors:n}),_e}if(a.common.async)return Promise.all(t.map(async i=>{let n={...a,common:{...a.common,issues:[]},parent:null};return{result:await i._parseAsync({data:a.data,path:a.path,parent:n}),ctx:n}})).then(s);{let i,n=[];for(let l of t){let c={...a,common:{...a.common,issues:[]},parent:null},u=l._parseSync({data:a.data,path:a.path,parent:c});if(u.status==="valid")return u;u.status==="dirty"&&!i&&(i={result:u,ctx:c}),c.common.issues.length&&n.push(c.common.issues)}if(i)return a.common.issues.push(...i.ctx.common.issues),i.result;let o=n.map(l=>new Lr(l));return ae(a,{code:X.invalid_union,unionErrors:o}),_e}}get options(){return this._def.options}};ys.create=(r,e)=>new ys({options:r,typeName:Pe.ZodUnion,...$e(e)});var ea=r=>r instanceof bs?ea(r.schema):r instanceof lt?ea(r.innerType()):r instanceof _s?[r.value]:r instanceof ws?r.options:r instanceof Es?He.objectValues(r.enum):r instanceof Ss?ea(r._def.innerType):r instanceof vs?[void 0]:r instanceof gs?[null]:r instanceof ot?[void 0,...ea(r.unwrap())]:r instanceof qt?[null,...ea(r.unwrap())]:r instanceof Ei||r instanceof Ts?ea(r.unwrap()):r instanceof Ps?ea(r._def.innerType):[],ic=class r extends Me{_parse(e){let{ctx:a}=this._processInputParams(e);if(a.parsedType!==oe.object)return ae(a,{code:X.invalid_type,expected:oe.object,received:a.parsedType}),_e;let t=this.discriminator,s=a.data[t],i=this.optionsMap.get(s);return i?a.common.async?i._parseAsync({data:a.data,path:a.path,parent:a}):i._parseSync({data:a.data,path:a.path,parent:a}):(ae(a,{code:X.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[t]}),_e)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,a,t){let s=new Map;for(let i of a){let n=ea(i.shape[e]);if(!n.length)throw new Error(`A discriminator value for key \`${e}\` could not be extracted from all schema options`);for(let o of n){if(s.has(o))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(o)}`);s.set(o,i)}}return new r({typeName:Pe.ZodDiscriminatedUnion,discriminator:e,options:a,optionsMap:s,...$e(t)})}};function kp(r,e){let a=Nt(r),t=Nt(e);if(r===e)return{valid:!0,data:r};if(a===oe.object&&t===oe.object){let s=He.objectKeys(e),i=He.objectKeys(r).filter(o=>s.indexOf(o)!==-1),n={...r,...e};for(let o of i){let l=kp(r[o],e[o]);if(!l.valid)return{valid:!1};n[o]=l.data}return{valid:!0,data:n}}else if(a===oe.array&&t===oe.array){if(r.length!==e.length)return{valid:!1};let s=[];for(let i=0;i{if(sc(i)||sc(n))return _e;let o=kp(i.value,n.value);return o.valid?((nc(i)||nc(n))&&a.dirty(),{status:a.value,value:o.data}):(ae(t,{code:X.invalid_intersection_types}),_e)};return t.common.async?Promise.all([this._def.left._parseAsync({data:t.data,path:t.path,parent:t}),this._def.right._parseAsync({data:t.data,path:t.path,parent:t})]).then(([i,n])=>s(i,n)):s(this._def.left._parseSync({data:t.data,path:t.path,parent:t}),this._def.right._parseSync({data:t.data,path:t.path,parent:t}))}};xs.create=(r,e,a)=>new xs({left:r,right:e,typeName:Pe.ZodIntersection,...$e(a)});var $t=class r extends Me{_parse(e){let{status:a,ctx:t}=this._processInputParams(e);if(t.parsedType!==oe.array)return ae(t,{code:X.invalid_type,expected:oe.array,received:t.parsedType}),_e;if(t.data.lengththis._def.items.length&&(ae(t,{code:X.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),a.dirty());let i=[...t.data].map((n,o)=>{let l=this._def.items[o]||this._def.rest;return l?l._parse(new ct(t,n,t.path,o)):null}).filter(n=>!!n);return t.common.async?Promise.all(i).then(n=>br.mergeArray(a,n)):br.mergeArray(a,i)}get items(){return this._def.items}rest(e){return new r({...this._def,rest:e})}};$t.create=(r,e)=>{if(!Array.isArray(r))throw new Error("You must pass an array of schemas to z.tuple([ ... ])");return new $t({items:r,typeName:Pe.ZodTuple,rest:null,...$e(e)})};var oc=class r extends Me{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){let{status:a,ctx:t}=this._processInputParams(e);if(t.parsedType!==oe.object)return ae(t,{code:X.invalid_type,expected:oe.object,received:t.parsedType}),_e;let s=[],i=this._def.keyType,n=this._def.valueType;for(let o in t.data)s.push({key:i._parse(new ct(t,o,t.path,o)),value:n._parse(new ct(t,t.data[o],t.path,o)),alwaysSet:o in t.data});return t.common.async?br.mergeObjectAsync(a,s):br.mergeObjectSync(a,s)}get element(){return this._def.valueType}static create(e,a,t){return a instanceof Me?new r({keyType:e,valueType:a,typeName:Pe.ZodRecord,...$e(t)}):new r({keyType:Ea.create(),valueType:e,typeName:Pe.ZodRecord,...$e(a)})}},En=class extends Me{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){let{status:a,ctx:t}=this._processInputParams(e);if(t.parsedType!==oe.map)return ae(t,{code:X.invalid_type,expected:oe.map,received:t.parsedType}),_e;let s=this._def.keyType,i=this._def.valueType,n=[...t.data.entries()].map(([o,l],c)=>({key:s._parse(new ct(t,o,t.path,[c,"key"])),value:i._parse(new ct(t,l,t.path,[c,"value"]))}));if(t.common.async){let o=new Map;return Promise.resolve().then(async()=>{for(let l of n){let c=await l.key,u=await l.value;if(c.status==="aborted"||u.status==="aborted")return _e;(c.status==="dirty"||u.status==="dirty")&&a.dirty(),o.set(c.value,u.value)}return{status:a.value,value:o}})}else{let o=new Map;for(let l of n){let c=l.key,u=l.value;if(c.status==="aborted"||u.status==="aborted")return _e;(c.status==="dirty"||u.status==="dirty")&&a.dirty(),o.set(c.value,u.value)}return{status:a.value,value:o}}}};En.create=(r,e,a)=>new En({valueType:e,keyType:r,typeName:Pe.ZodMap,...$e(a)});var Sn=class r extends Me{_parse(e){let{status:a,ctx:t}=this._processInputParams(e);if(t.parsedType!==oe.set)return ae(t,{code:X.invalid_type,expected:oe.set,received:t.parsedType}),_e;let s=this._def;s.minSize!==null&&t.data.sizes.maxSize.value&&(ae(t,{code:X.too_big,maximum:s.maxSize.value,type:"set",inclusive:!0,exact:!1,message:s.maxSize.message}),a.dirty());let i=this._def.valueType;function n(l){let c=new Set;for(let u of l){if(u.status==="aborted")return _e;u.status==="dirty"&&a.dirty(),c.add(u.value)}return{status:a.value,value:c}}let o=[...t.data.values()].map((l,c)=>i._parse(new ct(t,l,t.path,c)));return t.common.async?Promise.all(o).then(l=>n(l)):n(o)}min(e,a){return new r({...this._def,minSize:{value:e,message:fe.toString(a)}})}max(e,a){return new r({...this._def,maxSize:{value:e,message:fe.toString(a)}})}size(e,a){return this.min(e,a).max(e,a)}nonempty(e){return this.min(1,e)}};Sn.create=(r,e)=>new Sn({valueType:r,minSize:null,maxSize:null,typeName:Pe.ZodSet,...$e(e)});var cc=class r extends Me{constructor(){super(...arguments),this.validate=this.implement}_parse(e){let{ctx:a}=this._processInputParams(e);if(a.parsedType!==oe.function)return ae(a,{code:X.invalid_type,expected:oe.function,received:a.parsedType}),_e;function t(o,l){return wi({data:o,path:a.path,errorMaps:[a.common.contextualErrorMap,a.schemaErrorMap,yn(),Yt].filter(c=>!!c),issueData:{code:X.invalid_arguments,argumentsError:l}})}function s(o,l){return wi({data:o,path:a.path,errorMaps:[a.common.contextualErrorMap,a.schemaErrorMap,yn(),Yt].filter(c=>!!c),issueData:{code:X.invalid_return_type,returnTypeError:l}})}let i={errorMap:a.common.contextualErrorMap},n=a.data;if(this._def.returns instanceof Pa){let o=this;return Tr(async function(...l){let c=new Lr([]),u=await o._def.args.parseAsync(l,i).catch(d=>{throw c.addIssue(t(l,d)),c}),p=await Reflect.apply(n,this,u);return await o._def.returns._def.type.parseAsync(p,i).catch(d=>{throw c.addIssue(s(p,d)),c})})}else{let o=this;return Tr(function(...l){let c=o._def.args.safeParse(l,i);if(!c.success)throw new Lr([t(l,c.error)]);let u=Reflect.apply(n,this,c.data),p=o._def.returns.safeParse(u,i);if(!p.success)throw new Lr([s(u,p.error)]);return p.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new r({...this._def,args:$t.create(e).rest(ra.create())})}returns(e){return new r({...this._def,returns:e})}implement(e){return this.parse(e)}strictImplement(e){return this.parse(e)}static create(e,a,t){return new r({args:e||$t.create([]).rest(ra.create()),returns:a||ra.create(),typeName:Pe.ZodFunction,...$e(t)})}},bs=class extends Me{get schema(){return this._def.getter()}_parse(e){let{ctx:a}=this._processInputParams(e);return this._def.getter()._parse({data:a.data,path:a.path,parent:a})}};bs.create=(r,e)=>new bs({getter:r,typeName:Pe.ZodLazy,...$e(e)});var _s=class extends Me{_parse(e){if(e.data!==this._def.value){let a=this._getOrReturnCtx(e);return ae(a,{received:a.data,code:X.invalid_literal,expected:this._def.value}),_e}return{status:"valid",value:e.data}}get value(){return this._def.value}};_s.create=(r,e)=>new _s({value:r,typeName:Pe.ZodLiteral,...$e(e)});function Hb(r,e){return new ws({values:r,typeName:Pe.ZodEnum,...$e(e)})}var ws=class r extends Me{_parse(e){if(typeof e.data!="string"){let a=this._getOrReturnCtx(e),t=this._def.values;return ae(a,{expected:He.joinValues(t),received:a.parsedType,code:X.invalid_type}),_e}if(this._cache||(this._cache=new Set(this._def.values)),!this._cache.has(e.data)){let a=this._getOrReturnCtx(e),t=this._def.values;return ae(a,{received:a.data,code:X.invalid_enum_value,options:t}),_e}return Tr(e.data)}get options(){return this._def.values}get enum(){let e={};for(let a of this._def.values)e[a]=a;return e}get Values(){let e={};for(let a of this._def.values)e[a]=a;return e}get Enum(){let e={};for(let a of this._def.values)e[a]=a;return e}extract(e,a=this._def){return r.create(e,{...this._def,...a})}exclude(e,a=this._def){return r.create(this.options.filter(t=>!e.includes(t)),{...this._def,...a})}};ws.create=Hb;var Es=class extends Me{_parse(e){let a=He.getValidEnumValues(this._def.values),t=this._getOrReturnCtx(e);if(t.parsedType!==oe.string&&t.parsedType!==oe.number){let s=He.objectValues(a);return ae(t,{expected:He.joinValues(s),received:t.parsedType,code:X.invalid_type}),_e}if(this._cache||(this._cache=new Set(He.getValidEnumValues(this._def.values))),!this._cache.has(e.data)){let s=He.objectValues(a);return ae(t,{received:t.data,code:X.invalid_enum_value,options:s}),_e}return Tr(e.data)}get enum(){return this._def.values}};Es.create=(r,e)=>new Es({values:r,typeName:Pe.ZodNativeEnum,...$e(e)});var Pa=class extends Me{unwrap(){return this._def.type}_parse(e){let{ctx:a}=this._processInputParams(e);if(a.parsedType!==oe.promise&&a.common.async===!1)return ae(a,{code:X.invalid_type,expected:oe.promise,received:a.parsedType}),_e;let t=a.parsedType===oe.promise?a.data:Promise.resolve(a.data);return Tr(t.then(s=>this._def.type.parseAsync(s,{path:a.path,errorMap:a.common.contextualErrorMap})))}};Pa.create=(r,e)=>new Pa({type:r,typeName:Pe.ZodPromise,...$e(e)});var lt=class extends Me{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===Pe.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(e){let{status:a,ctx:t}=this._processInputParams(e),s=this._def.effect||null,i={addIssue:n=>{ae(t,n),n.fatal?a.abort():a.dirty()},get path(){return t.path}};if(i.addIssue=i.addIssue.bind(i),s.type==="preprocess"){let n=s.transform(t.data,i);if(t.common.async)return Promise.resolve(n).then(async o=>{if(a.value==="aborted")return _e;let l=await this._def.schema._parseAsync({data:o,path:t.path,parent:t});return l.status==="aborted"?_e:l.status==="dirty"?ps(l.value):a.value==="dirty"?ps(l.value):l});{if(a.value==="aborted")return _e;let o=this._def.schema._parseSync({data:n,path:t.path,parent:t});return o.status==="aborted"?_e:o.status==="dirty"?ps(o.value):a.value==="dirty"?ps(o.value):o}}if(s.type==="refinement"){let n=o=>{let l=s.refinement(o,i);if(t.common.async)return Promise.resolve(l);if(l instanceof Promise)throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");return o};if(t.common.async===!1){let o=this._def.schema._parseSync({data:t.data,path:t.path,parent:t});return o.status==="aborted"?_e:(o.status==="dirty"&&a.dirty(),n(o.value),{status:a.value,value:o.value})}else return this._def.schema._parseAsync({data:t.data,path:t.path,parent:t}).then(o=>o.status==="aborted"?_e:(o.status==="dirty"&&a.dirty(),n(o.value).then(()=>({status:a.value,value:o.value}))))}if(s.type==="transform")if(t.common.async===!1){let n=this._def.schema._parseSync({data:t.data,path:t.path,parent:t});if(!wa(n))return _e;let o=s.transform(n.value,i);if(o instanceof Promise)throw new Error("Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.");return{status:a.value,value:o}}else return this._def.schema._parseAsync({data:t.data,path:t.path,parent:t}).then(n=>wa(n)?Promise.resolve(s.transform(n.value,i)).then(o=>({status:a.value,value:o})):_e);He.assertNever(s)}};lt.create=(r,e,a)=>new lt({schema:r,typeName:Pe.ZodEffects,effect:e,...$e(a)});lt.createWithPreprocess=(r,e,a)=>new lt({schema:e,effect:{type:"preprocess",transform:r},typeName:Pe.ZodEffects,...$e(a)});var ot=class extends Me{_parse(e){return this._getType(e)===oe.undefined?Tr(void 0):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}};ot.create=(r,e)=>new ot({innerType:r,typeName:Pe.ZodOptional,...$e(e)});var qt=class extends Me{_parse(e){return this._getType(e)===oe.null?Tr(null):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}};qt.create=(r,e)=>new qt({innerType:r,typeName:Pe.ZodNullable,...$e(e)});var Ss=class extends Me{_parse(e){let{ctx:a}=this._processInputParams(e),t=a.data;return a.parsedType===oe.undefined&&(t=this._def.defaultValue()),this._def.innerType._parse({data:t,path:a.path,parent:a})}removeDefault(){return this._def.innerType}};Ss.create=(r,e)=>new Ss({innerType:r,typeName:Pe.ZodDefault,defaultValue:typeof e.default=="function"?e.default:()=>e.default,...$e(e)});var Ps=class extends Me{_parse(e){let{ctx:a}=this._processInputParams(e),t={...a,common:{...a.common,issues:[]}},s=this._def.innerType._parse({data:t.data,path:t.path,parent:{...t}});return xn(s)?s.then(i=>({status:"valid",value:i.status==="valid"?i.value:this._def.catchValue({get error(){return new Lr(t.common.issues)},input:t.data})})):{status:"valid",value:s.status==="valid"?s.value:this._def.catchValue({get error(){return new Lr(t.common.issues)},input:t.data})}}removeCatch(){return this._def.innerType}};Ps.create=(r,e)=>new Ps({innerType:r,typeName:Pe.ZodCatch,catchValue:typeof e.catch=="function"?e.catch:()=>e.catch,...$e(e)});var Pn=class extends Me{_parse(e){if(this._getType(e)!==oe.nan){let t=this._getOrReturnCtx(e);return ae(t,{code:X.invalid_type,expected:oe.nan,received:t.parsedType}),_e}return{status:"valid",value:e.data}}};Pn.create=r=>new Pn({typeName:Pe.ZodNaN,...$e(r)});var eD=Symbol("zod_brand"),Ei=class extends Me{_parse(e){let{ctx:a}=this._processInputParams(e),t=a.data;return this._def.type._parse({data:t,path:a.path,parent:a})}unwrap(){return this._def.type}},Si=class r extends Me{_parse(e){let{status:a,ctx:t}=this._processInputParams(e);if(t.common.async)return(async()=>{let i=await this._def.in._parseAsync({data:t.data,path:t.path,parent:t});return i.status==="aborted"?_e:i.status==="dirty"?(a.dirty(),ps(i.value)):this._def.out._parseAsync({data:i.value,path:t.path,parent:t})})();{let s=this._def.in._parseSync({data:t.data,path:t.path,parent:t});return s.status==="aborted"?_e:s.status==="dirty"?(a.dirty(),{status:"dirty",value:s.value}):this._def.out._parseSync({data:s.value,path:t.path,parent:t})}}static create(e,a){return new r({in:e,out:a,typeName:Pe.ZodPipeline})}},Ts=class extends Me{_parse(e){let a=this._def.innerType._parse(e),t=s=>(wa(s)&&(s.value=Object.freeze(s.value)),s);return xn(a)?a.then(s=>t(s)):t(a)}unwrap(){return this._def.innerType}};Ts.create=(r,e)=>new Ts({innerType:r,typeName:Pe.ZodReadonly,...$e(e)});function Lb(r,e){let a=typeof r=="function"?r(e):typeof r=="string"?{message:r}:r;return typeof a=="string"?{message:a}:a}function Bb(r,e={},a){return r?Sa.create().superRefine((t,s)=>{let i=r(t);if(i instanceof Promise)return i.then(n=>{if(!n){let o=Lb(e,t),l=o.fatal??a??!0;s.addIssue({code:"custom",...o,fatal:l})}});if(!i){let n=Lb(e,t),o=n.fatal??a??!0;s.addIssue({code:"custom",...n,fatal:o})}}):Sa.create()}var rD={object:Mr.lazycreate},Pe;(function(r){r.ZodString="ZodString",r.ZodNumber="ZodNumber",r.ZodNaN="ZodNaN",r.ZodBigInt="ZodBigInt",r.ZodBoolean="ZodBoolean",r.ZodDate="ZodDate",r.ZodSymbol="ZodSymbol",r.ZodUndefined="ZodUndefined",r.ZodNull="ZodNull",r.ZodAny="ZodAny",r.ZodUnknown="ZodUnknown",r.ZodNever="ZodNever",r.ZodVoid="ZodVoid",r.ZodArray="ZodArray",r.ZodObject="ZodObject",r.ZodUnion="ZodUnion",r.ZodDiscriminatedUnion="ZodDiscriminatedUnion",r.ZodIntersection="ZodIntersection",r.ZodTuple="ZodTuple",r.ZodRecord="ZodRecord",r.ZodMap="ZodMap",r.ZodSet="ZodSet",r.ZodFunction="ZodFunction",r.ZodLazy="ZodLazy",r.ZodLiteral="ZodLiteral",r.ZodEnum="ZodEnum",r.ZodEffects="ZodEffects",r.ZodNativeEnum="ZodNativeEnum",r.ZodOptional="ZodOptional",r.ZodNullable="ZodNullable",r.ZodDefault="ZodDefault",r.ZodCatch="ZodCatch",r.ZodPromise="ZodPromise",r.ZodBranded="ZodBranded",r.ZodPipeline="ZodPipeline",r.ZodReadonly="ZodReadonly"})(Pe||(Pe={}));var tD=(r,e={message:`Input not instance of ${r.name}`})=>Bb(a=>a instanceof r,e),Vb=Ea.create,Zb=ds.create,aD=Pn.create,sD=fs.create,Gb=ms.create,nD=hs.create,iD=_n.create,oD=vs.create,cD=gs.create,lD=Sa.create,uD=ra.create,pD=wt.create,dD=wn.create,fD=ta.create,mD=Mr.create,hD=Mr.strictCreate,vD=ys.create,gD=ic.create,yD=xs.create,xD=$t.create,bD=oc.create,_D=En.create,wD=Sn.create,ED=cc.create,SD=bs.create,PD=_s.create,TD=ws.create,RD=Es.create,kD=Pa.create,OD=lt.create,CD=ot.create,ID=qt.create,AD=lt.createWithPreprocess,jD=Si.create,DD=()=>Vb().optional(),ND=()=>Zb().optional(),$D=()=>Gb().optional(),qD={string:(r=>Ea.create({...r,coerce:!0})),number:(r=>ds.create({...r,coerce:!0})),boolean:(r=>ms.create({...r,coerce:!0})),bigint:(r=>fs.create({...r,coerce:!0})),date:(r=>hs.create({...r,coerce:!0}))};var FD=_e;var Op="2025-06-18";var Wb=[Op,"2025-03-26","2024-11-05","2024-10-07"],lc="2.0",Qb=x.union([x.string(),x.number().int()]),Kb=x.string(),LD=x.object({progressToken:x.optional(Qb)}).passthrough(),dt=x.object({_meta:x.optional(LD)}).passthrough(),zr=x.object({method:x.string(),params:x.optional(dt)}),Pi=x.object({_meta:x.optional(x.object({}).passthrough())}).passthrough(),Ft=x.object({method:x.string(),params:x.optional(Pi)}),ft=x.object({_meta:x.optional(x.object({}).passthrough())}).passthrough(),uc=x.union([x.string(),x.number().int()]),Xb=x.object({jsonrpc:x.literal(lc),id:uc}).merge(zr).strict(),Jb=r=>Xb.safeParse(r).success,Yb=x.object({jsonrpc:x.literal(lc)}).merge(Ft).strict(),e0=r=>Yb.safeParse(r).success,r0=x.object({jsonrpc:x.literal(lc),id:uc,result:ft}).strict(),Cp=r=>r0.safeParse(r).success,ut;(function(r){r[r.ConnectionClosed=-32e3]="ConnectionClosed",r[r.RequestTimeout=-32001]="RequestTimeout",r[r.ParseError=-32700]="ParseError",r[r.InvalidRequest=-32600]="InvalidRequest",r[r.MethodNotFound=-32601]="MethodNotFound",r[r.InvalidParams=-32602]="InvalidParams",r[r.InternalError=-32603]="InternalError"})(ut||(ut={}));var t0=x.object({jsonrpc:x.literal(lc),id:uc,error:x.object({code:x.number().int(),message:x.string(),data:x.optional(x.unknown())})}).strict(),a0=r=>t0.safeParse(r).success,s0=x.union([Xb,Yb,r0,t0]),Rs=ft.strict(),pc=Ft.extend({method:x.literal("notifications/cancelled"),params:Pi.extend({requestId:uc,reason:x.string().optional()})}),MD=x.object({src:x.string(),mimeType:x.optional(x.string()),sizes:x.optional(x.array(x.string()))}).passthrough(),Ti=x.object({icons:x.array(MD).optional()}).passthrough(),Ri=x.object({name:x.string(),title:x.optional(x.string())}).passthrough(),n0=Ri.extend({version:x.string(),websiteUrl:x.optional(x.string())}).merge(Ti),zD=x.object({experimental:x.optional(x.object({}).passthrough()),sampling:x.optional(x.object({}).passthrough()),elicitation:x.optional(x.object({}).passthrough()),roots:x.optional(x.object({listChanged:x.optional(x.boolean())}).passthrough())}).passthrough(),UD=zr.extend({method:x.literal("initialize"),params:dt.extend({protocolVersion:x.string(),capabilities:zD,clientInfo:n0})});var HD=x.object({experimental:x.optional(x.object({}).passthrough()),logging:x.optional(x.object({}).passthrough()),completions:x.optional(x.object({}).passthrough()),prompts:x.optional(x.object({listChanged:x.optional(x.boolean())}).passthrough()),resources:x.optional(x.object({subscribe:x.optional(x.boolean()),listChanged:x.optional(x.boolean())}).passthrough()),tools:x.optional(x.object({listChanged:x.optional(x.boolean())}).passthrough())}).passthrough(),Ip=ft.extend({protocolVersion:x.string(),capabilities:HD,serverInfo:n0,instructions:x.optional(x.string())}),BD=Ft.extend({method:x.literal("notifications/initialized")});var dc=zr.extend({method:x.literal("ping")}),VD=x.object({progress:x.number(),total:x.optional(x.number()),message:x.optional(x.string())}).passthrough(),fc=Ft.extend({method:x.literal("notifications/progress"),params:Pi.merge(VD).extend({progressToken:Qb})}),mc=zr.extend({params:dt.extend({cursor:x.optional(Kb)}).optional()}),hc=ft.extend({nextCursor:x.optional(Kb)}),i0=x.object({uri:x.string(),mimeType:x.optional(x.string()),_meta:x.optional(x.object({}).passthrough())}).passthrough(),o0=i0.extend({text:x.string()}),Ap=x.string().refine(r=>{try{return atob(r),!0}catch{return!1}},{message:"Invalid Base64 string"}),c0=i0.extend({blob:Ap}),l0=Ri.extend({uri:x.string(),description:x.optional(x.string()),mimeType:x.optional(x.string()),_meta:x.optional(x.object({}).passthrough())}).merge(Ti),ZD=Ri.extend({uriTemplate:x.string(),description:x.optional(x.string()),mimeType:x.optional(x.string()),_meta:x.optional(x.object({}).passthrough())}).merge(Ti),GD=mc.extend({method:x.literal("resources/list")}),jp=hc.extend({resources:x.array(l0)}),WD=mc.extend({method:x.literal("resources/templates/list")}),Dp=hc.extend({resourceTemplates:x.array(ZD)}),QD=zr.extend({method:x.literal("resources/read"),params:dt.extend({uri:x.string()})}),Np=ft.extend({contents:x.array(x.union([o0,c0]))}),KD=Ft.extend({method:x.literal("notifications/resources/list_changed")}),XD=zr.extend({method:x.literal("resources/subscribe"),params:dt.extend({uri:x.string()})}),JD=zr.extend({method:x.literal("resources/unsubscribe"),params:dt.extend({uri:x.string()})}),YD=Ft.extend({method:x.literal("notifications/resources/updated"),params:Pi.extend({uri:x.string()})}),e6=x.object({name:x.string(),description:x.optional(x.string()),required:x.optional(x.boolean())}).passthrough(),r6=Ri.extend({description:x.optional(x.string()),arguments:x.optional(x.array(e6)),_meta:x.optional(x.object({}).passthrough())}).merge(Ti),t6=mc.extend({method:x.literal("prompts/list")}),$p=hc.extend({prompts:x.array(r6)}),a6=zr.extend({method:x.literal("prompts/get"),params:dt.extend({name:x.string(),arguments:x.optional(x.record(x.string()))})}),qp=x.object({type:x.literal("text"),text:x.string(),_meta:x.optional(x.object({}).passthrough())}).passthrough(),Fp=x.object({type:x.literal("image"),data:Ap,mimeType:x.string(),_meta:x.optional(x.object({}).passthrough())}).passthrough(),Lp=x.object({type:x.literal("audio"),data:Ap,mimeType:x.string(),_meta:x.optional(x.object({}).passthrough())}).passthrough(),s6=x.object({type:x.literal("resource"),resource:x.union([o0,c0]),_meta:x.optional(x.object({}).passthrough())}).passthrough(),n6=l0.extend({type:x.literal("resource_link")}),u0=x.union([qp,Fp,Lp,n6,s6]),i6=x.object({role:x.enum(["user","assistant"]),content:u0}).passthrough(),Mp=ft.extend({description:x.optional(x.string()),messages:x.array(i6)}),o6=Ft.extend({method:x.literal("notifications/prompts/list_changed")}),c6=x.object({title:x.optional(x.string()),readOnlyHint:x.optional(x.boolean()),destructiveHint:x.optional(x.boolean()),idempotentHint:x.optional(x.boolean()),openWorldHint:x.optional(x.boolean())}).passthrough(),l6=Ri.extend({description:x.optional(x.string()),inputSchema:x.object({type:x.literal("object"),properties:x.optional(x.object({}).passthrough()),required:x.optional(x.array(x.string()))}).passthrough(),outputSchema:x.optional(x.object({type:x.literal("object"),properties:x.optional(x.object({}).passthrough()),required:x.optional(x.array(x.string()))}).passthrough()),annotations:x.optional(c6),_meta:x.optional(x.object({}).passthrough())}).merge(Ti),u6=mc.extend({method:x.literal("tools/list")}),zp=hc.extend({tools:x.array(l6)}),vc=ft.extend({content:x.array(u0).default([]),structuredContent:x.object({}).passthrough().optional(),isError:x.optional(x.boolean())}),TF=vc.or(ft.extend({toolResult:x.unknown()})),p6=zr.extend({method:x.literal("tools/call"),params:dt.extend({name:x.string(),arguments:x.optional(x.record(x.unknown()))})}),d6=Ft.extend({method:x.literal("notifications/tools/list_changed")}),p0=x.enum(["debug","info","notice","warning","error","critical","alert","emergency"]),f6=zr.extend({method:x.literal("logging/setLevel"),params:dt.extend({level:p0})}),m6=Ft.extend({method:x.literal("notifications/message"),params:Pi.extend({level:p0,logger:x.optional(x.string()),data:x.unknown()})}),h6=x.object({name:x.string().optional()}).passthrough(),v6=x.object({hints:x.optional(x.array(h6)),costPriority:x.optional(x.number().min(0).max(1)),speedPriority:x.optional(x.number().min(0).max(1)),intelligencePriority:x.optional(x.number().min(0).max(1))}).passthrough(),g6=x.object({role:x.enum(["user","assistant"]),content:x.union([qp,Fp,Lp])}).passthrough(),y6=zr.extend({method:x.literal("sampling/createMessage"),params:dt.extend({messages:x.array(g6),systemPrompt:x.optional(x.string()),includeContext:x.optional(x.enum(["none","thisServer","allServers"])),temperature:x.optional(x.number()),maxTokens:x.number().int(),stopSequences:x.optional(x.array(x.string())),metadata:x.optional(x.object({}).passthrough()),modelPreferences:x.optional(v6)})}),x6=ft.extend({model:x.string(),stopReason:x.optional(x.enum(["endTurn","stopSequence","maxTokens"]).or(x.string())),role:x.enum(["user","assistant"]),content:x.discriminatedUnion("type",[qp,Fp,Lp])}),b6=x.object({type:x.literal("boolean"),title:x.optional(x.string()),description:x.optional(x.string()),default:x.optional(x.boolean())}).passthrough(),_6=x.object({type:x.literal("string"),title:x.optional(x.string()),description:x.optional(x.string()),minLength:x.optional(x.number()),maxLength:x.optional(x.number()),format:x.optional(x.enum(["email","uri","date","date-time"]))}).passthrough(),w6=x.object({type:x.enum(["number","integer"]),title:x.optional(x.string()),description:x.optional(x.string()),minimum:x.optional(x.number()),maximum:x.optional(x.number())}).passthrough(),E6=x.object({type:x.literal("string"),title:x.optional(x.string()),description:x.optional(x.string()),enum:x.array(x.string()),enumNames:x.optional(x.array(x.string()))}).passthrough(),S6=x.union([b6,_6,w6,E6]),P6=zr.extend({method:x.literal("elicitation/create"),params:dt.extend({message:x.string(),requestedSchema:x.object({type:x.literal("object"),properties:x.record(x.string(),S6),required:x.optional(x.array(x.string()))}).passthrough()})}),T6=ft.extend({action:x.enum(["accept","decline","cancel"]),content:x.optional(x.record(x.string(),x.unknown()))}),R6=x.object({type:x.literal("ref/resource"),uri:x.string()}).passthrough();var k6=x.object({type:x.literal("ref/prompt"),name:x.string()}).passthrough(),O6=zr.extend({method:x.literal("completion/complete"),params:dt.extend({ref:x.union([k6,R6]),argument:x.object({name:x.string(),value:x.string()}).passthrough(),context:x.optional(x.object({arguments:x.optional(x.record(x.string(),x.string()))}))})}),Up=ft.extend({completion:x.object({values:x.array(x.string()).max(100),total:x.optional(x.number().int()),hasMore:x.optional(x.boolean())}).passthrough()}),C6=x.object({uri:x.string().startsWith("file://"),name:x.optional(x.string()),_meta:x.optional(x.object({}).passthrough())}).passthrough(),I6=zr.extend({method:x.literal("roots/list")}),A6=ft.extend({roots:x.array(C6)}),j6=Ft.extend({method:x.literal("notifications/roots/list_changed")}),RF=x.union([dc,UD,O6,f6,a6,t6,GD,WD,QD,XD,JD,p6,u6]),kF=x.union([pc,fc,BD,j6]),OF=x.union([Rs,x6,T6,A6]),CF=x.union([dc,y6,P6,I6]),IF=x.union([pc,fc,m6,YD,KD,d6,o6]),AF=x.union([Rs,Ip,Up,Mp,$p,jp,Dp,Np,vc,zp]),pt=class extends Error{constructor(e,a,t){super(`MCP error ${e}: ${a}`),this.code=e,this.data=t,this.name="McpError"}};var D6=6e4,gc=class{constructor(e){this._options=e,this._requestMessageId=0,this._requestHandlers=new Map,this._requestHandlerAbortControllers=new Map,this._notificationHandlers=new Map,this._responseHandlers=new Map,this._progressHandlers=new Map,this._timeoutInfo=new Map,this._pendingDebouncedNotifications=new Set,this.setNotificationHandler(pc,a=>{let t=this._requestHandlerAbortControllers.get(a.params.requestId);t?.abort(a.params.reason)}),this.setNotificationHandler(fc,a=>{this._onprogress(a)}),this.setRequestHandler(dc,a=>({}))}_setupTimeout(e,a,t,s,i=!1){this._timeoutInfo.set(e,{timeoutId:setTimeout(s,a),startTime:Date.now(),timeout:a,maxTotalTimeout:t,resetTimeoutOnProgress:i,onTimeout:s})}_resetTimeout(e){let a=this._timeoutInfo.get(e);if(!a)return!1;let t=Date.now()-a.startTime;if(a.maxTotalTimeout&&t>=a.maxTotalTimeout)throw this._timeoutInfo.delete(e),new pt(ut.RequestTimeout,"Maximum total timeout exceeded",{maxTotalTimeout:a.maxTotalTimeout,totalElapsed:t});return clearTimeout(a.timeoutId),a.timeoutId=setTimeout(a.onTimeout,a.timeout),!0}_cleanupTimeout(e){let a=this._timeoutInfo.get(e);a&&(clearTimeout(a.timeoutId),this._timeoutInfo.delete(e))}async connect(e){var a,t,s;this._transport=e;let i=(a=this.transport)===null||a===void 0?void 0:a.onclose;this._transport.onclose=()=>{i?.(),this._onclose()};let n=(t=this.transport)===null||t===void 0?void 0:t.onerror;this._transport.onerror=l=>{n?.(l),this._onerror(l)};let o=(s=this._transport)===null||s===void 0?void 0:s.onmessage;this._transport.onmessage=(l,c)=>{o?.(l,c),Cp(l)||a0(l)?this._onresponse(l):Jb(l)?this._onrequest(l,c):e0(l)?this._onnotification(l):this._onerror(new Error(`Unknown message type: ${JSON.stringify(l)}`))},await this._transport.start()}_onclose(){var e;let a=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._pendingDebouncedNotifications.clear(),this._transport=void 0,(e=this.onclose)===null||e===void 0||e.call(this);let t=new pt(ut.ConnectionClosed,"Connection closed");for(let s of a.values())s(t)}_onerror(e){var a;(a=this.onerror)===null||a===void 0||a.call(this,e)}_onnotification(e){var a;let t=(a=this._notificationHandlers.get(e.method))!==null&&a!==void 0?a:this.fallbackNotificationHandler;t!==void 0&&Promise.resolve().then(()=>t(e)).catch(s=>this._onerror(new Error(`Uncaught error in notification handler: ${s}`)))}_onrequest(e,a){var t,s;let i=(t=this._requestHandlers.get(e.method))!==null&&t!==void 0?t:this.fallbackRequestHandler,n=this._transport;if(i===void 0){n?.send({jsonrpc:"2.0",id:e.id,error:{code:ut.MethodNotFound,message:"Method not found"}}).catch(c=>this._onerror(new Error(`Failed to send an error response: ${c}`)));return}let o=new AbortController;this._requestHandlerAbortControllers.set(e.id,o);let l={signal:o.signal,sessionId:n?.sessionId,_meta:(s=e.params)===null||s===void 0?void 0:s._meta,sendNotification:c=>this.notification(c,{relatedRequestId:e.id}),sendRequest:(c,u,p)=>this.request(c,u,{...p,relatedRequestId:e.id}),authInfo:a?.authInfo,requestId:e.id,requestInfo:a?.requestInfo};Promise.resolve().then(()=>i(e,l)).then(c=>{if(!o.signal.aborted)return n?.send({result:c,jsonrpc:"2.0",id:e.id})},c=>{var u;if(!o.signal.aborted)return n?.send({jsonrpc:"2.0",id:e.id,error:{code:Number.isSafeInteger(c.code)?c.code:ut.InternalError,message:(u=c.message)!==null&&u!==void 0?u:"Internal error"}})}).catch(c=>this._onerror(new Error(`Failed to send response: ${c}`))).finally(()=>{this._requestHandlerAbortControllers.delete(e.id)})}_onprogress(e){let{progressToken:a,...t}=e.params,s=Number(a),i=this._progressHandlers.get(s);if(!i){this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(e)}`));return}let n=this._responseHandlers.get(s),o=this._timeoutInfo.get(s);if(o&&n&&o.resetTimeoutOnProgress)try{this._resetTimeout(s)}catch(l){n(l);return}i(t)}_onresponse(e){let a=Number(e.id),t=this._responseHandlers.get(a);if(t===void 0){this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(e)}`));return}if(this._responseHandlers.delete(a),this._progressHandlers.delete(a),this._cleanupTimeout(a),Cp(e))t(e);else{let s=new pt(e.error.code,e.error.message,e.error.data);t(s)}}get transport(){return this._transport}async close(){var e;await((e=this._transport)===null||e===void 0?void 0:e.close())}request(e,a,t){let{relatedRequestId:s,resumptionToken:i,onresumptiontoken:n}=t??{};return new Promise((o,l)=>{var c,u,p,f,d,v;if(!this._transport){l(new Error("Not connected"));return}((c=this._options)===null||c===void 0?void 0:c.enforceStrictCapabilities)===!0&&this.assertCapabilityForMethod(e.method),(u=t?.signal)===null||u===void 0||u.throwIfAborted();let m=this._requestMessageId++,h={...e,jsonrpc:"2.0",id:m};t?.onprogress&&(this._progressHandlers.set(m,t.onprogress),h.params={...e.params,_meta:{...((p=e.params)===null||p===void 0?void 0:p._meta)||{},progressToken:m}});let b=k=>{var O;this._responseHandlers.delete(m),this._progressHandlers.delete(m),this._cleanupTimeout(m),(O=this._transport)===null||O===void 0||O.send({jsonrpc:"2.0",method:"notifications/cancelled",params:{requestId:m,reason:String(k)}},{relatedRequestId:s,resumptionToken:i,onresumptiontoken:n}).catch(T=>this._onerror(new Error(`Failed to send cancellation: ${T}`))),l(k)};this._responseHandlers.set(m,k=>{var O;if(!(!((O=t?.signal)===null||O===void 0)&&O.aborted)){if(k instanceof Error)return l(k);try{let T=a.parse(k.result);o(T)}catch(T){l(T)}}}),(f=t?.signal)===null||f===void 0||f.addEventListener("abort",()=>{var k;b((k=t?.signal)===null||k===void 0?void 0:k.reason)});let _=(d=t?.timeout)!==null&&d!==void 0?d:D6,E=()=>b(new pt(ut.RequestTimeout,"Request timed out",{timeout:_}));this._setupTimeout(m,_,t?.maxTotalTimeout,E,(v=t?.resetTimeoutOnProgress)!==null&&v!==void 0?v:!1),this._transport.send(h,{relatedRequestId:s,resumptionToken:i,onresumptiontoken:n}).catch(k=>{this._cleanupTimeout(m),l(k)})})}async notification(e,a){var t,s;if(!this._transport)throw new Error("Not connected");if(this.assertNotificationCapability(e.method),((s=(t=this._options)===null||t===void 0?void 0:t.debouncedNotificationMethods)!==null&&s!==void 0?s:[]).includes(e.method)&&!e.params&&!a?.relatedRequestId){if(this._pendingDebouncedNotifications.has(e.method))return;this._pendingDebouncedNotifications.add(e.method),Promise.resolve().then(()=>{var l;if(this._pendingDebouncedNotifications.delete(e.method),!this._transport)return;let c={...e,jsonrpc:"2.0"};(l=this._transport)===null||l===void 0||l.send(c,a).catch(u=>this._onerror(u))});return}let o={...e,jsonrpc:"2.0"};await this._transport.send(o,a)}setRequestHandler(e,a){let t=e.shape.method.value;this.assertRequestHandlerCapability(t),this._requestHandlers.set(t,(s,i)=>Promise.resolve(a(e.parse(s),i)))}removeRequestHandler(e){this._requestHandlers.delete(e)}assertCanSetRequestHandler(e){if(this._requestHandlers.has(e))throw new Error(`A request handler for ${e} already exists, which would be overridden`)}setNotificationHandler(e,a){this._notificationHandlers.set(e.shape.method.value,t=>Promise.resolve(a(e.parse(t))))}removeNotificationHandler(e){this._notificationHandlers.delete(e)}};function d0(r,e){return Object.entries(e).reduce((a,[t,s])=>(s&&typeof s=="object"?a[t]=a[t]?{...a[t],...s}:s:a[t]=s,a),{...r})}var m1=ua(f1(),1),$c=class extends gc{constructor(e,a){var t;super(a),this._clientInfo=e,this._cachedToolOutputValidators=new Map,this._capabilities=(t=a?.capabilities)!==null&&t!==void 0?t:{},this._ajv=new m1.default}registerCapabilities(e){if(this.transport)throw new Error("Cannot register capabilities after connecting to transport");this._capabilities=d0(this._capabilities,e)}assertCapability(e,a){var t;if(!(!((t=this._serverCapabilities)===null||t===void 0)&&t[e]))throw new Error(`Server does not support ${e} (required for ${a})`)}async connect(e,a){if(await super.connect(e),e.sessionId===void 0)try{let t=await this.request({method:"initialize",params:{protocolVersion:Op,capabilities:this._capabilities,clientInfo:this._clientInfo}},Ip,a);if(t===void 0)throw new Error(`Server sent invalid initialize result: ${t}`);if(!Wb.includes(t.protocolVersion))throw new Error(`Server's protocol version is not supported: ${t.protocolVersion}`);this._serverCapabilities=t.capabilities,this._serverVersion=t.serverInfo,e.setProtocolVersion&&e.setProtocolVersion(t.protocolVersion),this._instructions=t.instructions,await this.notification({method:"notifications/initialized"})}catch(t){throw this.close(),t}}getServerCapabilities(){return this._serverCapabilities}getServerVersion(){return this._serverVersion}getInstructions(){return this._instructions}assertCapabilityForMethod(e){var a,t,s,i,n;switch(e){case"logging/setLevel":if(!(!((a=this._serverCapabilities)===null||a===void 0)&&a.logging))throw new Error(`Server does not support logging (required for ${e})`);break;case"prompts/get":case"prompts/list":if(!(!((t=this._serverCapabilities)===null||t===void 0)&&t.prompts))throw new Error(`Server does not support prompts (required for ${e})`);break;case"resources/list":case"resources/templates/list":case"resources/read":case"resources/subscribe":case"resources/unsubscribe":if(!(!((s=this._serverCapabilities)===null||s===void 0)&&s.resources))throw new Error(`Server does not support resources (required for ${e})`);if(e==="resources/subscribe"&&!this._serverCapabilities.resources.subscribe)throw new Error(`Server does not support resource subscriptions (required for ${e})`);break;case"tools/call":case"tools/list":if(!(!((i=this._serverCapabilities)===null||i===void 0)&&i.tools))throw new Error(`Server does not support tools (required for ${e})`);break;case"completion/complete":if(!(!((n=this._serverCapabilities)===null||n===void 0)&&n.completions))throw new Error(`Server does not support completions (required for ${e})`);break;case"initialize":break;case"ping":break}}assertNotificationCapability(e){var a;switch(e){case"notifications/roots/list_changed":if(!(!((a=this._capabilities.roots)===null||a===void 0)&&a.listChanged))throw new Error(`Client does not support roots list changed notifications (required for ${e})`);break;case"notifications/initialized":break;case"notifications/cancelled":break;case"notifications/progress":break}}assertRequestHandlerCapability(e){switch(e){case"sampling/createMessage":if(!this._capabilities.sampling)throw new Error(`Client does not support sampling capability (required for ${e})`);break;case"elicitation/create":if(!this._capabilities.elicitation)throw new Error(`Client does not support elicitation capability (required for ${e})`);break;case"roots/list":if(!this._capabilities.roots)throw new Error(`Client does not support roots capability (required for ${e})`);break;case"ping":break}}async ping(e){return this.request({method:"ping"},Rs,e)}async complete(e,a){return this.request({method:"completion/complete",params:e},Up,a)}async setLoggingLevel(e,a){return this.request({method:"logging/setLevel",params:{level:e}},Rs,a)}async getPrompt(e,a){return this.request({method:"prompts/get",params:e},Mp,a)}async listPrompts(e,a){return this.request({method:"prompts/list",params:e},$p,a)}async listResources(e,a){return this.request({method:"resources/list",params:e},jp,a)}async listResourceTemplates(e,a){return this.request({method:"resources/templates/list",params:e},Dp,a)}async readResource(e,a){return this.request({method:"resources/read",params:e},Np,a)}async subscribeResource(e,a){return this.request({method:"resources/subscribe",params:e},Rs,a)}async unsubscribeResource(e,a){return this.request({method:"resources/unsubscribe",params:e},Rs,a)}async callTool(e,a=vc,t){let s=await this.request({method:"tools/call",params:e},a,t),i=this.getToolOutputValidator(e.name);if(i){if(!s.structuredContent&&!s.isError)throw new pt(ut.InvalidRequest,`Tool ${e.name} has an output schema but did not return structured content`);if(s.structuredContent)try{if(!i(s.structuredContent))throw new pt(ut.InvalidParams,`Structured content does not match the tool's output schema: ${this._ajv.errorsText(i.errors)}`)}catch(n){throw n instanceof pt?n:new pt(ut.InvalidParams,`Failed to validate structured content: ${n instanceof Error?n.message:String(n)}`)}}return s}cacheToolOutputSchemas(e){this._cachedToolOutputValidators.clear();for(let a of e)if(a.outputSchema)try{let t=this._ajv.compile(a.outputSchema);this._cachedToolOutputValidators.set(a.name,t)}catch{}}getToolOutputValidator(e){return this._cachedToolOutputValidators.get(e)}async listTools(e,a){let t=await this.request({method:"tools/list",params:e},zp,a);return this.cacheToolOutputSchemas(t.tools),t}async sendRootsListChanged(){return this.notification({method:"notifications/roots/list_changed"})}};var sw=ua(tw(),1),Oi=ua(require("node:process"),1),nw=require("node:stream");var Fc=class{append(e){this._buffer=this._buffer?Buffer.concat([this._buffer,e]):e}readMessage(){if(!this._buffer)return null;let e=this._buffer.indexOf(` `);if(e===-1)return null;let a=this._buffer.toString("utf8",0,e).replace(/\r$/,"");return this._buffer=this._buffer.subarray(e+1),L5(a)}clear(){this._buffer=void 0}};function L5(r){return s0.parse(JSON.parse(r))}function aw(r){return JSON.stringify(r)+` -`}var M5=Oi.default.platform==="win32"?["APPDATA","HOMEDRIVE","HOMEPATH","LOCALAPPDATA","PATH","PROCESSOR_ARCHITECTURE","SYSTEMDRIVE","SYSTEMROOT","TEMP","USERNAME","USERPROFILE","PROGRAMFILES"]:["HOME","LOGNAME","PATH","SHELL","TERM","USER"];function z5(){let r={};for(let e of M5){let a=Oi.default.env[e];a!==void 0&&(a.startsWith("()")||(r[e]=a))}return r}var Lc=class{constructor(e){this._abortController=new AbortController,this._readBuffer=new Fc,this._stderrStream=null,this._serverParams=e,(e.stderr==="pipe"||e.stderr==="overlapped")&&(this._stderrStream=new nw.PassThrough)}async start(){if(this._process)throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");return new Promise((e,a)=>{var t,s,i,n,o;this._process=(0,sw.default)(this._serverParams.command,(t=this._serverParams.args)!==null&&t!==void 0?t:[],{env:{...z5(),...this._serverParams.env},stdio:["pipe","pipe",(s=this._serverParams.stderr)!==null&&s!==void 0?s:"inherit"],shell:!1,signal:this._abortController.signal,windowsHide:Oi.default.platform==="win32"&&U5(),cwd:this._serverParams.cwd}),this._process.on("error",l=>{var c,u;if(l.name==="AbortError"){(c=this.onclose)===null||c===void 0||c.call(this);return}a(l),(u=this.onerror)===null||u===void 0||u.call(this,l)}),this._process.on("spawn",()=>{e()}),this._process.on("close",l=>{var c;this._process=void 0,(c=this.onclose)===null||c===void 0||c.call(this)}),(i=this._process.stdin)===null||i===void 0||i.on("error",l=>{var c;(c=this.onerror)===null||c===void 0||c.call(this,l)}),(n=this._process.stdout)===null||n===void 0||n.on("data",l=>{this._readBuffer.append(l),this.processReadBuffer()}),(o=this._process.stdout)===null||o===void 0||o.on("error",l=>{var c;(c=this.onerror)===null||c===void 0||c.call(this,l)}),this._stderrStream&&this._process.stderr&&this._process.stderr.pipe(this._stderrStream)})}get stderr(){var e,a;return this._stderrStream?this._stderrStream:(a=(e=this._process)===null||e===void 0?void 0:e.stderr)!==null&&a!==void 0?a:null}get pid(){var e,a;return(a=(e=this._process)===null||e===void 0?void 0:e.pid)!==null&&a!==void 0?a:null}processReadBuffer(){for(var e,a;;)try{let t=this._readBuffer.readMessage();if(t===null)break;(e=this.onmessage)===null||e===void 0||e.call(this,t)}catch(t){(a=this.onerror)===null||a===void 0||a.call(this,t)}}async close(){this._abortController.abort(),this._process=void 0,this._readBuffer.clear()}send(e){return new Promise(a=>{var t;if(!(!((t=this._process)===null||t===void 0)&&t.stdin))throw new Error("Not connected");let s=aw(e);this._process.stdin.write(s)?a():this._process.stdin.once("drain",a)})}};function U5(){return"type"in Oi.default}var iw=ua(require("path"),1),ow=ua(require("os"),1),Mc=class{client=null;connected=!1;project;collectionName;VECTOR_DB_DIR;BATCH_SIZE=100;constructor(e){this.project=e,this.collectionName=`cm__${e}`,this.VECTOR_DB_DIR=iw.default.join(ow.default.homedir(),".claude-mem","vector-db")}async ensureConnection(){if(!(this.connected&&this.client)){Y.info("CHROMA_SYNC","Connecting to Chroma MCP server...",{project:this.project});try{let e=new Lc({command:"uvx",args:["chroma-mcp","--client-type","persistent","--data-dir",this.VECTOR_DB_DIR],stderr:"ignore"});this.client=new $c({name:"claude-mem-chroma-sync",version:"1.0.0"},{capabilities:{}}),await this.client.connect(e),this.connected=!0,Y.info("CHROMA_SYNC","Connected to Chroma MCP server",{project:this.project})}catch(e){throw Y.error("CHROMA_SYNC","Failed to connect to Chroma MCP server",{project:this.project},e),new Error(`Chroma connection failed: ${e instanceof Error?e.message:String(e)}`)}}}async ensureCollection(){if(await this.ensureConnection(),!this.client)throw new Error("Chroma client not initialized");try{await this.client.callTool({name:"chroma_get_collection_info",arguments:{collection_name:this.collectionName}}),Y.debug("CHROMA_SYNC","Collection exists",{collection:this.collectionName})}catch{Y.info("CHROMA_SYNC","Creating collection",{collection:this.collectionName});try{await this.client.callTool({name:"chroma_create_collection",arguments:{collection_name:this.collectionName,embedding_function_name:"default"}}),Y.info("CHROMA_SYNC","Collection created",{collection:this.collectionName})}catch(a){throw Y.error("CHROMA_SYNC","Failed to create collection",{collection:this.collectionName},a),new Error(`Collection creation failed: ${a instanceof Error?a.message:String(a)}`)}}}formatObservationDocs(e){let a=[],t=e.facts?JSON.parse(e.facts):[],s=e.concepts?JSON.parse(e.concepts):[],i=e.files_read?JSON.parse(e.files_read):[],n=e.files_modified?JSON.parse(e.files_modified):[],o={sqlite_id:e.id,doc_type:"observation",sdk_session_id:e.sdk_session_id,project:e.project,created_at_epoch:e.created_at_epoch,type:e.type||"discovery",title:e.title||"Untitled"};return e.subtitle&&(o.subtitle=e.subtitle),s.length>0&&(o.concepts=s.join(",")),i.length>0&&(o.files_read=i.join(",")),n.length>0&&(o.files_modified=n.join(",")),e.narrative&&a.push({id:`obs_${e.id}_narrative`,document:e.narrative,metadata:{...o,field_type:"narrative"}}),e.text&&a.push({id:`obs_${e.id}_text`,document:e.text,metadata:{...o,field_type:"text"}}),t.forEach((l,c)=>{a.push({id:`obs_${e.id}_fact_${c}`,document:l,metadata:{...o,field_type:"fact",fact_index:c}})}),a}formatSummaryDocs(e){let a=[],t={sqlite_id:e.id,doc_type:"session_summary",sdk_session_id:e.sdk_session_id,project:e.project,created_at_epoch:e.created_at_epoch,prompt_number:e.prompt_number||0};return e.request&&a.push({id:`summary_${e.id}_request`,document:e.request,metadata:{...t,field_type:"request"}}),e.investigated&&a.push({id:`summary_${e.id}_investigated`,document:e.investigated,metadata:{...t,field_type:"investigated"}}),e.learned&&a.push({id:`summary_${e.id}_learned`,document:e.learned,metadata:{...t,field_type:"learned"}}),e.completed&&a.push({id:`summary_${e.id}_completed`,document:e.completed,metadata:{...t,field_type:"completed"}}),e.next_steps&&a.push({id:`summary_${e.id}_next_steps`,document:e.next_steps,metadata:{...t,field_type:"next_steps"}}),e.notes&&a.push({id:`summary_${e.id}_notes`,document:e.notes,metadata:{...t,field_type:"notes"}}),a}async addDocuments(e){if(e.length!==0){if(await this.ensureCollection(),!this.client)throw new Error("Chroma client not initialized");try{await this.client.callTool({name:"chroma_add_documents",arguments:{collection_name:this.collectionName,documents:e.map(a=>a.document),ids:e.map(a=>a.id),metadatas:e.map(a=>a.metadata)}}),Y.debug("CHROMA_SYNC","Documents added",{collection:this.collectionName,count:e.length})}catch(a){throw Y.error("CHROMA_SYNC","Failed to add documents",{collection:this.collectionName,count:e.length},a),new Error(`Document add failed: ${a instanceof Error?a.message:String(a)}`)}}}async syncObservation(e,a,t,s,i,n){let o={id:e,sdk_session_id:a,project:t,text:null,type:s.type,title:s.title,subtitle:s.subtitle,facts:JSON.stringify(s.facts),narrative:s.narrative,concepts:JSON.stringify(s.concepts),files_read:JSON.stringify(s.files_read),files_modified:JSON.stringify(s.files_modified),prompt_number:i,created_at:new Date(n*1e3).toISOString(),created_at_epoch:n},l=this.formatObservationDocs(o);Y.info("CHROMA_SYNC","Syncing observation",{observationId:e,documentCount:l.length,project:t}),await this.addDocuments(l)}async syncSummary(e,a,t,s,i,n){let o={id:e,sdk_session_id:a,project:t,request:s.request,investigated:s.investigated,learned:s.learned,completed:s.completed,next_steps:s.next_steps,notes:s.notes,prompt_number:i,created_at:new Date(n*1e3).toISOString(),created_at_epoch:n},l=this.formatSummaryDocs(o);Y.info("CHROMA_SYNC","Syncing summary",{summaryId:e,documentCount:l.length,project:t}),await this.addDocuments(l)}formatUserPromptDoc(e){return{id:`prompt_${e.id}`,document:e.prompt_text,metadata:{sqlite_id:e.id,doc_type:"user_prompt",sdk_session_id:e.sdk_session_id,project:e.project,created_at_epoch:e.created_at_epoch,prompt_number:e.prompt_number}}}async syncUserPrompt(e,a,t,s,i,n){let o={id:e,claude_session_id:"",prompt_number:i,prompt_text:s,created_at:new Date(n*1e3).toISOString(),created_at_epoch:n,sdk_session_id:a,project:t},l=this.formatUserPromptDoc(o);Y.info("CHROMA_SYNC","Syncing user prompt",{promptId:e,project:t}),await this.addDocuments([l])}async getExistingChromaIds(){if(await this.ensureConnection(),!this.client)throw new Error("Chroma client not initialized");let e=new Set,a=new Set,t=new Set,s=0,i=1e3;for(Y.info("CHROMA_SYNC","Fetching existing Chroma document IDs...",{project:this.project});;)try{let o=(await this.client.callTool({name:"chroma_get_documents",arguments:{collection_name:this.collectionName,limit:i,offset:s,where:{project:this.project},include:["metadatas"]}})).content[0];if(o.type!=="text")throw new Error("Unexpected response type from chroma_get_documents");let c=JSON.parse(o.text).metadatas||[];if(c.length===0)break;for(let u of c)u.sqlite_id&&(u.doc_type==="observation"?e.add(u.sqlite_id):u.doc_type==="summary"?a.add(u.sqlite_id):u.doc_type==="prompt"&&t.add(u.sqlite_id));s+=i,Y.debug("CHROMA_SYNC","Fetched batch of existing IDs",{project:this.project,offset:s,batchSize:c.length})}catch(n){throw Y.error("CHROMA_SYNC","Failed to fetch existing IDs",{project:this.project},n),n}return Y.info("CHROMA_SYNC","Existing IDs fetched",{project:this.project,observations:e.size,summaries:a.size,prompts:t.size}),{observations:e,summaries:a,prompts:t}}async ensureBackfilled(){Y.info("CHROMA_SYNC","Starting smart backfill",{project:this.project}),await this.ensureCollection();let e=await this.getExistingChromaIds(),a=new Pr;try{let t=Array.from(e.observations),s=t.length>0?`AND id NOT IN (${t.join(",")})`:"",i=a.db.prepare(` +`}var M5=Oi.default.platform==="win32"?["APPDATA","HOMEDRIVE","HOMEPATH","LOCALAPPDATA","PATH","PROCESSOR_ARCHITECTURE","SYSTEMDRIVE","SYSTEMROOT","TEMP","USERNAME","USERPROFILE","PROGRAMFILES"]:["HOME","LOGNAME","PATH","SHELL","TERM","USER"];function z5(){let r={};for(let e of M5){let a=Oi.default.env[e];a!==void 0&&(a.startsWith("()")||(r[e]=a))}return r}var Lc=class{constructor(e){this._abortController=new AbortController,this._readBuffer=new Fc,this._stderrStream=null,this._serverParams=e,(e.stderr==="pipe"||e.stderr==="overlapped")&&(this._stderrStream=new nw.PassThrough)}async start(){if(this._process)throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");return new Promise((e,a)=>{var t,s,i,n,o;this._process=(0,sw.default)(this._serverParams.command,(t=this._serverParams.args)!==null&&t!==void 0?t:[],{env:{...z5(),...this._serverParams.env},stdio:["pipe","pipe",(s=this._serverParams.stderr)!==null&&s!==void 0?s:"inherit"],shell:!1,signal:this._abortController.signal,windowsHide:Oi.default.platform==="win32"&&U5(),cwd:this._serverParams.cwd}),this._process.on("error",l=>{var c,u;if(l.name==="AbortError"){(c=this.onclose)===null||c===void 0||c.call(this);return}a(l),(u=this.onerror)===null||u===void 0||u.call(this,l)}),this._process.on("spawn",()=>{e()}),this._process.on("close",l=>{var c;this._process=void 0,(c=this.onclose)===null||c===void 0||c.call(this)}),(i=this._process.stdin)===null||i===void 0||i.on("error",l=>{var c;(c=this.onerror)===null||c===void 0||c.call(this,l)}),(n=this._process.stdout)===null||n===void 0||n.on("data",l=>{this._readBuffer.append(l),this.processReadBuffer()}),(o=this._process.stdout)===null||o===void 0||o.on("error",l=>{var c;(c=this.onerror)===null||c===void 0||c.call(this,l)}),this._stderrStream&&this._process.stderr&&this._process.stderr.pipe(this._stderrStream)})}get stderr(){var e,a;return this._stderrStream?this._stderrStream:(a=(e=this._process)===null||e===void 0?void 0:e.stderr)!==null&&a!==void 0?a:null}get pid(){var e,a;return(a=(e=this._process)===null||e===void 0?void 0:e.pid)!==null&&a!==void 0?a:null}processReadBuffer(){for(var e,a;;)try{let t=this._readBuffer.readMessage();if(t===null)break;(e=this.onmessage)===null||e===void 0||e.call(this,t)}catch(t){(a=this.onerror)===null||a===void 0||a.call(this,t)}}async close(){this._abortController.abort(),this._process=void 0,this._readBuffer.clear()}send(e){return new Promise(a=>{var t;if(!(!((t=this._process)===null||t===void 0)&&t.stdin))throw new Error("Not connected");let s=aw(e);this._process.stdin.write(s)?a():this._process.stdin.once("drain",a)})}};function U5(){return"type"in Oi.default}var iw=ua(require("path"),1),ow=ua(require("os"),1),Mc=class{client=null;connected=!1;project;collectionName;VECTOR_DB_DIR;BATCH_SIZE=100;constructor(e){this.project=e,this.collectionName=`cm__${e}`,this.VECTOR_DB_DIR=iw.default.join(ow.default.homedir(),".claude-mem","vector-db")}async ensureConnection(){if(!(this.connected&&this.client)){Y.info("CHROMA_SYNC","Connecting to Chroma MCP server...",{project:this.project});try{let e=new Lc({command:"uvx",args:["chroma-mcp","--client-type","persistent","--data-dir",this.VECTOR_DB_DIR],stderr:"ignore"});this.client=new $c({name:"claude-mem-chroma-sync",version:"1.0.0"},{capabilities:{}}),await this.client.connect(e),this.connected=!0,Y.info("CHROMA_SYNC","Connected to Chroma MCP server",{project:this.project})}catch(e){throw Y.error("CHROMA_SYNC","Failed to connect to Chroma MCP server",{project:this.project},e),new Error(`Chroma connection failed: ${e instanceof Error?e.message:String(e)}`)}}}async ensureCollection(){if(await this.ensureConnection(),!this.client)throw new Error("Chroma client not initialized");try{await this.client.callTool({name:"chroma_get_collection_info",arguments:{collection_name:this.collectionName}}),Y.debug("CHROMA_SYNC","Collection exists",{collection:this.collectionName})}catch{Y.info("CHROMA_SYNC","Creating collection",{collection:this.collectionName});try{await this.client.callTool({name:"chroma_create_collection",arguments:{collection_name:this.collectionName,embedding_function_name:"default"}}),Y.info("CHROMA_SYNC","Collection created",{collection:this.collectionName})}catch(a){throw Y.error("CHROMA_SYNC","Failed to create collection",{collection:this.collectionName},a),new Error(`Collection creation failed: ${a instanceof Error?a.message:String(a)}`)}}}formatObservationDocs(e){let a=[],t=e.facts?JSON.parse(e.facts):[],s=e.concepts?JSON.parse(e.concepts):[],i=e.files_read?JSON.parse(e.files_read):[],n=e.files_modified?JSON.parse(e.files_modified):[],o={sqlite_id:e.id,doc_type:"observation",sdk_session_id:e.sdk_session_id,project:e.project,created_at_epoch:e.created_at_epoch,type:e.type||"discovery",title:e.title||"Untitled"};return e.subtitle&&(o.subtitle=e.subtitle),s.length>0&&(o.concepts=s.join(",")),i.length>0&&(o.files_read=i.join(",")),n.length>0&&(o.files_modified=n.join(",")),e.narrative&&a.push({id:`obs_${e.id}_narrative`,document:e.narrative,metadata:{...o,field_type:"narrative"}}),e.text&&a.push({id:`obs_${e.id}_text`,document:e.text,metadata:{...o,field_type:"text"}}),t.forEach((l,c)=>{a.push({id:`obs_${e.id}_fact_${c}`,document:l,metadata:{...o,field_type:"fact",fact_index:c}})}),a}formatSummaryDocs(e){let a=[],t={sqlite_id:e.id,doc_type:"session_summary",sdk_session_id:e.sdk_session_id,project:e.project,created_at_epoch:e.created_at_epoch,prompt_number:e.prompt_number||0};return e.request&&a.push({id:`summary_${e.id}_request`,document:e.request,metadata:{...t,field_type:"request"}}),e.investigated&&a.push({id:`summary_${e.id}_investigated`,document:e.investigated,metadata:{...t,field_type:"investigated"}}),e.learned&&a.push({id:`summary_${e.id}_learned`,document:e.learned,metadata:{...t,field_type:"learned"}}),e.completed&&a.push({id:`summary_${e.id}_completed`,document:e.completed,metadata:{...t,field_type:"completed"}}),e.next_steps&&a.push({id:`summary_${e.id}_next_steps`,document:e.next_steps,metadata:{...t,field_type:"next_steps"}}),e.notes&&a.push({id:`summary_${e.id}_notes`,document:e.notes,metadata:{...t,field_type:"notes"}}),a}async addDocuments(e){if(e.length!==0){if(await this.ensureCollection(),!this.client)throw new Error("Chroma client not initialized");try{await this.client.callTool({name:"chroma_add_documents",arguments:{collection_name:this.collectionName,documents:e.map(a=>a.document),ids:e.map(a=>a.id),metadatas:e.map(a=>a.metadata)}}),Y.debug("CHROMA_SYNC","Documents added",{collection:this.collectionName,count:e.length})}catch(a){throw Y.error("CHROMA_SYNC","Failed to add documents",{collection:this.collectionName,count:e.length},a),new Error(`Document add failed: ${a instanceof Error?a.message:String(a)}`)}}}async syncObservation(e,a,t,s,i,n){let o={id:e,sdk_session_id:a,project:t,text:null,type:s.type,title:s.title,subtitle:s.subtitle,facts:JSON.stringify(s.facts),narrative:s.narrative,concepts:JSON.stringify(s.concepts),files_read:JSON.stringify(s.files_read),files_modified:JSON.stringify(s.files_modified),prompt_number:i,created_at:new Date(n*1e3).toISOString(),created_at_epoch:n},l=this.formatObservationDocs(o);Y.info("CHROMA_SYNC","Syncing observation",{observationId:e,documentCount:l.length,project:t}),await this.addDocuments(l)}async syncSummary(e,a,t,s,i,n){let o={id:e,sdk_session_id:a,project:t,request:s.request,investigated:s.investigated,learned:s.learned,completed:s.completed,next_steps:s.next_steps,notes:s.notes,prompt_number:i,created_at:new Date(n*1e3).toISOString(),created_at_epoch:n},l=this.formatSummaryDocs(o);Y.info("CHROMA_SYNC","Syncing summary",{summaryId:e,documentCount:l.length,project:t}),await this.addDocuments(l)}formatUserPromptDoc(e){return{id:`prompt_${e.id}`,document:e.prompt_text,metadata:{sqlite_id:e.id,doc_type:"user_prompt",sdk_session_id:e.sdk_session_id,project:e.project,created_at_epoch:e.created_at_epoch,prompt_number:e.prompt_number}}}async syncUserPrompt(e,a,t,s,i,n){let o={id:e,claude_session_id:"",prompt_number:i,prompt_text:s,created_at:new Date(n*1e3).toISOString(),created_at_epoch:n,sdk_session_id:a,project:t},l=this.formatUserPromptDoc(o);Y.info("CHROMA_SYNC","Syncing user prompt",{promptId:e,project:t}),await this.addDocuments([l])}async getExistingChromaIds(){if(await this.ensureConnection(),!this.client)throw new Error("Chroma client not initialized");let e=new Set,a=new Set,t=new Set,s=0,i=1e3;for(Y.info("CHROMA_SYNC","Fetching existing Chroma document IDs...",{project:this.project});;)try{let o=(await this.client.callTool({name:"chroma_get_documents",arguments:{collection_name:this.collectionName,limit:i,offset:s,where:{project:this.project},include:["metadatas"]}})).content[0];if(o.type!=="text")throw new Error("Unexpected response type from chroma_get_documents");let c=JSON.parse(o.text).metadatas||[];if(c.length===0)break;for(let u of c)u.sqlite_id&&(u.doc_type==="observation"?e.add(u.sqlite_id):u.doc_type==="session_summary"?a.add(u.sqlite_id):u.doc_type==="user_prompt"&&t.add(u.sqlite_id));s+=i,Y.debug("CHROMA_SYNC","Fetched batch of existing IDs",{project:this.project,offset:s,batchSize:c.length})}catch(n){throw Y.error("CHROMA_SYNC","Failed to fetch existing IDs",{project:this.project},n),n}return Y.info("CHROMA_SYNC","Existing IDs fetched",{project:this.project,observations:e.size,summaries:a.size,prompts:t.size}),{observations:e,summaries:a,prompts:t}}async ensureBackfilled(){Y.info("CHROMA_SYNC","Starting smart backfill",{project:this.project}),await this.ensureCollection();let e=await this.getExistingChromaIds(),a=new Pr;try{let t=Array.from(e.observations),s=t.length>0?`AND id NOT IN (${t.join(",")})`:"",i=a.db.prepare(` SELECT * FROM observations WHERE project = ? ${s} ORDER BY id ASC diff --git a/src/servers/search-server.ts b/src/servers/search-server.ts index 4210bc8b..48af72c6 100644 --- a/src/servers/search-server.ts +++ b/src/servers/search-server.ts @@ -294,15 +294,12 @@ function formatSessionResult(session: SessionSummarySearchResult, index: number) } /** - * Format user prompt as index entry (truncated text, date, ID only) + * Format user prompt as index entry (full text - don't truncate context!) */ function formatUserPromptIndex(prompt: UserPromptSearchResult, index: number): string { - const truncated = prompt.prompt.length > 100 - ? prompt.prompt.substring(0, 100) + '...' - : prompt.prompt; const date = new Date(prompt.created_at_epoch).toLocaleString(); - return `${index + 1}. "${truncated}" + return `${index + 1}. "${prompt.prompt_text}" Date: ${date} | Prompt #${prompt.prompt_number} Source: claude-mem://user-prompt/${prompt.id}`; } @@ -315,7 +312,7 @@ function formatUserPromptResult(prompt: UserPromptSearchResult, index: number): contentParts.push(`## User Prompt #${prompt.prompt_number}`); contentParts.push(`*Source: claude-mem://user-prompt/${prompt.id}*`); contentParts.push(''); - contentParts.push(prompt.prompt); + contentParts.push(prompt.prompt_text); contentParts.push(''); contentParts.push('---'); @@ -371,7 +368,7 @@ const tools = [ if (chromaResults.ids.length > 0) { // Step 2: Filter by recency (90 days) - const ninetyDaysAgo = Math.floor(Date.now() / 1000) - (90 * 24 * 60 * 60); + const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000); const recentIds = chromaResults.ids.filter((id, idx) => { const meta = chromaResults.metadatas[idx]; return meta && meta.created_at_epoch > ninetyDaysAgo; @@ -466,7 +463,7 @@ const tools = [ if (chromaResults.ids.length > 0) { // Step 2: Filter by recency (90 days) - const ninetyDaysAgo = Math.floor(Date.now() / 1000) - (90 * 24 * 60 * 60); + const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000); const recentIds = chromaResults.ids.filter((id, idx) => { const meta = chromaResults.metadatas[idx]; return meta && meta.created_at_epoch > ninetyDaysAgo; @@ -531,9 +528,9 @@ const tools = [ }, { name: 'find_by_concept', - description: 'Find observations tagged with a specific concept. IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.', + description: 'Find observations tagged with a specific concept. Available concepts: "discovery", "problem-solution", "what-changed", "how-it-works", "pattern", "gotcha", "change". IMPORTANT: Always use index format first (default) to get an overview with minimal token usage, then use format: "full" only for specific items of interest.', inputSchema: z.object({ - concept: z.string().describe('Concept tag to search for'), + concept: z.string().describe('Concept tag to search for. Available: discovery, problem-solution, what-changed, how-it-works, pattern, gotcha, change'), format: z.enum(['index', 'full']).default('index').describe('Output format: "index" for titles/dates only (default, RECOMMENDED for initial search), "full" for complete details (use only after reviewing index results)'), project: z.string().optional().describe('Filter by project name'), dateRange: z.object({ @@ -1032,7 +1029,7 @@ const tools = [ if (chromaResults.ids.length > 0) { // Step 2: Filter by recency (90 days) - const ninetyDaysAgo = Math.floor(Date.now() / 1000) - (90 * 24 * 60 * 60); + const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000); const recentIds = chromaResults.ids.filter((id, idx) => { const meta = chromaResults.metadatas[idx]; return meta && meta.created_at_epoch > ninetyDaysAgo; @@ -1405,7 +1402,7 @@ const tools = [ if (chromaResults.ids.length > 0) { // Filter by recency (90 days) - const ninetyDaysAgo = Math.floor(Date.now() / 1000) - (90 * 24 * 60 * 60); + const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000); const recentIds = chromaResults.ids.filter((id, idx) => { const meta = chromaResults.metadatas[idx]; return meta && meta.created_at_epoch > ninetyDaysAgo; diff --git a/src/services/sync/ChromaSync.ts b/src/services/sync/ChromaSync.ts index 168e704a..acef538f 100644 --- a/src/services/sync/ChromaSync.ts +++ b/src/services/sync/ChromaSync.ts @@ -523,9 +523,9 @@ export class ChromaSync { if (meta.sqlite_id) { if (meta.doc_type === 'observation') { observationIds.add(meta.sqlite_id); - } else if (meta.doc_type === 'summary') { + } else if (meta.doc_type === 'session_summary') { summaryIds.add(meta.sqlite_id); - } else if (meta.doc_type === 'prompt') { + } else if (meta.doc_type === 'user_prompt') { promptIds.add(meta.sqlite_id); } }