diff --git a/PLAN-SESSION-CONTINUITY-FIX.md b/PLAN-SESSION-CONTINUITY-FIX.md new file mode 100644 index 00000000..3b9c629c --- /dev/null +++ b/PLAN-SESSION-CONTINUITY-FIX.md @@ -0,0 +1,664 @@ +# Session Continuity Regression Fix - Phased Execution Plan + +**Project**: claude-mem +**Issue**: Session continuity broken - each prompt creates new session instead of continuing existing one +**Root Cause**: Session SDK ID not propagated correctly from new-hook through to SDKAgent +**History**: Recurring issue over 3 months with 7 previous fix attempts that added complexity + +--- + +## Phase 1: Add Diagnostic Logging + +**Goal**: Add comprehensive logging to trace session ID and prompt number flow through the entire system. + +**Context**: Session continuity requires `claudeSessionId` to flow from hook → SessionStore → SessionManager → SDKAgent. We need to verify this flow is working correctly. + +**Files to Modify**: +1. `src/hooks/new-hook.ts` +2. `src/services/worker/http/routes/SessionRoutes.ts` +3. `src/services/worker/SessionManager.ts` +4. `src/services/worker/SDKAgent.ts` + +**Implementation Steps**: + +### 1.1 Add Logging to `src/hooks/new-hook.ts` + +Add logging at these locations: + +**Line ~24** (after receiving hook input): +```typescript +console.log('[NEW-HOOK] Received hook input:', { + session_id: hookInput.session_id, + has_prompt: !!hookInput.prompt, + cwd: hookInput.cwd +}); +``` + +**Line ~46-47** (before first API call): +```typescript +console.log('[NEW-HOOK] Calling /api/sessions/init:', { + claudeSessionId: session_id, + project, + prompt_length: prompt?.length +}); +``` + +**Line ~51** (after first API call): +```typescript +console.log('[NEW-HOOK] Received from /api/sessions/init:', { + sessionDbId: sessionData.sessionDbId, + promptNumber: sessionData.promptNumber, + skipped: sessionData.skipped +}); +``` + +**Line ~68** (before second API call): +```typescript +console.log('[NEW-HOOK] Calling /sessions/{sessionDbId}/init:', { + sessionDbId: sessionData.sessionDbId, + promptNumber: sessionData.promptNumber, + userPrompt_length: cleanedPrompt?.length +}); +``` + +### 1.2 Add Logging to `src/services/worker/http/routes/SessionRoutes.ts` + +**In `handleSessionInitByClaudeId` method (~line 483)**: +```typescript +console.log('[SESSION-ROUTES] handleSessionInitByClaudeId called:', { + claudeSessionId, + project, + prompt_length: prompt?.length +}); +``` + +**After `createSDKSession` call (~line 493)**: +```typescript +console.log('[SESSION-ROUTES] createSDKSession returned:', { + sessionDbId, + claudeSessionId +}); +``` + +**After prompt number calculation (~line 497)**: +```typescript +console.log('[SESSION-ROUTES] Calculated promptNumber:', { + sessionDbId, + promptNumber, + currentCount +}); +``` + +**In `handleSessionInit` method (~line 175)**: +```typescript +const { userPrompt, promptNumber } = req.body; +console.log('[SESSION-ROUTES] handleSessionInit called:', { + sessionDbId, + promptNumber, + has_userPrompt: !!userPrompt +}); +``` + +### 1.3 Add Logging to `src/services/worker/SessionManager.ts` + +**In `initializeSession` method at start (~line 50)**: +```typescript +console.log('[SESSION-MANAGER] initializeSession called:', { + sessionDbId, + promptNumber, + has_currentUserPrompt: !!currentUserPrompt +}); +``` + +**When session exists in memory (~line 55)**: +```typescript +console.log('[SESSION-MANAGER] Returning cached session:', { + sessionDbId, + claudeSessionId: session.claudeSessionId, + lastPromptNumber: session.lastPromptNumber +}); +``` + +**After fetching from database (~line 87)**: +```typescript +console.log('[SESSION-MANAGER] Fetched session from database:', { + sessionDbId, + claude_session_id: dbSession.claude_session_id, + sdk_session_id: dbSession.sdk_session_id +}); +``` + +**When creating new session object (~line 109-116)**: +```typescript +console.log('[SESSION-MANAGER] Creating new session object:', { + sessionDbId, + claudeSessionId: dbSession.claude_session_id, + lastPromptNumber: promptNumber || /* fallback value */ +}); +``` + +### 1.4 Add Logging to `src/services/worker/SDKAgent.ts` + +**In `startSession` method (~line 72)**: +```typescript +console.log('[SDK-AGENT] Starting SDK query with:', { + sessionDbId: session.sessionDbId, + claudeSessionId: session.claudeSessionId, + resume_parameter: session.claudeSessionId, + lastPromptNumber: session.lastPromptNumber +}); +``` + +**In `createMessageGenerator` method (~line 200)**: +```typescript +const isInitPrompt = session.lastPromptNumber === 1; +console.log('[SDK-AGENT] Creating message generator:', { + sessionDbId: session.sessionDbId, + claudeSessionId: session.claudeSessionId, + lastPromptNumber: session.lastPromptNumber, + isInitPrompt, + promptType: isInitPrompt ? 'INIT' : 'CONTINUATION' +}); +``` + +**Success Criteria**: +- [ ] All 15+ log points added across 4 files +- [ ] Build succeeds with no TypeScript errors +- [ ] Worker service restarts successfully + +**Handoff to Phase 2**: After adding logging, build with `npm run build-and-sync` + +--- + +## Phase 2: Test and Gather Diagnostic Data + +**Goal**: Execute test conversation and collect logs to identify where session ID propagation breaks. + +**Prerequisites**: Phase 1 completed, logging in place, worker service running + +**Test Procedure**: + +### 2.1 Start Fresh Conversation + +In a new Claude Code session: +1. Clear any existing logs: `bun ~/.claude/plugins/marketplaces/thedotmack/scripts/worker-service.cjs > /tmp/worker-logs.txt 2>&1 &` +2. Send first prompt: "test prompt 1" +3. Send second prompt: "test prompt 2" +4. Send third prompt: "test prompt 3" + +### 2.2 Collect Logs + +View worker logs: +```bash +tail -f /tmp/worker-logs.txt | grep -E '\[NEW-HOOK\]|\[SESSION-ROUTES\]|\[SESSION-MANAGER\]|\[SDK-AGENT\]' +``` + +### 2.3 Check Database State + +**Query 1 - Check sessions table**: +```bash +cd ~/.claude-mem +sqlite3 claude-mem.db "SELECT id, claude_session_id, sdk_session_id, status, started_at FROM sdk_sessions ORDER BY id DESC LIMIT 10;" +``` + +**Expected**: Same `claude_session_id` for all 3 prompts + +**Query 2 - Check user prompts table**: +```bash +sqlite3 claude-mem.db "SELECT claude_session_id, prompt_number, created_at FROM user_prompts ORDER BY created_at DESC LIMIT 10;" +``` + +**Expected**: Same `claude_session_id` with prompt_number: 1, 2, 3 + +### 2.4 Analyze Data Flow + +For each prompt (1, 2, 3), trace in logs: + +1. **NEW-HOOK** receives `session_id` from Claude Code +2. **SESSION-ROUTES** receives `claudeSessionId` in API call +3. **SESSION-ROUTES** creates/gets `sessionDbId` +4. **SESSION-ROUTES** calculates `promptNumber` +5. **SESSION-MANAGER** fetches/creates session with `claudeSessionId` +6. **SDK-AGENT** uses `claudeSessionId` as resume parameter +7. **SDK-AGENT** selects INIT vs CONTINUATION prompt + +**Key Questions to Answer**: +- [ ] Does `session_id` from hook stay the same across all 3 prompts? +- [ ] Does `claudeSessionId` match across all log entries for same conversation? +- [ ] Does `promptNumber` increment: 1, 2, 3? +- [ ] Does `lastPromptNumber` match `promptNumber` in SessionManager? +- [ ] Does SDK-AGENT receive correct `resume` parameter on prompts 2+? +- [ ] Does SDK-AGENT select CONTINUATION prompt for prompts 2+? + +**Success Criteria**: +- [ ] Logs collected for 3 test prompts +- [ ] Database queries run and results saved +- [ ] Data flow analysis completed +- [ ] Failure point identified + +**Handoff to Phase 3**: Document exact failure point (which log entry shows incorrect value) and move to fix implementation + +--- + +## Phase 3: Implement Fix Based on Findings + +**Goal**: Fix the identified root cause of session continuity failure. + +**Prerequisites**: Phase 2 completed, failure point identified from logs/database + +**Common Fix Scenarios**: + +### Scenario A: Hook Receives Different `session_id` Each Time + +**Symptom in Logs**: +``` +[NEW-HOOK] Received hook input: { session_id: 'abc-123', ... } // Prompt 1 +[NEW-HOOK] Received hook input: { session_id: 'def-456', ... } // Prompt 2 - DIFFERENT! +``` + +**Root Cause**: Hook not receiving consistent session ID from Claude Code + +**Fix Location**: This is external to codebase - investigate Claude Code hook configuration or report bug + +**Action**: Create GitHub issue in claude-code repo with evidence + +### Scenario B: `promptNumber` Not Passed or Calculated Correctly + +**Symptom in Logs**: +``` +[SESSION-ROUTES] Calculated promptNumber: { promptNumber: 1, currentCount: 1 } // Prompt 2 - WRONG! +``` + +**Root Cause**: User prompt not being saved to database, or count query failing + +**Fix Location**: `src/services/worker/http/routes/SessionRoutes.ts` line 520 + +**Fix**: +```typescript +// Add error handling around saveUserPrompt +try { + this.dbManager.getSessionStore().saveUserPrompt( + claudeSessionId, + promptNumber, + cleanedPrompt + ); + console.log('[SESSION-ROUTES] Successfully saved user prompt:', { + claudeSessionId, + promptNumber + }); +} catch (error) { + console.error('[SESSION-ROUTES] Failed to save user prompt:', error); + throw new Error(`Failed to save user prompt: ${error.message}`); +} +``` + +### Scenario C: Session Manager Uses Wrong Fallback Logic + +**Symptom in Logs**: +``` +[SESSION-MANAGER] Creating new session object: { lastPromptNumber: 1 } // Prompt 2 - WRONG! +``` + +**Root Cause**: Fragile `||` operator causing incorrect fallback when `promptNumber` is valid + +**Fix Location**: `src/services/worker/SessionManager.ts` line 116 + +**Fix**: +```typescript +// Replace fragile || with explicit undefined check +lastPromptNumber: promptNumber !== undefined + ? promptNumber + : this.dbManager.getSessionStore().getPromptNumberFromUserPrompts(dbSession.claude_session_id), +``` + +### Scenario D: Database Session Not Found + +**Symptom in Logs**: +``` +[SESSION-MANAGER] Fetched session from database: { claude_session_id: undefined } +``` + +**Root Cause**: `createSDKSession` INSERT failed silently, or session was deleted + +**Fix Location**: `src/services/sqlite/SessionStore.ts` line 1086-1101 + +**Fix**: +```typescript +// Add validation after INSERT OR IGNORE +const result = 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(claudeSessionId, claudeSessionId, project, userPrompt, now, nowEpoch, 'active'); + +// Verify session exists +const row = this.db.prepare('SELECT id FROM sdk_sessions WHERE claude_session_id = ?') + .get(claudeSessionId); + +if (!row) { + throw new Error(`Failed to create or retrieve SDK session for claudeSessionId: ${claudeSessionId}`); +} + +return row.id; +``` + +### Scenario E: SDK Agent Receives Empty `claudeSessionId` + +**Symptom in Logs**: +``` +[SDK-AGENT] Starting SDK query with: { claudeSessionId: undefined, resume_parameter: undefined } +``` + +**Root Cause**: SessionManager created session object with missing `claudeSessionId` + +**Fix Location**: `src/services/worker/SessionManager.ts` line 109 + +**Fix**: +```typescript +// Add validation before using database values +if (!dbSession.claude_session_id) { + throw new Error(`Database session ${sessionDbId} has no claude_session_id`); +} + +session = { + sessionDbId, + claudeSessionId: dbSession.claude_session_id, + // ... rest of session object +}; +``` + +**Success Criteria**: +- [ ] Fix implemented at identified failure point +- [ ] Validation added to fail loudly on errors +- [ ] Build succeeds +- [ ] Worker service restarts successfully + +**Handoff to Phase 4**: Build and deploy fix, then run verification tests + +--- + +## Phase 4: Verify Fix and Test Session Continuity + +**Goal**: Confirm session continuity is working correctly after fix. + +**Prerequisites**: Phase 3 completed, fix deployed, worker service running + +**Verification Procedure**: + +### 4.1 Run Full Test Conversation + +In a fresh Claude Code session: + +1. **Prompt 1**: "This is test prompt one for session continuity" +2. **Prompt 2**: "This is test prompt two, continuing the session" +3. **Prompt 3**: "This is test prompt three, still continuing" +4. **Prompt 4**: "Final test prompt four" + +### 4.2 Check Logs + +Verify in worker logs: + +**All prompts show same `session_id`**: +``` +[NEW-HOOK] Received hook input: { session_id: 'abc-123' } // All 4 prompts +``` + +**Prompt numbers increment**: +``` +[SESSION-ROUTES] Calculated promptNumber: { promptNumber: 1 } // Prompt 1 +[SESSION-ROUTES] Calculated promptNumber: { promptNumber: 2 } // Prompt 2 +[SESSION-ROUTES] Calculated promptNumber: { promptNumber: 3 } // Prompt 3 +[SESSION-ROUTES] Calculated promptNumber: { promptNumber: 4 } // Prompt 4 +``` + +**SDK Agent uses continuation prompts**: +``` +[SDK-AGENT] Creating message generator: { promptType: 'INIT' } // Prompt 1 +[SDK-AGENT] Creating message generator: { promptType: 'CONTINUATION' } // Prompt 2 +[SDK-AGENT] Creating message generator: { promptType: 'CONTINUATION' } // Prompt 3 +[SDK-AGENT] Creating message generator: { promptType: 'CONTINUATION' } // Prompt 4 +``` + +### 4.3 Verify Database State + +**Check sessions table**: +```bash +sqlite3 ~/.claude-mem/claude-mem.db "SELECT id, claude_session_id, sdk_session_id FROM sdk_sessions ORDER BY id DESC LIMIT 5;" +``` + +**Expected**: Only ONE session record for the 4 prompts, `claude_session_id` and `sdk_session_id` are identical + +**Check user_prompts table**: +```bash +sqlite3 ~/.claude-mem/claude-mem.db "SELECT claude_session_id, prompt_number, created_at FROM user_prompts ORDER BY created_at DESC LIMIT 5;" +``` + +**Expected**: 4 records with same `claude_session_id`, prompt_number values: 4, 3, 2, 1 + +### 4.4 Functional Test + +Verify actual session continuity behavior: + +1. **Prompt 1**: "My favorite color is blue" +2. **Prompt 2**: "What is my favorite color?" + - **Expected**: Response mentions "blue" +3. **Prompt 3**: "Change it to red" +4. **Prompt 4**: "What is my favorite color now?" + - **Expected**: Response mentions "red" + +**Success Criteria**: +- [x] Same `session_id` across all 4 prompts in logs +- [x] Prompt numbers increment: 1, 2, 3, 4 +- [x] INIT prompt only for first prompt +- [x] CONTINUATION prompts for prompts 2, 3, 4 +- [x] Only one session record in database +- [x] Four user_prompts records with incremental prompt_number +- [x] Functional test shows session continuity working + +**Handoff to Phase 5**: If all criteria pass, proceed to cleanup. If any fail, return to Phase 2 with new diagnostic focus. + +--- + +## Phase 5: Cleanup and Documentation + +**Goal**: Remove excessive logging, update documentation, close issues. + +**Prerequisites**: Phase 4 completed successfully, session continuity verified working + +**Cleanup Steps**: + +### 5.1 Reduce Logging Verbosity (Optional) + +You can either: +- **Keep all diagnostic logging** for future debugging (recommended) +- **Remove logging** to reduce noise in production logs +- **Convert to debug level** if logging framework supports it + +If removing logging, remove the `console.log` statements added in Phase 1 from: +- `src/hooks/new-hook.ts` +- `src/services/worker/http/routes/SessionRoutes.ts` +- `src/services/worker/SessionManager.ts` +- `src/services/worker/SDKAgent.ts` + +### 5.2 Update Documentation + +If the fix revealed any architectural insights, update: +- `CLAUDE.md` - Add any new gotchas or patterns discovered +- `README.md` - Update if user-facing behavior changed +- Code comments - Document the fix rationale + +### 5.3 Create Regression Test (Future Work) + +Consider adding automated test: +```typescript +describe('Session Continuity', () => { + it('should use same session ID across multiple prompts', async () => { + // Test that verifies session ID propagation + }); + + it('should increment prompt numbers correctly', async () => { + // Test that verifies prompt number calculation + }); +}); +``` + +### 5.4 Close Related Issues + +Search GitHub for related issues: +```bash +gh issue list --search "session continuity" --state open +gh issue list --search "session persistence" --state open +gh issue list --search "new session" --state open +``` + +Close with comment explaining the fix. + +**Success Criteria**: +- [ ] Logging cleaned up as desired +- [ ] Documentation updated +- [ ] Related GitHub issues closed +- [ ] No regressions introduced + +--- + +## Quick Reference + +### Key Files and What They Do + +| File | Purpose | Critical Lines | +|------|---------|----------------| +| `src/hooks/new-hook.ts` | Hook entry point, receives session_id from Claude Code | 24, 34, 46-47, 63-68 | +| `src/services/worker/http/routes/SessionRoutes.ts` | HTTP endpoints for session init, calculates prompt numbers | 482-533, 171-227 | +| `src/services/sqlite/SessionStore.ts` | Database operations for sessions and user prompts | 1086-1101, 1053-1058 | +| `src/services/worker/SessionManager.ts` | In-memory session management, bridges DB and SDK | 49-141, esp. 109, 116 | +| `src/services/worker/SDKAgent.ts` | SDK integration, sends resume parameter and prompts | 68-77, 195-218, 200-202 | +| `src/sdk/prompts.ts` | Init and continuation prompt templates | 30-87, 169-229 | + +### Build and Deploy Commands + +```bash +# Build TypeScript +npm run build + +# Sync to marketplace and restart worker +npm run build-and-sync + +# Restart worker only +killall bun +bun ~/.claude/plugins/marketplaces/thedotmack/scripts/worker-service.cjs & + +# Check worker is running +curl http://localhost:37777/health +``` + +### Database Queries + +```bash +# Check sessions +sqlite3 ~/.claude-mem/claude-mem.db "SELECT * FROM sdk_sessions ORDER BY id DESC LIMIT 10;" + +# Check user prompts +sqlite3 ~/.claude-mem/claude-mem.db "SELECT * FROM user_prompts ORDER BY created_at DESC LIMIT 10;" + +# Count prompts per session +sqlite3 ~/.claude-mem/claude-mem.db "SELECT claude_session_id, COUNT(*) as prompt_count FROM user_prompts GROUP BY claude_session_id ORDER BY prompt_count DESC LIMIT 10;" +``` + +### Debugging Tips + +1. **Check worker is running**: `curl http://localhost:37777/health` +2. **View worker logs**: `tail -f /tmp/worker-logs.txt` +3. **Check hook output**: Logs appear in Claude Code's stderr +4. **Database locked**: `killall bun` then restart worker +5. **Stale build**: `rm -rf plugin/scripts/*.js && npm run build` + +--- + +## Phase Execution Checklist + +Use this checklist when executing phases in new chat contexts: + +**Phase 1: Diagnostic Logging** +- [ ] Read this plan document +- [ ] Read the 4 files to modify +- [ ] Add all 15+ log points +- [ ] Build with `npm run build-and-sync` +- [ ] Verify worker restarts +- [ ] Mark phase complete, handoff to Phase 2 + +**Phase 2: Test and Gather Data** +- [ ] Read Phase 2 section +- [ ] Run 3 test prompts +- [ ] Collect and save logs +- [ ] Run database queries +- [ ] Trace data flow +- [ ] Identify failure point +- [ ] Document failure point +- [ ] Mark phase complete, handoff to Phase 3 + +**Phase 3: Implement Fix** +- [ ] Read Phase 3 section +- [ ] Review failure point from Phase 2 +- [ ] Select applicable scenario +- [ ] Implement fix +- [ ] Add validation +- [ ] Build and deploy +- [ ] Mark phase complete, handoff to Phase 4 + +**Phase 4: Verify Fix** +- [ ] Read Phase 4 section +- [ ] Run 4 test prompts +- [ ] Check logs for correct behavior +- [ ] Verify database state +- [ ] Run functional test +- [ ] All success criteria pass +- [ ] Mark phase complete, handoff to Phase 5 + +**Phase 5: Cleanup** +- [ ] Read Phase 5 section +- [ ] Clean up logging (optional) +- [ ] Update documentation +- [ ] Close GitHub issues +- [ ] Mark phase complete +- [ ] Session continuity regression FIX COMPLETE ✅ + +--- + +## Context for New Chat Sessions + +When starting a new phase, provide this context: + +**I'm working on Phase [X] of the Session Continuity Regression Fix for claude-mem.** + +**Background**: Session continuity is broken - each prompt creates a new session instead of continuing. This has been a recurring issue for 3 months. The root cause is that session SDK ID is not being propagated correctly from new-hook through to SDKAgent. + +**Current Status**: [Briefly describe what previous phases accomplished] + +**This Phase Goal**: [Copy the goal from the phase section] + +**Plan Document**: Read `/Users/alexnewman/Scripts/claude-mem/PLAN-SESSION-CONTINUITY-FIX.md` for full context. + +--- + +## Success Metrics + +**Overall Fix Success**: +- [ ] Same session ID used across multiple prompts in one conversation +- [ ] Prompt numbers increment correctly (1, 2, 3, ...) +- [ ] Init prompt only sent on first prompt +- [ ] Continuation prompts sent on subsequent prompts +- [ ] SDK receives correct resume parameter +- [ ] Only one session record created per conversation +- [ ] Functional session continuity test passes +- [ ] No new regressions introduced + +**Regression Prevention**: +- [ ] Validation added to fail loudly on errors +- [ ] No silent fallbacks that hide bugs +- [ ] Database queries verified +- [ ] Session ID propagation explicitly tested + +--- + +**Last Updated**: 2025-12-27 +**Author**: Claude (investigating 3-month recurring session continuity regression) diff --git a/plugin/scripts/worker-service.cjs b/plugin/scripts/worker-service.cjs index 69662103..d89c55d7 100755 --- a/plugin/scripts/worker-service.cjs +++ b/plugin/scripts/worker-service.cjs @@ -970,7 +970,7 @@ ${n.prompts.header_memory_continued}`}$r();pr();ia();var wm=require("path"),wT=r ...iss, path: iss.path ? [${ei(y)}, ...iss.path] : [${ei(y)}] })));`),f.write(`newResult[${ei(y)}] = ${v}.value`)}f.write("payload.value = newResult;"),f.write("return payload;");let h=f.compile();return(y,v)=>h(d,y,v)},a,s=Vo,i=!Mm.jitless,c=i&&XT.value,u=e.catchall,l;t._zod.parse=(d,f)=>{l??(l=r.value);let m=d.value;if(!s(m))return d.issues.push({expected:"object",code:"invalid_type",input:m,inst:t}),d;let g=[];if(i&&c&&f?.async===!1&&f.jitless!==!0)a||(a=n(e.shape)),d=a(d,f);else{d.value={};let v=l.shape;for(let b of l.keys){let w=v[b],x=w._zod.run({value:m[b],issues:[]},f),E=w._zod.optin==="optional"&&w._zod.optout==="optional";x instanceof Promise?g.push(x.then(T=>E?Z1(T,d,b,m):nl(T,d,b))):E?Z1(x,d,b,m):nl(x,d,b)}}if(!u)return g.length?Promise.all(g).then(()=>d):d;let _=[],p=l.keySet,h=u._zod,y=h.def.type;for(let v of Object.keys(m)){if(p.has(v))continue;if(y==="never"){_.push(v);continue}let b=h.run({value:m[v],issues:[]},f);b instanceof Promise?g.push(b.then(w=>nl(w,d,v))):nl(b,d,v)}return _.length&&d.issues.push({code:"unrecognized_keys",keys:_,input:m,inst:t}),g.length?Promise.all(g).then(()=>d):d}});function W1(t,e,r,n){for(let a of t)if(a.issues.length===0)return e.value=a.value,e;return e.issues.push({code:"invalid_union",input:e.value,inst:r,errors:t.map(a=>a.issues.map(s=>Ea(s,n,wa())))}),e}var mk=ae("$ZodUnion",(t,e)=>{ft.init(t,e),pt(t._zod,"optin",()=>e.options.some(r=>r._zod.optin==="optional")?"optional":void 0),pt(t._zod,"optout",()=>e.options.some(r=>r._zod.optout==="optional")?"optional":void 0),pt(t._zod,"values",()=>{if(e.options.every(r=>r._zod.values))return new Set(e.options.flatMap(r=>Array.from(r._zod.values)))}),pt(t._zod,"pattern",()=>{if(e.options.every(r=>r._zod.pattern)){let r=e.options.map(n=>n._zod.pattern);return new RegExp(`^(${r.map(n=>Ol(n.source)).join("|")})$`)}}),t._zod.parse=(r,n)=>{let a=!1,s=[];for(let i of e.options){let o=i._zod.run({value:r.value,issues:[]},n);if(o instanceof Promise)s.push(o),a=!0;else{if(o.issues.length===0)return o;s.push(o)}}return a?Promise.all(s).then(i=>W1(i,r,t,n)):W1(s,r,t,n)}}),Yz=ae("$ZodDiscriminatedUnion",(t,e)=>{mk.init(t,e);let r=t._zod.parse;pt(t._zod,"propValues",()=>{let a={};for(let s of e.options){let i=s._zod.propValues;if(!i||Object.keys(i).length===0)throw new Error(`Invalid discriminated union option at index "${e.options.indexOf(s)}"`);for(let[o,c]of Object.entries(i)){a[o]||(a[o]=new Set);for(let u of c)a[o].add(u)}}return a});let n=Pl(()=>{let a=e.options,s=new Map;for(let i of a){let o=i._zod.propValues[e.discriminator];if(!o||o.size===0)throw new Error(`Invalid discriminated union option at index "${e.options.indexOf(i)}"`);for(let c of o){if(s.has(c))throw new Error(`Duplicate discriminator value "${String(c)}"`);s.set(c,i)}}return s});t._zod.parse=(a,s)=>{let i=a.value;if(!Vo(i))return a.issues.push({code:"invalid_type",expected:"object",input:i,inst:t}),a;let o=n.value.get(i?.[e.discriminator]);return o?o._zod.run(a,s):e.unionFallback?r(a,s):(a.issues.push({code:"invalid_union",errors:[],note:"No matching discriminator",input:i,path:[e.discriminator],inst:t}),a)}}),Qz=ae("$ZodIntersection",(t,e)=>{ft.init(t,e),t._zod.parse=(r,n)=>{let a=r.value,s=e.left._zod.run({value:a,issues:[]},n),i=e.right._zod.run({value:a,issues:[]},n);return s instanceof Promise||i instanceof Promise?Promise.all([s,i]).then(([c,u])=>K1(r,c,u)):K1(r,s,i)}});function Lm(t,e){if(t===e)return{valid:!0,data:t};if(t instanceof Date&&e instanceof Date&&+t==+e)return{valid:!0,data:t};if(Go(t)&&Go(e)){let r=Object.keys(e),n=Object.keys(t).filter(s=>r.indexOf(s)!==-1),a={...t,...e};for(let s of n){let i=Lm(t[s],e[s]);if(!i.valid)return{valid:!1,mergeErrorPath:[s,...i.mergeErrorPath]};a[s]=i.data}return{valid:!0,data:a}}if(Array.isArray(t)&&Array.isArray(e)){if(t.length!==e.length)return{valid:!1,mergeErrorPath:[]};let r=[];for(let n=0;n{ft.init(t,e),t._zod.parse=(r,n)=>{let a=r.value;if(!Go(a))return r.issues.push({expected:"record",code:"invalid_type",input:a,inst:t}),r;let s=[];if(e.keyType._zod.values){let i=e.keyType._zod.values;r.value={};for(let c of i)if(typeof c=="string"||typeof c=="number"||typeof c=="symbol"){let u=e.valueType._zod.run({value:a[c],issues:[]},n);u instanceof Promise?s.push(u.then(l=>{l.issues.length&&r.issues.push(...Za(c,l.issues)),r.value[c]=l.value})):(u.issues.length&&r.issues.push(...Za(c,u.issues)),r.value[c]=u.value)}let o;for(let c in a)i.has(c)||(o=o??[],o.push(c));o&&o.length>0&&r.issues.push({code:"unrecognized_keys",input:a,inst:t,keys:o})}else{r.value={};for(let i of Reflect.ownKeys(a)){if(i==="__proto__")continue;let o=e.keyType._zod.run({value:i,issues:[]},n);if(o instanceof Promise)throw new Error("Async schemas not supported in object keys currently");if(o.issues.length){r.issues.push({origin:"record",code:"invalid_key",issues:o.issues.map(u=>Ea(u,n,wa())),input:i,path:[i],inst:t}),r.value[o.value]=o.value;continue}let c=e.valueType._zod.run({value:a[i],issues:[]},n);c instanceof Promise?s.push(c.then(u=>{u.issues.length&&r.issues.push(...Za(i,u.issues)),r.value[o.value]=u.value})):(c.issues.length&&r.issues.push(...Za(i,c.issues)),r.value[o.value]=c.value)}}return s.length?Promise.all(s).then(()=>r):r}}),t3=ae("$ZodEnum",(t,e)=>{ft.init(t,e);let r=ZT(e.entries);t._zod.values=new Set(r),t._zod.pattern=new RegExp(`^(${r.filter(n=>JT.has(typeof n)).map(n=>typeof n=="string"?bi(n):n.toString()).join("|")})$`),t._zod.parse=(n,a)=>{let s=n.value;return t._zod.values.has(s)||n.issues.push({code:"invalid_value",values:r,input:s,inst:t}),n}}),r3=ae("$ZodLiteral",(t,e)=>{ft.init(t,e),t._zod.values=new Set(e.values),t._zod.pattern=new RegExp(`^(${e.values.map(r=>typeof r=="string"?bi(r):r?r.toString():String(r)).join("|")})$`),t._zod.parse=(r,n)=>{let a=r.value;return t._zod.values.has(a)||r.issues.push({code:"invalid_value",values:e.values,input:a,inst:t}),r}}),a3=ae("$ZodTransform",(t,e)=>{ft.init(t,e),t._zod.parse=(r,n)=>{let a=e.transform(r.value,r);if(n.async)return(a instanceof Promise?a:Promise.resolve(a)).then(i=>(r.value=i,r));if(a instanceof Promise)throw new Hn;return r.value=a,r}}),n3=ae("$ZodOptional",(t,e)=>{ft.init(t,e),t._zod.optin="optional",t._zod.optout="optional",pt(t._zod,"values",()=>e.innerType._zod.values?new Set([...e.innerType._zod.values,void 0]):void 0),pt(t._zod,"pattern",()=>{let r=e.innerType._zod.pattern;return r?new RegExp(`^(${Ol(r.source)})?$`):void 0}),t._zod.parse=(r,n)=>e.innerType._zod.optin==="optional"?e.innerType._zod.run(r,n):r.value===void 0?r:e.innerType._zod.run(r,n)}),s3=ae("$ZodNullable",(t,e)=>{ft.init(t,e),pt(t._zod,"optin",()=>e.innerType._zod.optin),pt(t._zod,"optout",()=>e.innerType._zod.optout),pt(t._zod,"pattern",()=>{let r=e.innerType._zod.pattern;return r?new RegExp(`^(${Ol(r.source)}|null)$`):void 0}),pt(t._zod,"values",()=>e.innerType._zod.values?new Set([...e.innerType._zod.values,null]):void 0),t._zod.parse=(r,n)=>r.value===null?r:e.innerType._zod.run(r,n)}),i3=ae("$ZodDefault",(t,e)=>{ft.init(t,e),t._zod.optin="optional",pt(t._zod,"values",()=>e.innerType._zod.values),t._zod.parse=(r,n)=>{if(r.value===void 0)return r.value=e.defaultValue,r;let a=e.innerType._zod.run(r,n);return a instanceof Promise?a.then(s=>X1(s,e)):X1(a,e)}});function X1(t,e){return t.value===void 0&&(t.value=e.defaultValue),t}var o3=ae("$ZodPrefault",(t,e)=>{ft.init(t,e),t._zod.optin="optional",pt(t._zod,"values",()=>e.innerType._zod.values),t._zod.parse=(r,n)=>(r.value===void 0&&(r.value=e.defaultValue),e.innerType._zod.run(r,n))}),c3=ae("$ZodNonOptional",(t,e)=>{ft.init(t,e),pt(t._zod,"values",()=>{let r=e.innerType._zod.values;return r?new Set([...r].filter(n=>n!==void 0)):void 0}),t._zod.parse=(r,n)=>{let a=e.innerType._zod.run(r,n);return a instanceof Promise?a.then(s=>J1(s,t)):J1(a,t)}});function J1(t,e){return!t.issues.length&&t.value===void 0&&t.issues.push({code:"invalid_type",expected:"nonoptional",input:t.value,inst:e}),t}var u3=ae("$ZodCatch",(t,e)=>{ft.init(t,e),t._zod.optin="optional",pt(t._zod,"optout",()=>e.innerType._zod.optout),pt(t._zod,"values",()=>e.innerType._zod.values),t._zod.parse=(r,n)=>{let a=e.innerType._zod.run(r,n);return a instanceof Promise?a.then(s=>(r.value=s.value,s.issues.length&&(r.value=e.catchValue({...r,error:{issues:s.issues.map(i=>Ea(i,n,wa()))},input:r.value}),r.issues=[]),r)):(r.value=a.value,a.issues.length&&(r.value=e.catchValue({...r,error:{issues:a.issues.map(s=>Ea(s,n,wa()))},input:r.value}),r.issues=[]),r)}}),l3=ae("$ZodPipe",(t,e)=>{ft.init(t,e),pt(t._zod,"values",()=>e.in._zod.values),pt(t._zod,"optin",()=>e.in._zod.optin),pt(t._zod,"optout",()=>e.out._zod.optout),t._zod.parse=(r,n)=>{let a=e.in._zod.run(r,n);return a instanceof Promise?a.then(s=>Y1(s,e,n)):Y1(a,e,n)}});function Y1(t,e,r){return ti(t)?t:e.out._zod.run({value:t.value,issues:t.issues},r)}var d3=ae("$ZodReadonly",(t,e)=>{ft.init(t,e),pt(t._zod,"propValues",()=>e.innerType._zod.propValues),pt(t._zod,"values",()=>e.innerType._zod.values),pt(t._zod,"optin",()=>e.innerType._zod.optin),pt(t._zod,"optout",()=>e.innerType._zod.optout),t._zod.parse=(r,n)=>{let a=e.innerType._zod.run(r,n);return a instanceof Promise?a.then(Q1):Q1(a)}});function Q1(t){return t.value=Object.freeze(t.value),t}var p3=ae("$ZodCustom",(t,e)=>{or.init(t,e),ft.init(t,e),t._zod.parse=(r,n)=>r,t._zod.check=r=>{let n=r.value,a=e.fn(n);if(a instanceof Promise)return a.then(s=>eT(s,r,n,t));eT(a,r,n,t)}});function eT(t,e,r,n){if(!t){let a={code:"custom",input:r,inst:n,path:[...n._zod.def.path??[]],continue:!n._zod.def.abort};n._zod.def.params&&(a.params=n._zod.def.params),e.issues.push(ek(a))}}var f3=t=>{let e=typeof t;switch(e){case"number":return Number.isNaN(t)?"NaN":"number";case"object":{if(Array.isArray(t))return"array";if(t===null)return"null";if(Object.getPrototypeOf(t)!==Object.prototype&&t.constructor)return t.constructor.name}}return e},m3=()=>{let t={string:{unit:"characters",verb:"to have"},file:{unit:"bytes",verb:"to have"},array:{unit:"items",verb:"to have"},set:{unit:"items",verb:"to have"}};function e(n){return t[n]??null}let r={regex:"input",email:"email address",url:"URL",emoji:"emoji",uuid:"UUID",uuidv4:"UUIDv4",uuidv6:"UUIDv6",nanoid:"nanoid",guid:"GUID",cuid:"cuid",cuid2:"cuid2",ulid:"ULID",xid:"XID",ksuid:"KSUID",datetime:"ISO datetime",date:"ISO date",time:"ISO time",duration:"ISO duration",ipv4:"IPv4 address",ipv6:"IPv6 address",cidrv4:"IPv4 range",cidrv6:"IPv6 range",base64:"base64-encoded string",base64url:"base64url-encoded string",json_string:"JSON string",e164:"E.164 number",jwt:"JWT",template_literal:"input"};return n=>{switch(n.code){case"invalid_type":return`Invalid input: expected ${n.expected}, received ${f3(n.input)}`;case"invalid_value":return n.values.length===1?`Invalid input: expected ${Qm(n.values[0])}`:`Invalid option: expected one of ${jm(n.values,"|")}`;case"too_big":{let a=n.inclusive?"<=":"<",s=e(n.origin);return s?`Too big: expected ${n.origin??"value"} to have ${a}${n.maximum.toString()} ${s.unit??"elements"}`:`Too big: expected ${n.origin??"value"} to be ${a}${n.maximum.toString()}`}case"too_small":{let a=n.inclusive?">=":">",s=e(n.origin);return s?`Too small: expected ${n.origin} to have ${a}${n.minimum.toString()} ${s.unit}`:`Too small: expected ${n.origin} to be ${a}${n.minimum.toString()}`}case"invalid_format":{let a=n;return a.format==="starts_with"?`Invalid string: must start with "${a.prefix}"`:a.format==="ends_with"?`Invalid string: must end with "${a.suffix}"`:a.format==="includes"?`Invalid string: must include "${a.includes}"`:a.format==="regex"?`Invalid string: must match pattern ${a.pattern}`:`Invalid ${r[a.format]??n.format}`}case"not_multiple_of":return`Invalid number: must be a multiple of ${n.divisor}`;case"unrecognized_keys":return`Unrecognized key${n.keys.length>1?"s":""}: ${jm(n.keys,", ")}`;case"invalid_key":return`Invalid key in ${n.origin}`;case"invalid_union":return"Invalid input";case"invalid_element":return`Invalid value in ${n.origin}`;default:return"Invalid input"}}};function h3(){return{localeError:m3()}}var $J=Symbol("ZodOutput"),OJ=Symbol("ZodInput"),Fm=class{constructor(){this._map=new WeakMap,this._idmap=new Map}add(e,...r){let n=r[0];if(this._map.set(e,n),n&&typeof n=="object"&&"id"in n){if(this._idmap.has(n.id))throw new Error(`ID ${n.id} already exists in the registry`);this._idmap.set(n.id,e)}return this}remove(e){return this._map.delete(e),this}get(e){let r=e._zod.parent;if(r){let n={...this.get(r)??{}};return delete n.id,{...n,...this._map.get(e)}}return this._map.get(e)}has(e){return this._map.has(e)}};function v3(){return new Fm}var sl=v3();function g3(t,e){return new t({type:"string",...Pe(e)})}function y3(t,e){return new t({type:"string",format:"email",check:"string_format",abort:!1,...Pe(e)})}function tT(t,e){return new t({type:"string",format:"guid",check:"string_format",abort:!1,...Pe(e)})}function _3(t,e){return new t({type:"string",format:"uuid",check:"string_format",abort:!1,...Pe(e)})}function b3(t,e){return new t({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...Pe(e)})}function x3(t,e){return new t({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...Pe(e)})}function S3(t,e){return new t({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...Pe(e)})}function w3(t,e){return new t({type:"string",format:"url",check:"string_format",abort:!1,...Pe(e)})}function E3(t,e){return new t({type:"string",format:"emoji",check:"string_format",abort:!1,...Pe(e)})}function T3(t,e){return new t({type:"string",format:"nanoid",check:"string_format",abort:!1,...Pe(e)})}function k3(t,e){return new t({type:"string",format:"cuid",check:"string_format",abort:!1,...Pe(e)})}function R3(t,e){return new t({type:"string",format:"cuid2",check:"string_format",abort:!1,...Pe(e)})}function P3(t,e){return new t({type:"string",format:"ulid",check:"string_format",abort:!1,...Pe(e)})}function $3(t,e){return new t({type:"string",format:"xid",check:"string_format",abort:!1,...Pe(e)})}function O3(t,e){return new t({type:"string",format:"ksuid",check:"string_format",abort:!1,...Pe(e)})}function C3(t,e){return new t({type:"string",format:"ipv4",check:"string_format",abort:!1,...Pe(e)})}function I3(t,e){return new t({type:"string",format:"ipv6",check:"string_format",abort:!1,...Pe(e)})}function A3(t,e){return new t({type:"string",format:"cidrv4",check:"string_format",abort:!1,...Pe(e)})}function N3(t,e){return new t({type:"string",format:"cidrv6",check:"string_format",abort:!1,...Pe(e)})}function M3(t,e){return new t({type:"string",format:"base64",check:"string_format",abort:!1,...Pe(e)})}function j3(t,e){return new t({type:"string",format:"base64url",check:"string_format",abort:!1,...Pe(e)})}function D3(t,e){return new t({type:"string",format:"e164",check:"string_format",abort:!1,...Pe(e)})}function q3(t,e){return new t({type:"string",format:"jwt",check:"string_format",abort:!1,...Pe(e)})}function L3(t,e){return new t({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...Pe(e)})}function F3(t,e){return new t({type:"string",format:"date",check:"string_format",...Pe(e)})}function U3(t,e){return new t({type:"string",format:"time",check:"string_format",precision:null,...Pe(e)})}function z3(t,e){return new t({type:"string",format:"duration",check:"string_format",...Pe(e)})}function H3(t,e){return new t({type:"number",checks:[],...Pe(e)})}function B3(t,e){return new t({type:"number",check:"number_format",abort:!1,format:"safeint",...Pe(e)})}function V3(t,e){return new t({type:"boolean",...Pe(e)})}function G3(t,e){return new t({type:"null",...Pe(e)})}function Z3(t){return new t({type:"unknown"})}function W3(t,e){return new t({type:"never",...Pe(e)})}function rT(t,e){return new lk({check:"less_than",...Pe(e),value:t,inclusive:!1})}function bm(t,e){return new lk({check:"less_than",...Pe(e),value:t,inclusive:!0})}function aT(t,e){return new dk({check:"greater_than",...Pe(e),value:t,inclusive:!1})}function xm(t,e){return new dk({check:"greater_than",...Pe(e),value:t,inclusive:!0})}function nT(t,e){return new oz({check:"multiple_of",...Pe(e),value:t})}function hk(t,e){return new uz({check:"max_length",...Pe(e),maximum:t})}function hl(t,e){return new lz({check:"min_length",...Pe(e),minimum:t})}function vk(t,e){return new dz({check:"length_equals",...Pe(e),length:t})}function K3(t,e){return new pz({check:"string_format",format:"regex",...Pe(e),pattern:t})}function X3(t){return new fz({check:"string_format",format:"lowercase",...Pe(t)})}function J3(t){return new mz({check:"string_format",format:"uppercase",...Pe(t)})}function Y3(t,e){return new hz({check:"string_format",format:"includes",...Pe(e),includes:t})}function Q3(t,e){return new vz({check:"string_format",format:"starts_with",...Pe(e),prefix:t})}function eH(t,e){return new gz({check:"string_format",format:"ends_with",...Pe(e),suffix:t})}function Wo(t){return new yz({check:"overwrite",tx:t})}function tH(t){return Wo(e=>e.normalize(t))}function rH(){return Wo(t=>t.trim())}function aH(){return Wo(t=>t.toLowerCase())}function nH(){return Wo(t=>t.toUpperCase())}function sH(t,e,r){return new t({type:"array",element:e,...Pe(r)})}function iH(t,e,r){let n=Pe(r);return n.abort??(n.abort=!0),new t({type:"custom",check:"custom",fn:e,...n})}function oH(t,e,r){return new t({type:"custom",check:"custom",fn:e,...Pe(r)})}var gk={};dT(gk,{time:()=>wk,duration:()=>Tk,datetime:()=>_k,date:()=>xk,ZodISOTime:()=>Sk,ZodISODuration:()=>Ek,ZodISODateTime:()=>yk,ZodISODate:()=>bk});var yk=ae("ZodISODateTime",(t,e)=>{Cz.init(t,e),St.init(t,e)});function _k(t){return L3(yk,t)}var bk=ae("ZodISODate",(t,e)=>{Iz.init(t,e),St.init(t,e)});function xk(t){return F3(bk,t)}var Sk=ae("ZodISOTime",(t,e)=>{Az.init(t,e),St.init(t,e)});function wk(t){return U3(Sk,t)}var Ek=ae("ZodISODuration",(t,e)=>{Nz.init(t,e),St.init(t,e)});function Tk(t){return z3(Ek,t)}var kk=(t,e)=>{rk.init(t,e),t.name="ZodError",Object.defineProperties(t,{format:{value:r=>PU(t,r)},flatten:{value:r=>RU(t,r)},addIssue:{value:r=>t.issues.push(r)},addIssues:{value:r=>t.issues.push(...r)},isEmpty:{get(){return t.issues.length===0}}})},CJ=ae("ZodError",kk),Al=ae("ZodError",kk,{Parent:Error}),cH=$U(Al),uH=OU(Al),lH=nk(Al),dH=sk(Al),xt=ae("ZodType",(t,e)=>(ft.init(t,e),t.def=e,Object.defineProperty(t,"_def",{value:e}),t.check=(...r)=>t.clone({...e,checks:[...e.checks??[],...r.map(n=>typeof n=="function"?{_zod:{check:n,def:{check:"custom"},onattach:[]}}:n)]}),t.clone=(r,n)=>Ya(t,r,n),t.brand=()=>t,t.register=(r,n)=>(r.add(t,n),t),t.parse=(r,n)=>cH(t,r,n,{callee:t.parse}),t.safeParse=(r,n)=>lH(t,r,n),t.parseAsync=async(r,n)=>uH(t,r,n,{callee:t.parseAsync}),t.safeParseAsync=async(r,n)=>dH(t,r,n),t.spa=t.safeParseAsync,t.refine=(r,n)=>t.check(tB(r,n)),t.superRefine=r=>t.check(rB(r)),t.overwrite=r=>t.check(Wo(r)),t.optional=()=>Se(t),t.nullable=()=>oT(t),t.nullish=()=>Se(oT(t)),t.nonoptional=r=>ZH(t,r),t.array=()=>Ge(t),t.or=r=>gt([t,r]),t.and=r=>th(t,r),t.transform=r=>zm(t,Ak(r)),t.default=r=>BH(t,r),t.prefault=r=>GH(t,r),t.catch=r=>KH(t,r),t.pipe=r=>zm(t,r),t.readonly=()=>YH(t),t.describe=r=>{let n=t.clone();return sl.add(n,{description:r}),n},Object.defineProperty(t,"description",{get(){return sl.get(t)?.description},configurable:!0}),t.meta=(...r)=>{if(r.length===0)return sl.get(t);let n=t.clone();return sl.add(n,r[0]),n},t.isOptional=()=>t.safeParse(void 0).success,t.isNullable=()=>t.safeParse(null).success,t)),Rk=ae("_ZodString",(t,e)=>{eh.init(t,e),xt.init(t,e);let r=t._zod.bag;t.format=r.format??null,t.minLength=r.minimum??null,t.maxLength=r.maximum??null,t.regex=(...n)=>t.check(K3(...n)),t.includes=(...n)=>t.check(Y3(...n)),t.startsWith=(...n)=>t.check(Q3(...n)),t.endsWith=(...n)=>t.check(eH(...n)),t.min=(...n)=>t.check(hl(...n)),t.max=(...n)=>t.check(hk(...n)),t.length=(...n)=>t.check(vk(...n)),t.nonempty=(...n)=>t.check(hl(1,...n)),t.lowercase=n=>t.check(X3(n)),t.uppercase=n=>t.check(J3(n)),t.trim=()=>t.check(rH()),t.normalize=(...n)=>t.check(tH(...n)),t.toLowerCase=()=>t.check(aH()),t.toUpperCase=()=>t.check(nH())}),pH=ae("ZodString",(t,e)=>{eh.init(t,e),Rk.init(t,e),t.email=r=>t.check(y3(fH,r)),t.url=r=>t.check(w3(mH,r)),t.jwt=r=>t.check(q3($H,r)),t.emoji=r=>t.check(E3(hH,r)),t.guid=r=>t.check(tT(sT,r)),t.uuid=r=>t.check(_3(il,r)),t.uuidv4=r=>t.check(b3(il,r)),t.uuidv6=r=>t.check(x3(il,r)),t.uuidv7=r=>t.check(S3(il,r)),t.nanoid=r=>t.check(T3(vH,r)),t.guid=r=>t.check(tT(sT,r)),t.cuid=r=>t.check(k3(gH,r)),t.cuid2=r=>t.check(R3(yH,r)),t.ulid=r=>t.check(P3(_H,r)),t.base64=r=>t.check(M3(kH,r)),t.base64url=r=>t.check(j3(RH,r)),t.xid=r=>t.check($3(bH,r)),t.ksuid=r=>t.check(O3(xH,r)),t.ipv4=r=>t.check(C3(SH,r)),t.ipv6=r=>t.check(I3(wH,r)),t.cidrv4=r=>t.check(A3(EH,r)),t.cidrv6=r=>t.check(N3(TH,r)),t.e164=r=>t.check(D3(PH,r)),t.datetime=r=>t.check(_k(r)),t.date=r=>t.check(xk(r)),t.time=r=>t.check(wk(r)),t.duration=r=>t.check(Tk(r))});function te(t){return g3(pH,t)}var St=ae("ZodStringFormat",(t,e)=>{vt.init(t,e),Rk.init(t,e)}),fH=ae("ZodEmail",(t,e)=>{Sz.init(t,e),St.init(t,e)}),sT=ae("ZodGUID",(t,e)=>{bz.init(t,e),St.init(t,e)}),il=ae("ZodUUID",(t,e)=>{xz.init(t,e),St.init(t,e)}),mH=ae("ZodURL",(t,e)=>{wz.init(t,e),St.init(t,e)}),hH=ae("ZodEmoji",(t,e)=>{Ez.init(t,e),St.init(t,e)}),vH=ae("ZodNanoID",(t,e)=>{Tz.init(t,e),St.init(t,e)}),gH=ae("ZodCUID",(t,e)=>{kz.init(t,e),St.init(t,e)}),yH=ae("ZodCUID2",(t,e)=>{Rz.init(t,e),St.init(t,e)}),_H=ae("ZodULID",(t,e)=>{Pz.init(t,e),St.init(t,e)}),bH=ae("ZodXID",(t,e)=>{$z.init(t,e),St.init(t,e)}),xH=ae("ZodKSUID",(t,e)=>{Oz.init(t,e),St.init(t,e)}),SH=ae("ZodIPv4",(t,e)=>{Mz.init(t,e),St.init(t,e)}),wH=ae("ZodIPv6",(t,e)=>{jz.init(t,e),St.init(t,e)}),EH=ae("ZodCIDRv4",(t,e)=>{Dz.init(t,e),St.init(t,e)}),TH=ae("ZodCIDRv6",(t,e)=>{qz.init(t,e),St.init(t,e)}),kH=ae("ZodBase64",(t,e)=>{Lz.init(t,e),St.init(t,e)}),RH=ae("ZodBase64URL",(t,e)=>{Uz.init(t,e),St.init(t,e)}),PH=ae("ZodE164",(t,e)=>{zz.init(t,e),St.init(t,e)}),$H=ae("ZodJWT",(t,e)=>{Bz.init(t,e),St.init(t,e)}),Pk=ae("ZodNumber",(t,e)=>{fk.init(t,e),xt.init(t,e),t.gt=(n,a)=>t.check(aT(n,a)),t.gte=(n,a)=>t.check(xm(n,a)),t.min=(n,a)=>t.check(xm(n,a)),t.lt=(n,a)=>t.check(rT(n,a)),t.lte=(n,a)=>t.check(bm(n,a)),t.max=(n,a)=>t.check(bm(n,a)),t.int=n=>t.check(iT(n)),t.safe=n=>t.check(iT(n)),t.positive=n=>t.check(aT(0,n)),t.nonnegative=n=>t.check(xm(0,n)),t.negative=n=>t.check(rT(0,n)),t.nonpositive=n=>t.check(bm(0,n)),t.multipleOf=(n,a)=>t.check(nT(n,a)),t.step=(n,a)=>t.check(nT(n,a)),t.finite=()=>t;let r=t._zod.bag;t.minValue=Math.max(r.minimum??Number.NEGATIVE_INFINITY,r.exclusiveMinimum??Number.NEGATIVE_INFINITY)??null,t.maxValue=Math.min(r.maximum??Number.POSITIVE_INFINITY,r.exclusiveMaximum??Number.POSITIVE_INFINITY)??null,t.isInt=(r.format??"").includes("int")||Number.isSafeInteger(r.multipleOf??.5),t.isFinite=!0,t.format=r.format??null});function ut(t){return H3(Pk,t)}var OH=ae("ZodNumberFormat",(t,e)=>{Vz.init(t,e),Pk.init(t,e)});function iT(t){return B3(OH,t)}var CH=ae("ZodBoolean",(t,e)=>{Gz.init(t,e),xt.init(t,e)});function Ht(t){return V3(CH,t)}var IH=ae("ZodNull",(t,e)=>{Zz.init(t,e),xt.init(t,e)});function $k(t){return G3(IH,t)}var AH=ae("ZodUnknown",(t,e)=>{Wz.init(t,e),xt.init(t,e)});function Nt(){return Z3(AH)}var NH=ae("ZodNever",(t,e)=>{Kz.init(t,e),xt.init(t,e)});function MH(t){return W3(NH,t)}var jH=ae("ZodArray",(t,e)=>{Xz.init(t,e),xt.init(t,e),t.element=e.element,t.min=(r,n)=>t.check(hl(r,n)),t.nonempty=r=>t.check(hl(1,r)),t.max=(r,n)=>t.check(hk(r,n)),t.length=(r,n)=>t.check(vk(r,n)),t.unwrap=()=>t.element});function Ge(t,e){return sH(jH,t,e)}var Ok=ae("ZodObject",(t,e)=>{Jz.init(t,e),xt.init(t,e),dt.defineLazy(t,"shape",()=>e.shape),t.keyof=()=>Bt(Object.keys(t._zod.def.shape)),t.catchall=r=>t.clone({...t._zod.def,catchall:r}),t.passthrough=()=>t.clone({...t._zod.def,catchall:Nt()}),t.loose=()=>t.clone({...t._zod.def,catchall:Nt()}),t.strict=()=>t.clone({...t._zod.def,catchall:MH()}),t.strip=()=>t.clone({...t._zod.def,catchall:void 0}),t.extend=r=>dt.extend(t,r),t.merge=r=>dt.merge(t,r),t.pick=r=>dt.pick(t,r),t.omit=r=>dt.omit(t,r),t.partial=(...r)=>dt.partial(Nk,t,r[0]),t.required=(...r)=>dt.required(Mk,t,r[0])});function le(t,e){let r={type:"object",get shape(){return dt.assignProp(this,"shape",{...t}),this.shape},...dt.normalizeParams(e)};return new Ok(r)}function Hr(t,e){return new Ok({type:"object",get shape(){return dt.assignProp(this,"shape",{...t}),this.shape},catchall:Nt(),...dt.normalizeParams(e)})}var Ck=ae("ZodUnion",(t,e)=>{mk.init(t,e),xt.init(t,e),t.options=e.options});function gt(t,e){return new Ck({type:"union",options:t,...dt.normalizeParams(e)})}var DH=ae("ZodDiscriminatedUnion",(t,e)=>{Ck.init(t,e),Yz.init(t,e)});function Ik(t,e,r){return new DH({type:"union",options:e,discriminator:t,...dt.normalizeParams(r)})}var qH=ae("ZodIntersection",(t,e)=>{Qz.init(t,e),xt.init(t,e)});function th(t,e){return new qH({type:"intersection",left:t,right:e})}var LH=ae("ZodRecord",(t,e)=>{e3.init(t,e),xt.init(t,e),t.keyType=e.keyType,t.valueType=e.valueType});function Mt(t,e,r){return new LH({type:"record",keyType:t,valueType:e,...dt.normalizeParams(r)})}var Um=ae("ZodEnum",(t,e)=>{t3.init(t,e),xt.init(t,e),t.enum=e.entries,t.options=Object.values(e.entries);let r=new Set(Object.keys(e.entries));t.extract=(n,a)=>{let s={};for(let i of n)if(r.has(i))s[i]=e.entries[i];else throw new Error(`Key ${i} not found in enum`);return new Um({...e,checks:[],...dt.normalizeParams(a),entries:s})},t.exclude=(n,a)=>{let s={...e.entries};for(let i of n)if(r.has(i))delete s[i];else throw new Error(`Key ${i} not found in enum`);return new Um({...e,checks:[],...dt.normalizeParams(a),entries:s})}});function Bt(t,e){let r=Array.isArray(t)?Object.fromEntries(t.map(n=>[n,n])):t;return new Um({type:"enum",entries:r,...dt.normalizeParams(e)})}var FH=ae("ZodLiteral",(t,e)=>{r3.init(t,e),xt.init(t,e),t.values=new Set(e.values),Object.defineProperty(t,"value",{get(){if(e.values.length>1)throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");return e.values[0]}})});function we(t,e){return new FH({type:"literal",values:Array.isArray(t)?t:[t],...dt.normalizeParams(e)})}var UH=ae("ZodTransform",(t,e)=>{a3.init(t,e),xt.init(t,e),t._zod.parse=(r,n)=>{r.addIssue=s=>{if(typeof s=="string")r.issues.push(dt.issue(s,r.value,e));else{let i=s;i.fatal&&(i.continue=!1),i.code??(i.code="custom"),i.input??(i.input=r.value),i.inst??(i.inst=t),i.continue??(i.continue=!0),r.issues.push(dt.issue(i))}};let a=e.transform(r.value,r);return a instanceof Promise?a.then(s=>(r.value=s,r)):(r.value=a,r)}});function Ak(t){return new UH({type:"transform",transform:t})}var Nk=ae("ZodOptional",(t,e)=>{n3.init(t,e),xt.init(t,e),t.unwrap=()=>t._zod.def.innerType});function Se(t){return new Nk({type:"optional",innerType:t})}var zH=ae("ZodNullable",(t,e)=>{s3.init(t,e),xt.init(t,e),t.unwrap=()=>t._zod.def.innerType});function oT(t){return new zH({type:"nullable",innerType:t})}var HH=ae("ZodDefault",(t,e)=>{i3.init(t,e),xt.init(t,e),t.unwrap=()=>t._zod.def.innerType,t.removeDefault=t.unwrap});function BH(t,e){return new HH({type:"default",innerType:t,get defaultValue(){return typeof e=="function"?e():e}})}var VH=ae("ZodPrefault",(t,e)=>{o3.init(t,e),xt.init(t,e),t.unwrap=()=>t._zod.def.innerType});function GH(t,e){return new VH({type:"prefault",innerType:t,get defaultValue(){return typeof e=="function"?e():e}})}var Mk=ae("ZodNonOptional",(t,e)=>{c3.init(t,e),xt.init(t,e),t.unwrap=()=>t._zod.def.innerType});function ZH(t,e){return new Mk({type:"nonoptional",innerType:t,...dt.normalizeParams(e)})}var WH=ae("ZodCatch",(t,e)=>{u3.init(t,e),xt.init(t,e),t.unwrap=()=>t._zod.def.innerType,t.removeCatch=t.unwrap});function KH(t,e){return new WH({type:"catch",innerType:t,catchValue:typeof e=="function"?e:()=>e})}var XH=ae("ZodPipe",(t,e)=>{l3.init(t,e),xt.init(t,e),t.in=e.in,t.out=e.out});function zm(t,e){return new XH({type:"pipe",in:t,out:e})}var JH=ae("ZodReadonly",(t,e)=>{d3.init(t,e),xt.init(t,e)});function YH(t){return new JH({type:"readonly",innerType:t})}var jk=ae("ZodCustom",(t,e)=>{p3.init(t,e),xt.init(t,e)});function QH(t,e){let r=new or({check:"custom",...dt.normalizeParams(e)});return r._zod.check=t,r}function eB(t,e){return iH(jk,t??(()=>!0),e)}function tB(t,e={}){return oH(jk,t,e)}function rB(t,e){let r=QH(n=>(n.addIssue=a=>{if(typeof a=="string")n.issues.push(dt.issue(a,n.value,r._zod.def));else{let s=a;s.fatal&&(s.continue=!1),s.code??(s.code="custom"),s.input??(s.input=n.value),s.inst??(s.inst=r),s.continue??(s.continue=!r._zod.def.abort),n.issues.push(dt.issue(s))}},t(n.value,n)),e);return r}function Dk(t,e){return zm(Ak(t),e)}wa(h3());var rh="io.modelcontextprotocol/related-task",Nl="2.0",ca=eB(t=>t!==null&&(typeof t=="object"||typeof t=="function")),qk=gt([te(),ut().int()]),Lk=te(),aB=Hr({ttl:gt([ut(),$k()]).optional(),pollInterval:ut().optional()}),ah=Hr({taskId:te()}),nB=Hr({progressToken:qk.optional(),[rh]:ah.optional()}),cr=Hr({task:aB.optional(),_meta:nB.optional()}),Ft=le({method:te(),params:cr.optional()}),Bn=Hr({_meta:le({[rh]:Se(ah)}).passthrough().optional()}),Ar=le({method:te(),params:Bn.optional()}),Vt=Hr({_meta:Hr({[rh]:ah.optional()}).optional()}),Ml=gt([te(),ut().int()]),sB=le({jsonrpc:we(Nl),id:Ml,...Ft.shape}).strict();var iB=le({jsonrpc:we(Nl),...Ar.shape}).strict();var oB=le({jsonrpc:we(Nl),id:Ml,result:Vt}).strict();var cT;(function(t){t[t.ConnectionClosed=-32e3]="ConnectionClosed",t[t.RequestTimeout=-32001]="RequestTimeout",t[t.ParseError=-32700]="ParseError",t[t.InvalidRequest=-32600]="InvalidRequest",t[t.MethodNotFound=-32601]="MethodNotFound",t[t.InvalidParams=-32602]="InvalidParams",t[t.InternalError=-32603]="InternalError",t[t.UrlElicitationRequired=-32042]="UrlElicitationRequired"})(cT||(cT={}));var cB=le({jsonrpc:we(Nl),id:Ml,error:le({code:ut().int(),message:te(),data:Se(Nt())})}).strict();var IJ=gt([sB,iB,oB,cB]),Fk=Vt.strict(),uB=Bn.extend({requestId:Ml,reason:te().optional()}),Uk=Ar.extend({method:we("notifications/cancelled"),params:uB}),lB=le({src:te(),mimeType:te().optional(),sizes:Ge(te()).optional()}),Ko=le({icons:Ge(lB).optional()}),hi=le({name:te(),title:te().optional()}),zk=hi.extend({...hi.shape,...Ko.shape,version:te(),websiteUrl:te().optional()}),dB=th(le({applyDefaults:Ht().optional()}),Mt(te(),Nt())),pB=Dk(t=>t&&typeof t=="object"&&!Array.isArray(t)&&Object.keys(t).length===0?{form:{}}:t,th(le({form:dB.optional(),url:ca.optional()}),Mt(te(),Nt()).optional())),fB=le({list:Se(le({}).passthrough()),cancel:Se(le({}).passthrough()),requests:Se(le({sampling:Se(le({createMessage:Se(le({}).passthrough())}).passthrough()),elicitation:Se(le({create:Se(le({}).passthrough())}).passthrough())}).passthrough())}).passthrough(),mB=le({list:Se(le({}).passthrough()),cancel:Se(le({}).passthrough()),requests:Se(le({tools:Se(le({call:Se(le({}).passthrough())}).passthrough())}).passthrough())}).passthrough(),hB=le({experimental:Mt(te(),ca).optional(),sampling:le({context:ca.optional(),tools:ca.optional()}).optional(),elicitation:pB.optional(),roots:le({listChanged:Ht().optional()}).optional(),tasks:Se(fB)}),vB=cr.extend({protocolVersion:te(),capabilities:hB,clientInfo:zk}),gB=Ft.extend({method:we("initialize"),params:vB}),yB=le({experimental:Mt(te(),ca).optional(),logging:ca.optional(),completions:ca.optional(),prompts:Se(le({listChanged:Se(Ht())})),resources:le({subscribe:Ht().optional(),listChanged:Ht().optional()}).optional(),tools:le({listChanged:Ht().optional()}).optional(),tasks:Se(mB)}).passthrough(),_B=Vt.extend({protocolVersion:te(),capabilities:yB,serverInfo:zk,instructions:te().optional()}),bB=Ar.extend({method:we("notifications/initialized")}),Hk=Ft.extend({method:we("ping")}),xB=le({progress:ut(),total:Se(ut()),message:Se(te())}),SB=le({...Bn.shape,...xB.shape,progressToken:qk}),Bk=Ar.extend({method:we("notifications/progress"),params:SB}),wB=cr.extend({cursor:Lk.optional()}),Xo=Ft.extend({params:wB.optional()}),Jo=Vt.extend({nextCursor:Se(Lk)}),Yo=le({taskId:te(),status:Bt(["working","input_required","completed","failed","cancelled"]),ttl:gt([ut(),$k()]),createdAt:te(),lastUpdatedAt:te(),pollInterval:Se(ut()),statusMessage:Se(te())}),Vk=Vt.extend({task:Yo}),EB=Bn.merge(Yo),Gk=Ar.extend({method:we("notifications/tasks/status"),params:EB}),Zk=Ft.extend({method:we("tasks/get"),params:cr.extend({taskId:te()})}),Wk=Vt.merge(Yo),Kk=Ft.extend({method:we("tasks/result"),params:cr.extend({taskId:te()})}),Xk=Xo.extend({method:we("tasks/list")}),Jk=Jo.extend({tasks:Ge(Yo)}),AJ=Ft.extend({method:we("tasks/cancel"),params:cr.extend({taskId:te()})}),NJ=Vt.merge(Yo),Yk=le({uri:te(),mimeType:Se(te()),_meta:Mt(te(),Nt()).optional()}),Qk=Yk.extend({text:te()}),nh=te().refine(t=>{try{return atob(t),!0}catch{return!1}},{message:"Invalid Base64 string"}),eR=Yk.extend({blob:nh}),xi=le({audience:Ge(Bt(["user","assistant"])).optional(),priority:ut().min(0).max(1).optional(),lastModified:gk.datetime({offset:!0}).optional()}),tR=le({...hi.shape,...Ko.shape,uri:te(),description:Se(te()),mimeType:Se(te()),annotations:xi.optional(),_meta:Se(Hr({}))}),TB=le({...hi.shape,...Ko.shape,uriTemplate:te(),description:Se(te()),mimeType:Se(te()),annotations:xi.optional(),_meta:Se(Hr({}))}),kB=Xo.extend({method:we("resources/list")}),RB=Jo.extend({resources:Ge(tR)}),PB=Xo.extend({method:we("resources/templates/list")}),$B=Jo.extend({resourceTemplates:Ge(TB)}),sh=cr.extend({uri:te()}),OB=sh,CB=Ft.extend({method:we("resources/read"),params:OB}),IB=Vt.extend({contents:Ge(gt([Qk,eR]))}),AB=Ar.extend({method:we("notifications/resources/list_changed")}),NB=sh,MB=Ft.extend({method:we("resources/subscribe"),params:NB}),jB=sh,DB=Ft.extend({method:we("resources/unsubscribe"),params:jB}),qB=Bn.extend({uri:te()}),LB=Ar.extend({method:we("notifications/resources/updated"),params:qB}),FB=le({name:te(),description:Se(te()),required:Se(Ht())}),UB=le({...hi.shape,...Ko.shape,description:Se(te()),arguments:Se(Ge(FB)),_meta:Se(Hr({}))}),zB=Xo.extend({method:we("prompts/list")}),HB=Jo.extend({prompts:Ge(UB)}),BB=cr.extend({name:te(),arguments:Mt(te(),te()).optional()}),VB=Ft.extend({method:we("prompts/get"),params:BB}),ih=le({type:we("text"),text:te(),annotations:xi.optional(),_meta:Mt(te(),Nt()).optional()}),oh=le({type:we("image"),data:nh,mimeType:te(),annotations:xi.optional(),_meta:Mt(te(),Nt()).optional()}),ch=le({type:we("audio"),data:nh,mimeType:te(),annotations:xi.optional(),_meta:Mt(te(),Nt()).optional()}),GB=le({type:we("tool_use"),name:te(),id:te(),input:le({}).passthrough(),_meta:Se(le({}).passthrough())}).passthrough(),ZB=le({type:we("resource"),resource:gt([Qk,eR]),annotations:xi.optional(),_meta:Mt(te(),Nt()).optional()}),WB=tR.extend({type:we("resource_link")}),uh=gt([ih,oh,ch,WB,ZB]),KB=le({role:Bt(["user","assistant"]),content:uh}),XB=Vt.extend({description:Se(te()),messages:Ge(KB)}),JB=Ar.extend({method:we("notifications/prompts/list_changed")}),YB=le({title:te().optional(),readOnlyHint:Ht().optional(),destructiveHint:Ht().optional(),idempotentHint:Ht().optional(),openWorldHint:Ht().optional()}),QB=le({taskSupport:Bt(["required","optional","forbidden"]).optional()}),rR=le({...hi.shape,...Ko.shape,description:te().optional(),inputSchema:le({type:we("object"),properties:Mt(te(),ca).optional(),required:Ge(te()).optional()}).catchall(Nt()),outputSchema:le({type:we("object"),properties:Mt(te(),ca).optional(),required:Ge(te()).optional()}).catchall(Nt()).optional(),annotations:Se(YB),execution:Se(QB),_meta:Mt(te(),Nt()).optional()}),e7=Xo.extend({method:we("tools/list")}),t7=Jo.extend({tools:Ge(rR)}),aR=Vt.extend({content:Ge(uh).default([]),structuredContent:Mt(te(),Nt()).optional(),isError:Se(Ht())}),MJ=aR.or(Vt.extend({toolResult:Nt()})),r7=cr.extend({name:te(),arguments:Se(Mt(te(),Nt()))}),a7=Ft.extend({method:we("tools/call"),params:r7}),n7=Ar.extend({method:we("notifications/tools/list_changed")}),nR=Bt(["debug","info","notice","warning","error","critical","alert","emergency"]),s7=cr.extend({level:nR}),i7=Ft.extend({method:we("logging/setLevel"),params:s7}),o7=Bn.extend({level:nR,logger:te().optional(),data:Nt()}),c7=Ar.extend({method:we("notifications/message"),params:o7}),u7=le({name:te().optional()}),l7=le({hints:Se(Ge(u7)),costPriority:Se(ut().min(0).max(1)),speedPriority:Se(ut().min(0).max(1)),intelligencePriority:Se(ut().min(0).max(1))}),d7=le({mode:Se(Bt(["auto","required","none"]))}),p7=le({type:we("tool_result"),toolUseId:te().describe("The unique identifier for the corresponding tool call."),content:Ge(uh).default([]),structuredContent:le({}).passthrough().optional(),isError:Se(Ht()),_meta:Se(le({}).passthrough())}).passthrough(),f7=Ik("type",[ih,oh,ch]),vl=Ik("type",[ih,oh,ch,GB,p7]),m7=le({role:Bt(["user","assistant"]),content:gt([vl,Ge(vl)]),_meta:Se(le({}).passthrough())}).passthrough(),h7=cr.extend({messages:Ge(m7),modelPreferences:l7.optional(),systemPrompt:te().optional(),includeContext:Bt(["none","thisServer","allServers"]).optional(),temperature:ut().optional(),maxTokens:ut().int(),stopSequences:Ge(te()).optional(),metadata:ca.optional(),tools:Se(Ge(rR)),toolChoice:Se(d7)}),v7=Ft.extend({method:we("sampling/createMessage"),params:h7}),g7=Vt.extend({model:te(),stopReason:Se(Bt(["endTurn","stopSequence","maxTokens"]).or(te())),role:Bt(["user","assistant"]),content:f7}),y7=Vt.extend({model:te(),stopReason:Se(Bt(["endTurn","stopSequence","maxTokens","toolUse"]).or(te())),role:Bt(["user","assistant"]),content:gt([vl,Ge(vl)])}),_7=le({type:we("boolean"),title:te().optional(),description:te().optional(),default:Ht().optional()}),b7=le({type:we("string"),title:te().optional(),description:te().optional(),minLength:ut().optional(),maxLength:ut().optional(),format:Bt(["email","uri","date","date-time"]).optional(),default:te().optional()}),x7=le({type:Bt(["number","integer"]),title:te().optional(),description:te().optional(),minimum:ut().optional(),maximum:ut().optional(),default:ut().optional()}),S7=le({type:we("string"),title:te().optional(),description:te().optional(),enum:Ge(te()),default:te().optional()}),w7=le({type:we("string"),title:te().optional(),description:te().optional(),oneOf:Ge(le({const:te(),title:te()})),default:te().optional()}),E7=le({type:we("string"),title:te().optional(),description:te().optional(),enum:Ge(te()),enumNames:Ge(te()).optional(),default:te().optional()}),T7=gt([S7,w7]),k7=le({type:we("array"),title:te().optional(),description:te().optional(),minItems:ut().optional(),maxItems:ut().optional(),items:le({type:we("string"),enum:Ge(te())}),default:Ge(te()).optional()}),R7=le({type:we("array"),title:te().optional(),description:te().optional(),minItems:ut().optional(),maxItems:ut().optional(),items:le({anyOf:Ge(le({const:te(),title:te()}))}),default:Ge(te()).optional()}),P7=gt([k7,R7]),$7=gt([E7,T7,P7]),O7=gt([$7,_7,b7,x7]),C7=cr.extend({mode:we("form").optional(),message:te(),requestedSchema:le({type:we("object"),properties:Mt(te(),O7),required:Ge(te()).optional()})}),I7=cr.extend({mode:we("url"),message:te(),elicitationId:te(),url:te().url()}),A7=gt([C7,I7]),N7=Ft.extend({method:we("elicitation/create"),params:A7}),M7=Bn.extend({elicitationId:te()}),j7=Ar.extend({method:we("notifications/elicitation/complete"),params:M7}),D7=Vt.extend({action:Bt(["accept","decline","cancel"]),content:Dk(t=>t===null?void 0:t,Mt(te(),gt([te(),ut(),Ht(),Ge(te())])).optional())}),q7=le({type:we("ref/resource"),uri:te()}),L7=le({type:we("ref/prompt"),name:te()}),F7=cr.extend({ref:gt([L7,q7]),argument:le({name:te(),value:te()}),context:le({arguments:Mt(te(),te()).optional()}).optional()}),U7=Ft.extend({method:we("completion/complete"),params:F7});var z7=Vt.extend({completion:Hr({values:Ge(te()).max(100),total:Se(ut().int()),hasMore:Se(Ht())})}),H7=le({uri:te().startsWith("file://"),name:te().optional(),_meta:Mt(te(),Nt()).optional()}),B7=Ft.extend({method:we("roots/list")}),V7=Vt.extend({roots:Ge(H7)}),G7=Ar.extend({method:we("notifications/roots/list_changed")}),jJ=gt([Hk,gB,U7,i7,VB,zB,kB,PB,CB,MB,DB,a7,e7,Zk,Kk,Xk]),DJ=gt([Uk,Bk,bB,G7,Gk]),qJ=gt([Fk,g7,y7,D7,V7,Wk,Jk,Vk]),LJ=gt([Hk,v7,N7,B7,Zk,Kk,Xk]),FJ=gt([Uk,Bk,c7,LB,AB,n7,JB,Gk,j7]),UJ=gt([Fk,_B,z7,XB,HB,RB,$B,IB,aR,t7,Wk,Jk,Vk]);var zJ=Symbol("Let zodToJsonSchema decide on which parser to use");var HJ=new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");var BJ=lT(IL(),1),VJ=lT(k6(),1);var GJ=Symbol.for("mcp.completable");var uT;(function(t){t.Completable="McpCompletable"})(uT||(uT={}));function sR({prompt:t,options:e}){let{systemPrompt:r,settingSources:n,sandbox:a,...s}=e??{},i,o;r===void 0?i="":typeof r=="string"?i=r:r.type==="preset"&&(o=r.append);let c=s.pathToClaudeCodeExecutable;if(!c){let Z=(0,wT.fileURLToPath)(Z7.url),ee=(0,wm.join)(Z,"..");c=(0,wm.join)(ee,"cli.js")}process.env.CLAUDE_AGENT_SDK_VERSION="0.1.76";let{abortController:u=TT(),additionalDirectories:l=[],agents:d,allowedTools:f=[],betas:m,canUseTool:g,continue:_,cwd:p,disallowedTools:h=[],tools:y,env:v,executable:b=UT()?"bun":"node",executableArgs:w=[],extraArgs:x={},fallbackModel:E,enableFileCheckpointing:T,forkSession:R,hooks:M,includePartialMessages:j,persistSession:L,maxThinkingTokens:H,maxTurns:N,maxBudgetUsd:W,mcpServers:oe,model:he,outputFormat:ne,permissionMode:re="default",allowDangerouslySkipPermissions:U=!1,permissionPromptToolName:P,plugins:z,resume:I,resumeSessionAt:S,stderr:k,strictMcpConfig:D}=s,K=ne?.type==="json_schema"?ne.schema:void 0,J=v;if(J||(J={...process.env}),J.CLAUDE_CODE_ENTRYPOINT||(J.CLAUDE_CODE_ENTRYPOINT="sdk-ts"),T&&(J.CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING="true"),!c)throw new Error("pathToClaudeCodeExecutable is required");let de={},se=new Map;if(oe)for(let[Z,ee]of Object.entries(oe))ee.type==="sdk"&&"instance"in ee?(se.set(Z,ee.instance),de[Z]={type:"sdk",name:Z}):de[Z]=ee;let me=typeof t=="string",O=new Tm({abortController:u,additionalDirectories:l,betas:m,cwd:p,executable:b,executableArgs:w,extraArgs:x,pathToClaudeCodeExecutable:c,env:J,forkSession:R,stderr:k,maxThinkingTokens:H,maxTurns:N,maxBudgetUsd:W,model:he,fallbackModel:E,jsonSchema:K,permissionMode:re,allowDangerouslySkipPermissions:U,permissionPromptToolName:P,continueConversation:_,resume:I,resumeSessionAt:S,settingSources:n??[],allowedTools:f,disallowedTools:h,tools:y,mcpServers:de,strictMcpConfig:D,canUseTool:!!g,hooks:!!M,includePartialMessages:j,persistSession:L,plugins:z,sandbox:a,spawnClaudeCodeProcess:s.spawnClaudeCodeProcess}),C={systemPrompt:i,appendSystemPrompt:o,agents:d},F=new Pm(O,me,g,M,u,se,K,C);return typeof t=="string"?O.write(JSON.stringify({type:"user",session_id:"",message:{role:"user",content:[{type:"text",text:t}]},parent_tool_use_id:null})+` -`):F.streamInput(t),F}var jl=class{dbManager;sessionManager;constructor(e,r){this.dbManager=e,this.sessionManager=r}async startSession(e,r){try{let n=this.findClaudeExecutable(),a=this.getModelId(),s=["Bash","Read","Write","Edit","Grep","Glob","WebFetch","WebSearch","Task","NotebookEdit","AskUserQuestion","TodoWrite"],i=this.createMessageGenerator(e),o=sR({prompt:i,options:{model:a,disallowedTools:s,abortController:e.abortController,pathToClaudeCodeExecutable:n}});for await(let u of o){if(u.type==="assistant"){let l=u.message.content,d=Array.isArray(l)?l.filter(h=>h.type==="text").map(h=>h.text).join(` +`):F.streamInput(t),F}var jl=class{dbManager;sessionManager;constructor(e,r){this.dbManager=e,this.sessionManager=r}async startSession(e,r){try{let n=this.findClaudeExecutable(),a=this.getModelId(),s=["Bash","Read","Write","Edit","Grep","Glob","WebFetch","WebSearch","Task","NotebookEdit","AskUserQuestion","TodoWrite"],i=this.createMessageGenerator(e),o=sR({prompt:i,options:{model:a,resume:e.claudeSessionId,disallowedTools:s,abortController:e.abortController,pathToClaudeCodeExecutable:n}});for await(let u of o){if(u.type==="assistant"){let l=u.message.content,d=Array.isArray(l)?l.filter(h=>h.type==="text").map(h=>h.text).join(` `):typeof l=="string"?l:"",f=d.length,m=e.cumulativeInputTokens+e.cumulativeOutputTokens,g=u.message.usage;g&&(e.cumulativeInputTokens+=g.input_tokens||0,e.cumulativeOutputTokens+=g.output_tokens||0,g.cache_creation_input_tokens&&(e.cumulativeInputTokens+=g.cache_creation_input_tokens),A.debug("SDK","Token usage captured",{sessionId:e.sessionDbId,inputTokens:g.input_tokens,outputTokens:g.output_tokens,cacheCreation:g.cache_creation_input_tokens||0,cacheRead:g.cache_read_input_tokens||0,cumulativeInput:e.cumulativeInputTokens,cumulativeOutput:e.cumulativeOutputTokens}));let _=e.cumulativeInputTokens+e.cumulativeOutputTokens-m,p=e.earliestPendingTimestamp;if(f>0){let h=f>100?d.substring(0,100)+"...":d;A.dataOut("SDK",`Response received (${f} chars)`,{sessionId:e.sessionDbId,promptNumber:e.lastPromptNumber},h),await this.processSDKResponse(e,d,r,_,p)}else await this.markMessagesProcessed(e,r)}u.type==="result"&&u.subtype}let c=Date.now()-e.startTime;A.success("SDK","Agent completed",{sessionId:e.sessionDbId,duration:`${(c/1e3).toFixed(1)}s`})}catch(n){throw n.name==="AbortError"?A.warn("SDK","Agent aborted",{sessionId:e.sessionDbId}):A.failure("SDK","Agent error",{sessionDbId:e.sessionDbId},n),n}finally{this.sessionManager.deleteSession(e.sessionDbId).catch(()=>{})}}async*createMessageGenerator(e){let r=ct.getInstance().getActiveMode(),n=e.lastPromptNumber===1?Ks(e.project,e.claudeSessionId,e.userPrompt,r):Ys(e.userPrompt,e.lastPromptNumber,e.claudeSessionId,r);e.conversationHistory.push({role:"user",content:n}),yield{type:"user",message:{role:"user",content:n},session_id:e.claudeSessionId,parent_tool_use_id:null,isSynthetic:!0};for await(let a of this.sessionManager.getMessageIterator(e.sessionDbId))if(a.type==="observation"){a.prompt_number!==void 0&&(e.lastPromptNumber=a.prompt_number);let s=Xs({id:0,tool_name:a.tool_name,tool_input:JSON.stringify(a.tool_input),tool_output:JSON.stringify(a.tool_response),created_at_epoch:Date.now(),cwd:a.cwd});e.conversationHistory.push({role:"user",content:s}),yield{type:"user",message:{role:"user",content:s},session_id:e.claudeSessionId,parent_tool_use_id:null,isSynthetic:!0}}else if(a.type==="summarize"){let s=Js({id:e.sessionDbId,sdk_session_id:e.sdkSessionId,project:e.project,user_prompt:e.userPrompt,last_user_message:a.last_user_message||"",last_assistant_message:a.last_assistant_message||""},r);e.conversationHistory.push({role:"user",content:s}),yield{type:"user",message:{role:"user",content:s},session_id:e.claudeSessionId,parent_tool_use_id:null,isSynthetic:!0}}}async processSDKResponse(e,r,n,a,s){r&&e.conversationHistory.push({role:"assistant",content:r});let i=Zs(r,e.claudeSessionId);for(let c of i){let{id:u,createdAtEpoch:l}=this.dbManager.getSessionStore().storeObservation(e.claudeSessionId,e.project,c,e.lastPromptNumber,a,s??void 0);A.info("SDK","Observation saved",{sessionId:e.sessionDbId,obsId:u,type:c.type,title:c.title||"(untitled)",filesRead:c.files_read?.length??0,filesModified:c.files_modified?.length??0,concepts:c.concepts?.length??0});let d=Date.now(),f=c.type,m=c.title||"(untitled)";this.dbManager.getChromaSync().syncObservation(u,e.claudeSessionId,e.project,c,e.lastPromptNumber,l,a).then(()=>{let g=Date.now()-d;A.debug("CHROMA","Observation synced",{obsId:u,duration:`${g}ms`,type:f,title:m})}).catch(g=>{A.warn("CHROMA","Observation sync failed, continuing without vector search",{obsId:u,type:f,title:m},g)}),n&&n.sseBroadcaster&&n.sseBroadcaster.broadcast({type:"new_observation",observation:{id:u,sdk_session_id:e.sdkSessionId,session_id:e.claudeSessionId,type:c.type,title:c.title,subtitle:c.subtitle,text:c.text||null,narrative:c.narrative||null,facts:JSON.stringify(c.facts||[]),concepts:JSON.stringify(c.concepts||[]),files_read:JSON.stringify(c.files||[]),files_modified:JSON.stringify([]),project:e.project,prompt_number:e.lastPromptNumber,created_at_epoch:l}})}let o=Ws(r,e.sessionDbId);if(o){let{id:c,createdAtEpoch:u}=this.dbManager.getSessionStore().storeSummary(e.claudeSessionId,e.project,o,e.lastPromptNumber,a,s??void 0);A.info("SDK","Summary saved",{sessionId:e.sessionDbId,summaryId:c,request:o.request||"(no request)",hasCompleted:!!o.completed,hasNextSteps:!!o.next_steps});let l=Date.now(),d=o.request||"(no request)";this.dbManager.getChromaSync().syncSummary(c,e.claudeSessionId,e.project,o,e.lastPromptNumber,u,a).then(()=>{let f=Date.now()-l;A.debug("CHROMA","Summary synced",{summaryId:c,duration:`${f}ms`,request:d})}).catch(f=>{A.warn("CHROMA","Summary sync failed, continuing without vector search",{summaryId:c,request:d},f)}),n&&n.sseBroadcaster&&n.sseBroadcaster.broadcast({type:"new_summary",summary:{id:c,session_id:e.claudeSessionId,request:o.request,investigated:o.investigated,learned:o.learned,completed:o.completed,next_steps:o.next_steps,notes:o.notes,project:e.project,prompt_number:e.lastPromptNumber,created_at_epoch:u}})}await this.markMessagesProcessed(e,n)}async markMessagesProcessed(e,r){let n=this.sessionManager.getPendingMessageStore();if(e.pendingProcessingIds.size>0){for(let s of e.pendingProcessingIds)n.markProcessed(s);A.debug("SDK","Messages marked as processed",{sessionId:e.sessionDbId,messageIds:Array.from(e.pendingProcessingIds),count:e.pendingProcessingIds.size}),e.pendingProcessingIds.clear(),e.earliestPendingTimestamp=null;let a=n.cleanupProcessed(100);a>0&&A.debug("SDK","Cleaned up old processed messages",{deletedCount:a})}r&&typeof r.broadcastProcessingStatus=="function"&&r.broadcastProcessingStatus()}findClaudeExecutable(){let e=We.loadFromFile(Or);if(e.CLAUDE_CODE_PATH){let{existsSync:r}=require("fs");if(!r(e.CLAUDE_CODE_PATH))throw new Error(`CLAUDE_CODE_PATH is set to "${e.CLAUDE_CODE_PATH}" but the file does not exist.`);return e.CLAUDE_CODE_PATH}try{let r=(0,iR.execSync)(process.platform==="win32"?"where claude":"which claude",{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]}).trim().split(` `)[0].trim();if(r)return r}catch(r){A.debug("SDK","Claude executable auto-detection failed",r)}throw new Error(`Claude executable not found. Please either: 1. Add "claude" to your system PATH, or diff --git a/plugin/skills/mem-search.zip b/plugin/skills/mem-search.zip index 9ee245ce..125f54e0 100644 Binary files a/plugin/skills/mem-search.zip and b/plugin/skills/mem-search.zip differ diff --git a/src/services/worker/SDKAgent.ts b/src/services/worker/SDKAgent.ts index 689b347a..6a903828 100644 --- a/src/services/worker/SDKAgent.ts +++ b/src/services/worker/SDKAgent.ts @@ -69,6 +69,7 @@ export class SDKAgent { prompt: messageGenerator, options: { model: modelId, + resume: session.claudeSessionId, disallowedTools, abortController: session.abortController, pathToClaudeCodeExecutable: claudePath