diff --git a/.agents/mcp-ask-user-debug-session.md b/.agents/mcp-ask-user-debug-session.md new file mode 100644 index 00000000..95c2f07f --- /dev/null +++ b/.agents/mcp-ask-user-debug-session.md @@ -0,0 +1,494 @@ +# MCP ask_user Tool Debug Session +**Date**: 2026-01-19 +**Status**: READY FOR INVESTIGATION +**Priority**: HIGH (Intermittent timeouts causing subagent failures) + +## 🐛 BUG SUMMARY + +### Primary Issues +1. **Intermittent Timeouts**: `ask_user` tool from subagents sometimes succeeds, sometimes times out +2. **Counter Accumulation**: Question counter increments but doesn't clear after question is answered +3. **Duplicate Event Handling**: Each question is received 3x by the MCP bridge + +### Impact +- Subagents fail when ask_user times out +- User confusion from increasing counter that never resets +- Race conditions from duplicate question handling + +--- + +## 📊 EVIDENCE & SYMPTOMS + +### Console Log Pattern (2026-01-19) +``` +instance-shell2.tsx:202 [Instance Shell] onMount fired for instance: mkkd2vy8 +mcp-bridge.ts:24 [MCP Bridge UI] Initializing MCP bridge for instance: mkkd2vy8 + +↓ **REPEATED 3 TIMES** ↓ + +instance-shell2.tsx:202 [Instance Shell] onMount fired for instance: mkkd2vy8 +mcp-bridge.ts:24 [MCP Bridge UI] Initializing MCP bridge for instance: mkkd2vy8 + +instance-shell2.tsx:202 [Instance Shell] onMount fired for instance: mkkd2vy8 +mcp-bridge.ts:24 [MCP Bridge UI] Initializing MCP bridge for instance: mkkd2vy8 +``` + +### Question Handling Pattern +``` +mcp-bridge.ts:76 [MCP Bridge UI] Received question: {requestId: 'req_1768779214029_atnlu1qq6', questions: Array(1), ...} +mcp-bridge.ts:76 [MCP Bridge UI] Received question: {requestId: 'req_1768779214029_atnlu1qq6', questions: Array(1), ...} +mcp-bridge.ts:76 [MCP Bridge UI] Received question: {requestId: 'req_1768779214029_atnlu1qq6', questions: Array(1), ...} + +askquestion-wizard.tsx:83 [Question Wizard] Opening wizard for question: req_1768779214029_atnlu1qq6 +askquestion-wizard.tsx:88 [Question Wizard] Wizard opened successfully + +mcp-bridge.ts:76 [MCP Bridge UI] Received question: {requestId: 'req_1768779214029_atnlu1qq6', questions: Array(1), ...} +askquestion-wizard.tsx:83 [Question Wizard] Opening wizard for question: req_1768779214029_atnlu1qq6 +askquestion-wizard.tsx:88 [Question Wizard] Wizard opened successfully +``` +↳ **Same requestId received and processed 3 times** + +### Successful Operations (When They Work) +``` +mcp-bridge.ts:112 [MCP Bridge UI] Sending answer for req_1768779214029_atnlu1qq6 +mcp-bridge.ts:117 [MCP Bridge UI] Answer sent successfully + +mcp-bridge.ts:130 [MCP Bridge UI] Sending cancel for req_1768779214029_atnlu1qq6: user_cancelled +mcp-bridge.ts:135 [MCP Bridge UI] Cancel sent successfully +``` +↳ **IPC communication works when triggered** + +### Counter Behavior +``` +// Counter increments when questions arrive (3x per question) +// Counter DOES NOT decrement when: +// - Answer is sent successfully +// - Question is cancelled +// Result: Counter shows accumulated count instead of pending count +``` + +--- + +## 🔍 ROOT CAUSE HYPOTHESIS + +### Primary Suspect: Multiple Component Initialization +**File**: `packages/ui/src/components/instance-shell2.tsx` + +**Issue**: `onMount` lifecycle hook fires **3 times** for the same instance +- Each onMount calls `initializeMCPBridge()` +- Each initialization registers IPC event listeners +- Result: **3 listeners registered for same event channel** + +**Why this happens**: +1. Solid.js reactive system may be re-running the component +2. Missing or incorrect `onCleanup` to remove old listeners +3. Component mounting/unmounting/remounting pattern +4. StrictMode or dev-mode double-rendering (unlikely in Electron) + +### Secondary Suspect: IPC Event Handler Accumulation +**File**: `packages/ui/src/lib/mcp-bridge.ts` + +**Issue**: Event listeners not properly cleaned up +```typescript +// Current pattern (suspected): +window.electron.ipcRenderer.on('mcp:askQuestion', (event, data) => { + // Handler registered 3x, fires 3x per event +}); + +// Missing cleanup: +onCleanup(() => { + window.electron.ipcRenderer.removeListener('mcp:askQuestion', handler); +}); +``` + +### Tertiary Suspect: Question Store Counter Logic +**File**: `packages/ui/src/stores/questions.ts` + +**Issue**: Counter increment/decrement mismatch +- `addPendingQuestion()` increments counter +- `removePendingQuestion()` should decrement counter +- Possible issues: + - removePendingQuestion not called after answer/cancel + - Called with wrong requestId (doesn't match) + - Race condition from 3x duplicate questions + +--- + +## 🎯 INVESTIGATION PLAN + +### Phase 1: Identify Initialization Redundancy +```markdown +- [ ] Read instance-shell2.tsx onMount implementation +- [ ] Check if onCleanup exists for MCP bridge +- [ ] Verify MCP bridge initialization is idempotent +- [ ] Add guards to prevent multiple initializations +- [ ] Check parent component re-render patterns +``` + +### Phase 2: Audit IPC Event Listeners +```markdown +- [ ] Read mcp-bridge.ts initializeMCPBridge function +- [ ] Identify all ipcRenderer.on() registrations +- [ ] Check if removeListener is called anywhere +- [ ] Verify listener references stored for cleanup +- [ ] Add listener deduplication logic +``` + +### Phase 3: Trace Question Lifecycle +```markdown +- [ ] Read questions.ts store implementation +- [ ] Trace addPendingQuestion call sites +- [ ] Trace removePendingQuestion call sites +- [ ] Verify counter increment/decrement logic +- [ ] Check if duplicate requestIds handled +``` + +### Phase 4: Fix Implementation +```markdown +- [ ] Add initialization guard in instance-shell2 +- [ ] Implement proper onCleanup for IPC listeners +- [ ] Add requestId deduplication in question handler +- [ ] Ensure removePendingQuestion called after answer/cancel +- [ ] Add defensive checks for duplicate questions +``` + +### Phase 5: Validation +```markdown +- [ ] Test: Single question should log "Received question" once +- [ ] Test: Counter should increment by 1 per question +- [ ] Test: Counter should decrement to 0 after answer +- [ ] Test: Multiple subagents shouldn't cause accumulation +- [ ] Test: No timeout errors for 10+ consecutive ask_user calls +``` + +--- + +## 📂 KEY FILES TO INVESTIGATE + +### 1. Instance Shell (Component Lifecycle) +**Path**: `packages/ui/src/components/instance-shell2.tsx` +**Lines of Interest**: +- onMount implementation (~line 202) +- MCP bridge initialization call +- onCleanup implementation (if exists) + +**Questions**: +- Why does onMount fire 3 times? +- Is there an onCleanup to remove event listeners? +- Are there multiple instances of the same component? + +### 2. MCP Bridge (IPC Communication) +**Path**: `packages/ui/src/lib/mcp-bridge.ts` +**Lines of Interest**: +- `initializeMCPBridge()` function (~line 24) +- `ipcRenderer.on('mcp:askQuestion')` handler (~line 76) +- `sendAnswer()` function (~line 112) +- `sendCancel()` function (~line 130) + +**Questions**: +- Are listeners properly removed on cleanup? +- Is there guard against multiple initializations? +- How is requestId validated? + +### 3. Question Store (State Management) +**Path**: `packages/ui/src/stores/questions.ts` +**Lines of Interest**: +- `addPendingQuestion()` implementation +- `removePendingQuestion()` implementation +- Counter increment/decrement logic +- Duplicate requestId handling + +**Questions**: +- Is removePendingQuestion called after answer? +- Does counter logic match question lifecycle? +- Are duplicate requestIds filtered? + +### 4. Question Wizard (UI Component) +**Path**: `packages/ui/src/components/askquestion-wizard.tsx` +**Lines of Interest**: +- `handleSubmit()` implementation (~line 83) +- `handleCancel()` implementation +- Calls to removePendingQuestion +- Dialog open/close lifecycle + +**Questions**: +- Does wizard call removePendingQuestion on submit? +- Does wizard call removePendingQuestion on cancel? +- Can multiple wizards open for same requestId? + +--- + +## 🔧 EXPECTED FIX PATTERN + +### Fix 1: Prevent Multiple Initializations +```typescript +// instance-shell2.tsx +let mcpBridgeInitialized = false; + +onMount(() => { + if (!mcpBridgeInitialized) { + initializeMCPBridge(props.instanceId); + mcpBridgeInitialized = true; + } + + onCleanup(() => { + cleanupMCPBridge(props.instanceId); + mcpBridgeInitialized = false; + }); +}); +``` + +### Fix 2: IPC Listener Cleanup +```typescript +// mcp-bridge.ts +const listeners = new Map(); + +export function initializeMCPBridge(instanceId: string) { + // Remove old listener if exists + const oldHandler = listeners.get(`askQuestion-${instanceId}`); + if (oldHandler) { + window.electron.ipcRenderer.removeListener('mcp:askQuestion', oldHandler); + } + + // Register new listener + const handler = (event, data) => { + // Deduplicate by requestId + if (isQuestionAlreadyHandled(data.requestId)) return; + // ... rest of handler + }; + + window.electron.ipcRenderer.on('mcp:askQuestion', handler); + listeners.set(`askQuestion-${instanceId}`, handler); +} + +export function cleanupMCPBridge(instanceId: string) { + const handler = listeners.get(`askQuestion-${instanceId}`); + if (handler) { + window.electron.ipcRenderer.removeListener('mcp:askQuestion', handler); + listeners.delete(`askQuestion-${instanceId}`); + } +} +``` + +### Fix 3: Question Store Counter Fix +```typescript +// questions.ts +export function removePendingQuestion(requestId: string) { + const question = pendingQuestions[requestId]; + if (!question) { + console.warn('[Questions Store] Attempted to remove non-existent question:', requestId); + return; + } + + delete pendingQuestions[requestId]; + setPendingQuestionCount(prev => Math.max(0, prev - 1)); // Never go negative + console.log('[Questions Store] Removed question, new count:', getPendingQuestionCount()); +} +``` + +### Fix 4: Wizard Cleanup Integration +```typescript +// askquestion-wizard.tsx +const handleSubmit = async () => { + try { + await sendAnswer(requestId, selectedValue); + removePendingQuestion(requestId); // ENSURE THIS IS CALLED + setIsOpen(false); + } catch (error) { + console.error('[Question Wizard] Submit failed:', error); + } +}; + +const handleCancel = async () => { + try { + await sendCancel(requestId); + removePendingQuestion(requestId); // ENSURE THIS IS CALLED + setIsOpen(false); + } catch (error) { + console.error('[Question Wizard] Cancel failed:', error); + } +}; +``` + +--- + +## ⚠️ DEBUGGING TIPS + +### Enable Verbose Logging +Add these logs to trace execution: +```typescript +// instance-shell2.tsx +console.log('[Instance Shell] MOUNT START:', props.instanceId, 'Count:', ++mountCounter); +console.log('[Instance Shell] CLEANUP:', props.instanceId, 'Count:', --mountCounter); + +// mcp-bridge.ts +console.log('[MCP Bridge] INIT START:', instanceId, 'Active listeners:', listeners.size); +console.log('[MCP Bridge] QUESTION RECEIVED:', requestId, 'Already handled:', isAlreadyHandled); +console.log('[MCP Bridge] ANSWER SENT:', requestId, 'Cleaning up...'); + +// questions.ts +console.log('[Questions Store] ADD:', requestId, 'New count:', count); +console.log('[Questions Store] REMOVE:', requestId, 'New count:', count); +``` + +### Test Scenario +1. Start app, open single instance +2. Run subagent with single ask_user call +3. Verify logs show: + - "MOUNT START" **once** + - "INIT START" **once** + - "QUESTION RECEIVED" **once** + - "ADD" **once** with count=1 + - Answer question + - "ANSWER SENT" **once** + - "REMOVE" **once** with count=0 + +### Success Criteria +✅ Each question received exactly once +✅ Counter increments by 1 per question +✅ Counter decrements by 1 per answer/cancel +✅ Counter reaches 0 after all questions answered +✅ No timeouts for 20+ consecutive ask_user calls +✅ Works with multiple concurrent subagents + +--- + +## 📝 EXPECTED OUTCOMES + +### After Fix Applied +1. **Single Event Handling**: Each question logged once in console +2. **Accurate Counter**: Matches actual pending questions +3. **No Timeouts**: ask_user tool reliable in subagents +4. **Clean Lifecycle**: Proper cleanup on instance close +5. **Scalability**: Works with 10+ concurrent subagents + +### Testing Checklist +```markdown +- [ ] Single instance, single question → counter 1 → answer → counter 0 +- [ ] Single instance, 5 questions → counter 5 → answer all → counter 0 +- [ ] Multiple instances, each with questions → independent counters +- [ ] Close instance with pending questions → counter clears +- [ ] Rapid fire 10 subagents with ask_user → no timeouts +- [ ] Cancel questions → counter decrements properly +``` + +--- + +## 🚀 NEXT SESSION COMMANDS + +### Start Investigation +```bash +# Read key files +cat packages/ui/src/components/instance-shell2.tsx +cat packages/ui/src/lib/mcp-bridge.ts +cat packages/ui/src/stores/questions.ts +cat packages/ui/src/components/askquestion-wizard.tsx + +# Search for specific patterns +grep -n "onMount" packages/ui/src/components/instance-shell2.tsx +grep -n "onCleanup" packages/ui/src/components/instance-shell2.tsx +grep -n "ipcRenderer.on" packages/ui/src/lib/mcp-bridge.ts +grep -n "removeListener" packages/ui/src/lib/mcp-bridge.ts +grep -n "removePendingQuestion" packages/ui/src/components/askquestion-wizard.tsx +``` + +### After Fix Implementation +```bash +# Test the fix +npm run dev + +# In app: Run test subagent with ask_user calls +# Monitor console for: +# 1. Single "Received question" per question +# 2. Counter incrementing correctly +# 3. Counter decrementing after answer +# 4. No duplicate logs +``` + +--- + +## 🔗 RELATED CONTEXT + +### Fork-Specific Feature +This `ask_user` MCP tool is a **custom CodeNomad fork feature**, not present in upstream. It uses: +- Custom IPC channel: `mcp:askQuestion`, `mcp:answerQuestion`, `mcp:cancelQuestion` +- Custom UI: `askquestion-wizard.tsx` modal component +- Custom state: `questions.ts` store with counter +- Integration: `instance-shell2.tsx` initializes on mount + +### Architecture +``` +SubAgent (MCP Server) + ↓ IPC: mcp:askQuestion +Electron Main Process + ↓ Forward to Renderer +MCP Bridge (mcp-bridge.ts) + ↓ IPC handler: on('mcp:askQuestion') +Questions Store (questions.ts) + ↓ addPendingQuestion() +AskQuestion Wizard (askquestion-wizard.tsx) + ↓ User answers + ↓ sendAnswer() via MCP Bridge + ↓ removePendingQuestion() +Electron Main Process + ↓ IPC: mcp:answerQuestion +SubAgent (MCP Server) + ↓ Continues execution +``` + +### Known Good State +- **Before Bug**: Single initialization, single question handling +- **Current State**: 3x initialization, 3x question handling, counter accumulation +- **Likely Cause**: Recent refactor or upstream merge introduced lifecycle issues + +--- + +## 📚 REFERENCE LOGS + +### Full Console Sequence (2026-01-19 14:40:14) +``` +instance-shell2.tsx:202 [Instance Shell] onMount fired for instance: mkkd2vy8 +mcp-bridge.ts:24 [MCP Bridge UI] Initializing MCP bridge for instance: mkkd2vy8 +instance-shell2.tsx:202 [Instance Shell] onMount fired for instance: mkkd2vy8 +mcp-bridge.ts:24 [MCP Bridge UI] Initializing MCP bridge for instance: mkkd2vy8 +instance-shell2.tsx:202 [Instance Shell] onMount fired for instance: mkkd2vy8 +mcp-bridge.ts:24 [MCP Bridge UI] Initializing MCP bridge for instance: mkkd2vy8 + +mcp-bridge.ts:76 [MCP Bridge UI] Received question: {requestId: 'req_1768779214029_atnlu1qq6', questions: Array(1), instanceId: 'mkkd2vy8', ...} +askquestion-wizard.tsx:83 [Question Wizard] Opening wizard for question: req_1768779214029_atnlu1qq6 +askquestion-wizard.tsx:88 [Question Wizard] Wizard opened successfully + +mcp-bridge.ts:76 [MCP Bridge UI] Received question: {requestId: 'req_1768779214029_atnlu1qq6', ...} +askquestion-wizard.tsx:83 [Question Wizard] Opening wizard for question: req_1768779214029_atnlu1qq6 +askquestion-wizard.tsx:88 [Question Wizard] Wizard opened successfully + +mcp-bridge.ts:76 [MCP Bridge UI] Received question: {requestId: 'req_1768779214029_atnlu1qq6', ...} +askquestion-wizard.tsx:83 [Question Wizard] Opening wizard for question: req_1768779214029_atnlu1qq6 +askquestion-wizard.tsx:88 [Question Wizard] Wizard opened successfully + +mcp-bridge.ts:112 [MCP Bridge UI] Sending answer for req_1768779214029_atnlu1qq6 +mcp-bridge.ts:117 [MCP Bridge UI] Answer sent successfully + +[Multiple similar patterns for subsequent questions: req_1768781344166_vwjapj2zf, req_1768781372754_qvshpxniq, req_1768781431451_lrgtyzqo3] + +mcp-bridge.ts:130 [MCP Bridge UI] Sending cancel for req_1768781431451_lrgtyzqo3: user_cancelled +mcp-bridge.ts:135 [MCP Bridge UI] Cancel sent successfully +``` + +--- + +## ✅ SUCCESS METRICS + +After successful debug session: +1. **Console Clean**: Each question appears **once** in logs +2. **Counter Accurate**: Reflects actual pending questions (not accumulated) +3. **No Timeouts**: 20+ consecutive ask_user calls succeed +4. **User Confidence**: Trust restored in ask_user tool for subagents + +--- + +**Debug Mode Recommendation**: Use "Claudette Debug v4" or "systematic-debugging" skill for structured investigation approach. + +**Estimated Complexity**: MEDIUM (lifecycle management + IPC cleanup) +**Estimated Time**: 45-90 minutes (investigation + fix + testing) +**Risk Level**: LOW (isolated to fork feature, no upstream conflicts) diff --git a/.agents/upstream-merge-memory.md b/.agents/upstream-merge-memory.md new file mode 100644 index 00000000..4323f9f9 --- /dev/null +++ b/.agents/upstream-merge-memory.md @@ -0,0 +1,444 @@ +--- +applyTo: '**' +--- + +# Fork Metadata +- Original Repo: https://github.com/NeuralNomadsAI/CodeNomad.git +- Fork Repo: https://github.com/bizzkoot/CodeNomad +- Analysis Date: 2026-01-27 +- Current Branch: dev +- Base Branch: dev +- Analysis From: origin/mirror + +# Divergence Summary +- Commits Behind Upstream: 30 commits +- Commits Ahead of Upstream: 30 commits +- Fork Custom Modifications: 92 files changed, 28,111 insertions(+), 4,582 deletions(-) + +# Custom Modifications Registry + +## Major Features Added in Fork +1. **ask_user MCP Tool** - Complete MCP server implementation with native ask_user functionality +2. **Chat Search Functionality** - Full-text search with highlighting and navigation +3. **Question Panel** - Multi-line support, markdown rendering, minimize functionality +4. **Source Control Panel** - Git integration with publish branch, delete untracked files +5. **Markdown Preview** - Modal preview for markdown files with icon support +6. **Auto-collapse Chat Input** - Automatic collapse on message send + +## Modified Files (Fork-Specific) +### MCP Server Package (NEW) +- packages/mcp-server/* (entire package is custom) + +### UI Components (Heavy Modifications) +- packages/ui/src/components/askquestion-wizard.tsx +- packages/ui/src/components/search-panel.tsx +- packages/ui/src/components/search-highlighted-text.tsx +- packages/ui/src/components/markdown-preview-modal.tsx +- packages/ui/src/components/markdown-preview-icon.tsx +- packages/ui/src/components/folder-tree-browser.tsx +- packages/ui/src/components/folder-tree-node.tsx +- packages/ui/src/components/source-control/source-control-panel.tsx +- packages/ui/src/components/question-notification-banner.tsx + +### Stores (Custom Logic) +- packages/ui/src/stores/questions.ts +- packages/ui/src/stores/search-store.ts +- packages/ui/src/stores/git.ts + +### Libraries (Custom Features) +- packages/ui/src/lib/mcp-bridge.ts +- packages/ui/src/lib/search-algorithm.ts +- packages/ui/src/lib/search-highlight.ts +- packages/ui/src/lib/section-expansion.ts +- packages/ui/src/lib/markdown-file-detector.ts +- packages/ui/src/lib/file-path-validator.ts + +### Server Routes (Custom) +- packages/server/src/server/routes/git.ts + +### Documentation +- dev-docs/askquestion-integration.md +- tasks/todo/ask-user-feature/* + +## Files Modified in Both Fork and Upstream (CONFLICT ZONES) +1. **packages/ui/src/components/prompt-input.tsx** - Both modified heavily +2. **packages/ui/src/components/expand-button.tsx** - Both modified +3. **packages/ui/src/components/message-block.tsx** - Both modified +4. **packages/ui/src/components/tool-call.tsx** - Both modified +5. **packages/ui/src/lib/sse-manager.ts** - Both modified +6. **packages/ui/src/stores/instances.ts** - Both modified +7. **packages/electron-app/electron/main/main.ts** - Both modified (auth vs custom) +8. **packages/electron-app/electron/main/process-manager.ts** - Both modified + +# Merge History +## 2026-02-15 - PARTIAL UPSTREAM DEV MERGE v0.10.3 - Infrastructure Only +- **Strategy**: Infrastructure merge with UI component reverts +- **Source**: `upstream/dev` (v0.10.3 line) +- **Last Merge**: `444335ad99276922831ba7308de2c7f3b2fcb1e2` +- **Status**: Partial Success - Server/API merged, UI components reverted + +### What Was Attempted +Full merge of upstream v0.10.3 including: +- Monaco-powered diff viewer in SourceControlPanel +- Worktree file browser section +- Session changes section with reactive data +- Source Control panel reorganization + +### What Failed +**UI components caused "Starting instance..." hangs** during instance creation. + +**Root Cause**: Upstream's reactive patterns incompatible with fork initialization: +- `createEffect` hooks tracking `instances()` store +- Monaco editor loading during component mount +- Worktree client initialization on render +- Reactive dependencies on instance/sessions stores + +### Resolution Applied +**Reverted**: `packages/ui/src/components/source-control/source-control-panel.tsx` +- Restored to original fork version (914 lines, text-based diff) +- Removed all reactive store dependencies +- Verified "Starting instance..." completes successfully + +### Successfully Merged (Infrastructure) +- ✅ **Server API**: `GET /api/workspaces/:id/git/file-original` endpoint +- ✅ **API Client**: `fetchGitOriginalContent()` method +- ✅ **Git Store**: Optional chaining safety fix +- ✅ **Platform**: Power save blocker, dev startup fixes +- ✅ **UI Safety**: Permission/Question null checks + +### Files Modified +``` +packages/server/src/server/routes/git.ts (+50 lines) - New endpoint +packages/ui/src/lib/api-client.ts (+9 lines) - New API method +packages/ui/src/stores/git.ts (+1 line) - Safety fix +packages/ui/src/components/tool-call/ + permission-block.tsx (+1 line) - Null check + question-block.tsx (+1 line) - Null check +``` + +### Files Reverted +``` +packages/ui/src/components/source-control/source-control-panel.tsx + → Restored to fork version (works reliably) +``` + +### Validation After Reverts +- ✅ `npm run lint` — no errors +- ✅ `npm run typecheck` — all packages pass +- ✅ `npm run dev` — No "Starting instance..." hang +- ✅ Instance creation — Works reliably +- ✅ Source Control — Functional with text-based diff + +### Lesson Learned +Upstream UI components cannot be directly merged due to architectural differences: +- Fork uses lazy-loading on user interaction +- Upstream uses reactive store subscriptions +- Fork prioritizes stability over feature parity +- Future UI features should be custom implementations using preserved infrastructure + +### Available for Custom Implementation +Infrastructure is preserved for these deferred features: +| Feature | Infrastructure | UI Status | +|---------|---------------|-----------| +| Monaco diff viewer | ✅ API ready | Reverted - add to existing modal | +| Worktree file browser | ✅ API ready | Reverted - add to RightPanel | +| Session changes | ✅ API ready | Reverted - add to RightPanel | + +--- + +## 2026-02-14 - UPSTREAM DEV MERGE into restore_v0.9.2-patch.4 +- **Strategy**: Hybrid (auto-merge + targeted fork preservation) +- **Source**: `refs/remotes/upstream/dev` +- **Divergence at start**: ahead 174 / behind 132 (merge-base `158f6e25`) +- **Commit**: `620e933` + +### Conflict Strategy Applied +- **Preserved fork-critical files**: prompt input/tool-call/session-events/session-actions/instance store flows tied to ask_user MCP behavior. +- **Accepted upstream in low-risk areas**: keyboard hint, instance tab, style token updates, many new right-panel/worktree/monaco files. +- **Manual hybrids**: + - `packages/server/src/config/schema.ts`: kept `askUserTimeout` + added upstream OS notification preference fields and passthrough. + - `packages/server/src/server/http-server.ts`: kept both git routes and worktree routes. + - `packages/ui/src/lib/api-client.ts`: retained git APIs + upstream worktree APIs. + - `packages/ui/src/types/global.d.ts`: kept MCP bridge methods + upstream wake lock/notification methods. + - package manifests: preserved fork versions while including required upstream deps where needed. + +### Validation +- `npm run lint` ✅ (warnings only, no errors) +- `npm run typecheck` ✅ (UI + electron-app) + +### Additional Compatibility Fixes +- Added preference fields required by merged upstream UI (`promptSubmitOnEnter`, OS notification settings) in `packages/ui/src/stores/preferences.tsx`. +- Added missing SSE handler export `handleSessionDiff` and session action `deleteMessagePart` to satisfy integrated upstream callers. +- Added `registerPromptInputApi` support in prompt input component and class passthrough for context panel. + +## 2026-01-27 - UPSTREAM MERGE v0.9.2 (origin/mirror) +- **Strategy**: Direct merge with manual conflict resolution +- **Upstream Source**: origin/mirror (15 commits, v0.9.2) +- **Merge Status**: In-progress (staged, typecheck passed) +- **Conflicts Resolved (11)**: + - packages/ui/src/components/expand-button.tsx + - packages/ui/src/components/instance/instance-shell2.tsx + - packages/ui/src/components/markdown.tsx + - packages/ui/src/components/message-block.tsx + - packages/ui/src/components/message-timeline.tsx + - packages/ui/src/components/permission-approval-modal.tsx + - packages/ui/src/components/permission-notification-banner.tsx + - packages/ui/src/components/prompt-input.tsx + - packages/ui/src/components/tool-call.tsx + - packages/ui/src/lib/markdown.ts + - packages/ui/src/main.tsx + +### Decisions & Notes +- **Kept fork ask_user flow**: Removed upstream question-interruption handling from permission modal/tool-call to avoid breaking MCP question wizard. +- **Adopted i18n scaffolding**: Integrated i18n provider and message catalogs; localized UI labels where possible. +- **Preserved fork UX**: Retained mobile prompt placeholder shortening and desktop multi-state expand logic. +- **Typecheck**: `npm run typecheck` ✅ (UI + electron-app) + +## 2026-01-25 - SUCCESSFUL UPSTREAM SYNC v0.9.1 +- **Strategy**: Incremental conflict resolution with strategic file preservation +- **Branch**: merge/mirror-to-dev-20260125 +- **Merge Commit**: fa5b125 +- **Upstream Source**: origin/mirror (20 commits from v0.9.0 → v0.9.1) +- **Fork State**: Preserved all custom features (ask_user MCP, search, failed notifications) + +### Execution Summary +- **Phase 1**: Branch analysis and divergence identification (20 commits each side) +- **Phase 2**: Merge execution with 11 conflicts detected +- **Phase 3**: Strategic conflict resolution: + - Safe changes: Version bumps, configs, workflows (committed first) + - Critical files: Kept fork versions of permission-approval-modal.tsx, tool-call.tsx + - Hybrid merge: session-events.ts (removed question tool refs, kept upstream structure) +- **Phase 4**: Build validation and fixes: + - Initial build: Failed (rollup issue) + - Fix: `rm -rf node_modules package-lock.json && npm install` + - Final build: ✅ PASSED (8.31s) +- **Phase 5**: Typecheck resolution: + - Issue: mcp-server .d.ts files not being generated + - Root cause: Corrupt tsconfig.tsbuildinfo + moduleResolution: "bundler" + - Fix: Changed to moduleResolution: "node", added types field, clean rebuild + - Result: ✅ All typechecks pass (UI + electron-app) + +### Conflicts Resolved (11 total) +1. **package.json** → THEIRS (v0.9.1) +2. **packages/*/package.json** (5 files) → THEIRS (version bumps) +3. **.gitignore** → MANUAL (merged temp/ + .codenomad/, .tmp/) +4. **.github/workflows/reusable-release.yml** → THEIRS (added release-ui, publish-server) +5. **packages/ui/src/components/permission-approval-modal.tsx** → OURS (preserve ask_user MCP) +6. **packages/ui/src/components/tool-call.tsx** → OURS (preserve section expansion + ask_user rendering) +7. **packages/ui/src/stores/session-events.ts** → MANUAL (removed question tool refs, kept upstream structure) +8. **package-lock.json** → REGENERATED (9751 insertions, 4372 deletions) + +### Strategic Decisions + +#### Ask_user vs. Question Tool +**Conflict**: Upstream refactored tool-call.tsx into modular components (ansi-render, diff-render, question-block, permission-block) tightly coupled with their question tool. + +**Decision**: Keep fork's tool-call.tsx (1050 lines) + +**Rationale**: +- Fork's ask_user MCP tool is fundamentally different and more robust: + - Complete MCP server package with JSON-RPC + - Native Electron IPC bridge with zero-cost routing + - Automatic Claude Desktop registration + - Persistent failed notification handling +- Upstream's question tool is a simple UI component without MCP integration +- Fork version also includes custom section expansion feature (search integration) + +**Files Affected**: +- ✅ Kept fork: tool-call.tsx, permission-approval-modal.tsx +- ✅ Modified: session-events.ts (removed reconcilePendingQuestionsV2) + +### Merged Upstream Features (v0.9.1) + +✅ **New Packages & Infrastructure** +- Cloudflare package (remote UI hosting) +- UI auto-update system (version.json manifest) +- Release workflows (release-ui, publish-server CI/CD) + +✅ **UI Enhancements** +- GitHub stars display with brand-icons component +- Version pill component for UI version info +- Enhanced folder picker layout +- Task UI improvements (steps/model headers, prompt/output panes, ANSI support) +- Multi-file diff rendering for apply_patch tool +- Modular tool-call components (we use some, kept our tool-call.tsx) + +✅ **Server & API** +- Filesystem API: create-folder endpoint +- Remote UI support: auto-update via manifest +- Process management: improved workspace cleanup +- UI version serving: emit ui-version.json +- Enhanced path handling for @file mentions + +✅ **Performance & Bug Fixes** +- Session list optimization (reduced churn) +- Message block performance (better invalidation) +- Permission UX improvements +- Server --host binding configuration + +### Fork Features Preserved + +✅ **ask_user MCP Tool** (Complete Implementation) +- packages/mcp-server/* (native MCP server) +- MCP bridge initialization and cleanup +- Question wizard with multi-line support +- Failed notifications with retry logic +- Automatic Claude Desktop registration + +✅ **Custom Features** +- Section expansion (search integration) +- Search functionality (chat search with highlighting) +- Custom tool-call rendering and section expansion +- MCP IPC bridge (zero-cost routing) + +### Build Validation +| Check | Status | Notes | +|-------|--------|-------| +| UI typecheck | ✅ PASSED | No TypeScript errors | +| electron-app typecheck | ✅ PASSED | Fixed by regenerating .d.ts files | +| Build | ✅ PASSED | 8.31s compile time | +| Dev server | ✅ PASSED | All features functional | + +### Test Verification +All fork features tested and working: +- ✅ MCP bridge initialization +- ✅ ask_user tool (question wizard) +- ✅ Failed notifications loading +- ✅ Section expansion +- ✅ Search functionality +- ✅ No runtime errors + +### Post-Merge Fixes + +**2026-01-25**: Fixed electron-app typecheck errors +- **Problem**: mcp-server .d.ts declaration files not being generated +- **Root Cause**: + - Corrupt incremental build cache (tsconfig.tsbuildinfo) + - moduleResolution: "bundler" incompatible with TypeScript 5.9.3 +- **Solution**: + - Changed tsconfig.json: moduleResolution "bundler" → "node" + - Added "types" field to package.json: "dist/server.d.ts" + - Clean rebuild: `rm tsconfig.tsbuildinfo && tsc` +- **Result**: ✅ All typechecks pass, .d.ts files properly generated +- **Commit**: 011a70e + +### Files Changed +- **60 files total**: +6,611 lines, -1,192 lines +- **New files (13)**: Cloudflare package, UI components, remote UI system +- **Modified files (47)**: UI components, server routes, configs, lockfiles + +### Documentation +- **PR.md**: Comprehensive dev→main merge documentation created + +## 2026-01-19 - SUCCESSFUL UPSTREAM MERGE +- Strategy: Bulk merge with selective conflict resolution +- Branch: upstream-merge-analysis-20260119 +- Merge Commit: f532220 (amended) +- User Decisions: + 1. Windows Support: ✅ YES - Included all Windows fixes + 2. Expand Chat: ✅ KEPT FORK - Skipped all 11 upstream expand commits + 3. Authentication: ✅ YES - Merged full authentication system (19 files) + 4. Question Tool: ✅ KEPT FORK - Skipped upstream's question tool, kept ask_user MCP + 5. Performance: ✅ YES - Merged performance optimization + +- Execution Summary: + - **Phase 1**: Bulk merge executed - 9 conflicts identified + - **Phase 2**: Conflicts resolved: + - Package files: Accepted upstream versions (0.7.1, 0.7.2) + - Fork features: Kept expand-button, prompt-input, tool-call, sse-manager, question types + - Manual merge: message-block.tsx (merged both changes) + - Restored fork versions: 7 files that auto-merged but had upstream question tool refs + - **Phase 3**: Removed upstream question tool references from auto-merged files + - **Phase 4**: Validation passed - typecheck successful + +- Conflicts Resolved: 9 files + 1. package-lock.json → THEIRS (regenerate) + 2. packages/opencode-config/package.json → THEIRS (v0.7.1) + 3. packages/ui/package.json → THEIRS (v0.7.2) + 4. expand-button.tsx → OURS (fork's auto-collapse) + 5. prompt-input.tsx → OURS (fork's implementation) + 6. message-block.tsx → MANUAL (merged both: perf + search) + 7. tool-call.tsx → OURS (fork's custom renderers) + 8. sse-manager.ts → OURS (fork's event handling) + 9. question.ts → OURS (fork's ask_user types) + +- Files Restored to Fork Version (removed upstream question tool refs): + 1. permission-approval-modal.tsx + 2. permission-notification-banner.tsx + 3. sessions.ts + 4. instances.ts + 5. message-v2/bridge.ts + 6. session-events.ts + 7. session-api.ts + +- Tests: ✅ PASSED + - Typecheck: PASSED (UI + electron-app) + - Build: PASSED (7.71s) + - Runtime: PASSED (dev server running successfully) + +## Post-Merge Fixes +- **2025-01-19**: Fixed fastify compatibility issue + - Problem: @fastify/reply-from 12.5.0 required fastify 5.x + - Solution: Downgraded to @fastify/reply-from 9.8.0 (compatible with fastify 4.28.1) + - Commit: Fix committed to dev branch + +## Merged Features +✅ **Authentication System** (commit 4063413) + - 19 files added/modified + - packages/server/src/auth/* (complete auth subsystem) + - electron/main/main.ts (auth integration) + - HTTP server routes for login/token + +✅ **Windows Compatibility Fixes** (4 commits) + - df9722c: Background processes via cmd.exe + - dffa490: OpenCode binary validation + - e567d35: Prefer .exe/.cmd candidates + - 62f52fc: Spawn opencode shims via shells + +✅ **Performance Optimizations** (commit 927e4e1) + - Reduced session list churn + - Message block invalidation improvements + - Performance improvements in instance-shell2, message-block, session-list + +✅ **Bug Fixes** + - ae322c5: Go to Session navigation (partially - merged with fork's impl) + - Various stability improvements + +## Skipped Features (Fork Implementation Preserved) +❌ **Expand Chat Feature** (11 commits: f06359a through 7749225) + - Reason: Fork has superior auto-collapse implementation + - Fork feature: Auto-collapse on send, custom expand logic + - Decision: Keep fork's implementation + +❌ **Question Tool** (commit 72f420b + related) + - Reason: Fork has comprehensive ask_user MCP tool + - Fork feature: Native MCP server with ask_user implementation + - Decision: Keep fork's ask_user MCP implementation + - Action: Removed all upstream question tool references from auto-merged files + +## Next Steps +1. **Test Build**: Run `npm run build` to ensure build succeeds +2. **Manual Testing**: Test authentication features, fork features (search, ask_user) +3. **Merge to Dev**: If tests pass, merge this branch back to dev: + ```bash + git checkout dev + git merge upstream-merge-analysis-20260119 + ``` +4. **Regenerate Lockfile**: Run `npm install` to clean up package-lock.json +5. **Push to Origin**: Push updated dev branch to fork + +# Merge Patterns +## Safe Patterns +- Version bumps (package.json changes only) +- Documentation additions +- New files that don't conflict with fork +- Windows-specific fixes (we may not need these if macOS only) + +## Risk Patterns +- prompt-input.tsx modifications (both sides changed) +- expand-button.tsx modifications (both sides changed) +- Electron main.ts changes (upstream added auth, fork added custom features) + +## Upstream Features We May Not Need +- Windows shell fixes (if fork is macOS-only) +- Remote authentication (if fork doesn't need remote access) diff --git a/.github/workflows/dev-release.yml b/.github/workflows/dev-release.yml index 235e9bc0..4fdc3c0f 100644 --- a/.github/workflows/dev-release.yml +++ b/.github/workflows/dev-release.yml @@ -1,4 +1,4 @@ -name: Dev CI +name: Develop Pre-Release on: push: @@ -7,12 +7,35 @@ on: workflow_dispatch: permissions: - contents: read + id-token: write + contents: write + +concurrency: + group: dev-prerelease + cancel-in-progress: true jobs: - dev-ci: - uses: ./.github/workflows/build-and-upload.yml + prepare: + runs-on: ubuntu-latest + outputs: + version_suffix: ${{ steps.vars.outputs.version_suffix }} + steps: + - name: Compute version suffix + id: vars + shell: bash + run: | + set -euo pipefail + SHA8="${GITHUB_SHA::8}" + DATE=$(date -u +%Y%m%d) + echo "version_suffix=-dev-${DATE}-${SHA8}" >> "$GITHUB_OUTPUT" + + prerelease: + needs: prepare + uses: ./.github/workflows/reusable-release.yml with: - upload: false - set_versions: false + version_suffix: ${{ needs.prepare.outputs.version_suffix }} + npm_package_name: "@neuralnomads/codenomad-dev" + dist_tag: latest + prerelease: true + release_ui: false secrets: inherit diff --git a/.github/workflows/manual-npm-publish.yml b/.github/workflows/manual-npm-publish.yml index 86b8768a..81d93fd1 100644 --- a/.github/workflows/manual-npm-publish.yml +++ b/.github/workflows/manual-npm-publish.yml @@ -12,6 +12,11 @@ on: required: false default: dev type: string + package_name: + description: "Package name to publish (e.g. @neuralnomads/codenomad-dev)" + required: false + default: "@neuralnomads/codenomad" + type: string workflow_call: inputs: version: @@ -21,6 +26,13 @@ on: required: false type: string default: dev + package_name: + required: false + type: string + default: "@neuralnomads/codenomad" + secrets: + NPM_TOKEN: + required: false permissions: contents: read @@ -51,7 +63,7 @@ jobs: run: npm install @rollup/rollup-linux-x64-gnu --no-save - name: Build server package (includes UI bundling) - run: npm run build --workspace @neuralnomads/codenomad + run: npm run build --workspace packages/server - name: Set publish metadata shell: bash @@ -62,13 +74,31 @@ jobs: fi echo "VERSION=$VERSION_INPUT" >> "$GITHUB_ENV" echo "DIST_TAG=${{ inputs.dist_tag || 'dev' }}" >> "$GITHUB_ENV" + echo "PACKAGE_NAME=${{ inputs.package_name }}" >> "$GITHUB_ENV" - name: Bump package version for publish run: npm version ${VERSION} --workspaces --include-workspace-root --no-git-tag-version --allow-same-version + - name: Set server package name for publish + shell: bash + run: | + set -euo pipefail + node -e "const fs=require('fs'); const path=require('path'); const p=path.join('packages','server','package.json'); const j=JSON.parse(fs.readFileSync(p,'utf8')); j.name=process.env.PACKAGE_NAME || j.name; fs.writeFileSync(p, JSON.stringify(j, null, 2)+'\n'); console.log('Publishing as', j.name);" + - name: Publish server package with provenance env: + # Optional: when present, npm will use token auth. + # When empty/unset, npm trusted publishing (OIDC) may be used if configured. + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_CONFIG_PROVENANCE: true NPM_CONFIG_REGISTRY: https://registry.npmjs.org + shell: bash run: | - npm publish --workspace @neuralnomads/codenomad --access public --tag ${DIST_TAG} --provenance + set -euo pipefail + if [ -z "${NODE_AUTH_TOKEN:-}" ]; then + echo "NPM_TOKEN not set; attempting npm trusted publishing (OIDC)" + unset NODE_AUTH_TOKEN + else + echo "Using NPM_TOKEN authentication" + fi + npm publish --workspace packages/server --access public --tag ${DIST_TAG} --provenance diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dfd07e8e..0ce704b5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,4 +14,5 @@ jobs: uses: ./.github/workflows/reusable-release.yml with: dist_tag: latest + npm_package_name: "@neuralnomads/codenomad" secrets: inherit diff --git a/.github/workflows/reusable-release.yml b/.github/workflows/reusable-release.yml index 2f6da125..4fd532c3 100644 --- a/.github/workflows/reusable-release.yml +++ b/.github/workflows/reusable-release.yml @@ -13,6 +13,21 @@ on: required: false default: dev type: string + npm_package_name: + description: "npm package name to publish (defaults to server package name)" + required: false + default: "" + type: string + prerelease: + description: "Create GitHub prerelease" + required: false + default: false + type: boolean + release_ui: + description: "Publish remote UI + manifest" + required: false + default: true + type: boolean permissions: id-token: write @@ -53,11 +68,16 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG: ${{ steps.versions.outputs.tag }} + IS_PRERELEASE: ${{ inputs.prerelease }} run: | if gh release view "$TAG" >/dev/null 2>&1; then echo "Release $TAG already exists" else - gh release create "$TAG" --title "$TAG" --generate-notes + if [ "${IS_PRERELEASE}" = "true" ]; then + gh release create "$TAG" --title "$TAG" --generate-notes --prerelease + else + gh release create "$TAG" --title "$TAG" --generate-notes + fi fi build-and-upload: @@ -70,13 +90,16 @@ jobs: secrets: inherit release-ui: + if: github.repository == 'NeuralNomadsAI/CodeNomad' needs: prepare-release + if: ${{ inputs.release_ui }} permissions: contents: read uses: ./.github/workflows/release-ui.yml secrets: inherit publish-server: + if: github.repository == 'NeuralNomadsAI/CodeNomad' needs: - prepare-release - build-and-upload @@ -84,4 +107,5 @@ jobs: with: version: ${{ needs.prepare-release.outputs.version }} dist_tag: ${{ inputs.dist_tag }} + package_name: ${{ inputs.npm_package_name }} secrets: inherit diff --git a/.gitignore b/.gitignore index 131c5a63..66e33759 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,9 @@ release/ out/ .dir-locals.el .opencode/bashOutputs/ +temp/ # Local runtime artifacts .codenomad/ .tmp/ -packages/cloudflare/.wrangler/ \ No newline at end of file +packages/cloudflare/.wrangler/ diff --git a/.opencode/plans/2026-01-31-reactive-ask-user-retry.md b/.opencode/plans/2026-01-31-reactive-ask-user-retry.md new file mode 100644 index 00000000..57a2e6d3 --- /dev/null +++ b/.opencode/plans/2026-01-31-reactive-ask-user-retry.md @@ -0,0 +1,967 @@ +# Reactive ask_user MCP Retry System Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Implement a reactive retry mechanism for ask_user MCP that detects UI rendering failures and instructs the agent to retry within the same session without triggering premium requests. + +**Architecture:** Add a render-confirmation heartbeat system where UI must acknowledge question display within 30 seconds. If no confirmation, return `shouldRetry: true` with clear directive. Distinguish between "UI didn't render" (retry) and "User didn't respond" (timeout). Update tool schema description to instruct agents on retry behavior. Enhance question schema with structured options (label+description), header field, and custom answer toggle like OpenCode. + +**Tech Stack:** TypeScript, Zod, Node.js EventEmitter pattern, Electron IPC + +--- + +## Prerequisites + +- Current timeout: 5 minutes (300000ms) +- No automatic retry exists beyond 1 UI-level attempt +- Agent receives `{ timedOut: true }` but doesn't know to retry +- Goal: Zero additional premium requests on retry + +--- + +## Overview of Changes + +### New Schema Fields (CnAskUserOutput) + +```typescript +{ + answered: boolean, + cancelled: boolean, + timedOut: boolean, + shouldRetry: boolean, // NEW: Agent should retry this question + retryReason: string | null, // NEW: Why retry is needed (for debugging) + renderConfirmed: boolean, // NEW: Whether UI confirmed display + answers: QuestionAnswer[] +} +``` + +### New Input Parameter (CnAskUserInput) + +```typescript +{ + questions: [...], + title?: string, + maxRetries?: number, // NEW: Max retry attempts (default: 3) + renderTimeout?: number // NEW: Time to wait for UI render confirmation (default: 30000ms) +} +``` + +### Flow Changes + +1. **Question Sent** → Start 30s render confirmation timer +2. **UI Confirms** → Cancel render timer, start 5min user response timer +3. **No Confirmation in 30s** → Return `shouldRetry: true, retryReason: "UI render timeout"` +4. **Agent Receives shouldRetry** → Retries ask_user immediately (same session) +5. **Max Retries Exceeded** → Return `shouldRetry: false, error: "Max retries exceeded"` + +--- + +## Task 1: Update Schemas with New Fields + +**Files:** +- Modify: `packages/mcp-server/src/tools/schemas.ts` +- Test: `packages/mcp-server/src/__tests__/schemas.test.ts` (create if doesn't exist) + +**Step 1: Update CnAskUserInputSchema** + +Add `maxRetries` and `renderTimeout` optional parameters: + +```typescript +export const CnAskUserInputSchema = z.object({ + questions: z.array(QuestionInfoSchema).min(1).max(10), + title: z.string().max(100).optional(), + maxRetries: z.number().int().min(0).max(5).optional().default(3) + .describe("Maximum retry attempts if UI fails to render (0-5, default: 3)"), + renderTimeout: z.number().int().min(10000).max(60000).optional().default(30000) + .describe("Milliseconds to wait for UI render confirmation (10-60s, default: 30s)"), +}); +``` + +**Step 2: Update CnAskUserOutputSchema** + +Add retry-related fields: + +```typescript +export const CnAskUserOutputSchema = z.object({ + answered: z.boolean(), + cancelled: z.boolean(), + timedOut: z.boolean(), + shouldRetry: z.boolean() + .describe("If true, the agent MUST retry this question immediately in the same session"), + retryReason: z.string().nullable() + .describe("Human-readable reason for retry (for debugging)"), + renderConfirmed: z.boolean() + .describe("Whether the UI confirmed the question was displayed"), + answers: z.array(QuestionAnswerSchema), +}); +``` + +**Step 3: Create schema validation test** + +```typescript +import { describe, it } from 'node:test'; +import assert from 'node:assert'; +import { CnAskUserInputSchema, CnAskUserOutputSchema } from '../tools/schemas.js'; + +describe('CnAskUserInputSchema', () => { + it('should accept valid input with default maxRetries', () => { + const result = CnAskUserInputSchema.safeParse({ + questions: [{ question: 'Test?' }] + }); + assert.strictEqual(result.success, true); + assert.strictEqual(result.data?.maxRetries, 3); + assert.strictEqual(result.data?.renderTimeout, 30000); + }); + + it('should accept custom maxRetries and renderTimeout', () => { + const result = CnAskUserInputSchema.safeParse({ + questions: [{ question: 'Test?' }], + maxRetries: 5, + renderTimeout: 15000 + }); + assert.strictEqual(result.success, true); + assert.strictEqual(result.data?.maxRetries, 5); + assert.strictEqual(result.data?.renderTimeout, 15000); + }); + + it('should reject maxRetries > 5', () => { + const result = CnAskUserInputSchema.safeParse({ + questions: [{ question: 'Test?' }], + maxRetries: 10 + }); + assert.strictEqual(result.success, false); + }); +}); + +describe('CnAskUserOutputSchema', () => { + it('should validate output with retry fields', () => { + const result = CnAskUserOutputSchema.safeParse({ + answered: false, + cancelled: false, + timedOut: false, + shouldRetry: true, + retryReason: "UI render timeout", + renderConfirmed: false, + answers: [] + }); + assert.strictEqual(result.success, true); + }); +}); +``` + +**Step 4: Run tests** + +```bash +cd packages/mcp-server +node --test src/__tests__/schemas.test.ts +``` + +Expected: PASS + +**Step 5: Commit** + +```bash +git add packages/mcp-server/src/tools/schemas.ts +if [ -f packages/mcp-server/src/__tests__/schemas.test.ts ]; then + git add packages/mcp-server/src/__tests__/schemas.test.ts +fi +git commit -m "feat(mcp): add retry-related fields to ask_user schemas" +``` + +--- + +## Task 2: Add Render Confirmation Tracking to PendingRequest + +**Files:** +- Modify: `packages/mcp-server/src/pending.ts` +- Test: `packages/mcp-server/src/__tests__/pending.test.ts` (update existing) + +**Step 1: Update PendingRequest interface** + +```typescript +export interface PendingRequest { + id: string; + questions: any[]; + resolve: (result: PendingRequestResult) => void; + reject: (error: Error) => void; + createdAt: number; + timeout: NodeJS.Timeout | null; + // NEW FIELDS + renderTimeout: NodeJS.Timeout | null; // Timer for UI render confirmation + renderConfirmed: boolean; // Whether UI confirmed display + maxRetries: number; // Max retry attempts allowed + retryCount: number; // Current retry attempt number +} +``` + +**Step 2: Update PendingRequestResult interface** + +```typescript +export interface PendingRequestResult { + answered: boolean; + cancelled: boolean; + timedOut: boolean; + // NEW FIELDS + shouldRetry: boolean; + retryReason: string | null; + renderConfirmed: boolean; + answers: QuestionAnswer[]; +} +``` + +**Step 3: Update PendingRequestManager class** + +Add new methods: + +```typescript +/** + * Mark request as having confirmed render + */ +confirmRender(id: string): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + + // Clear render timeout + if (request.renderTimeout) { + clearTimeout(request.renderTimeout); + request.renderTimeout = null; + } + + request.renderConfirmed = true; + return true; +} + +/** + * Check if request can be retried + */ +canRetry(id: string): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + return request.retryCount < request.maxRetries; +} + +/** + * Increment retry count for a request + */ +incrementRetry(id: string): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + request.retryCount += 1; + return true; +} +``` + +**Step 4: Update resolve method** + +Include new fields in resolved result: + +```typescript +resolve(id: string, answers: QuestionAnswer[]): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + + if (request.timeout) { + clearTimeout(request.timeout); + } + if (request.renderTimeout) { + clearTimeout(request.renderTimeout); + } + + request.resolve({ + answered: true, + cancelled: false, + timedOut: false, + shouldRetry: false, + retryReason: null, + renderConfirmed: request.renderConfirmed, + answers + }); + + this.pending.delete(id); + return true; +} +``` + +**Step 5: Update reject method** + +Add retry logic: + +```typescript +reject(id: string, error: Error): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + + if (request.timeout) { + clearTimeout(request.timeout); + } + if (request.renderTimeout) { + clearTimeout(request.renderTimeout); + } + + const isCancelled = error.message === 'cancelled'; + const isTimedOut = error.message === 'Question timeout'; + const isRenderTimeout = error.message === 'Render timeout'; + + // Determine if we should retry + const shouldRetry = isRenderTimeout && request.retryCount < request.maxRetries; + const retryReason = shouldRetry + ? `UI failed to render question (attempt ${request.retryCount + 1}/${request.maxRetries})` + : isRenderTimeout + ? `Max retries (${request.maxRetries}) exceeded` + : null; + + request.resolve({ + answered: false, + cancelled: isCancelled, + timedOut: isTimedOut, + shouldRetry, + retryReason, + renderConfirmed: request.renderConfirmed, + answers: [] + }); + + this.pending.delete(id); + return true; +} +``` + +**Step 6: Run existing tests** + +```bash +node --test packages/mcp-server/src/__tests__/pending.test.ts +``` + +Expected: PASS (may need test updates for new fields) + +**Step 7: Commit** + +```bash +git add packages/mcp-server/src/pending.ts +git commit -m "feat(mcp): add render confirmation and retry tracking to PendingRequestManager" +``` + +--- + +## Task 3: Update askUser Tool with Render Timeout Logic + +**Files:** +- Modify: `packages/mcp-server/src/tools/askUser.ts` +- Test: `packages/mcp-server/src/__tests__/askUser.test.ts` (create if doesn't exist) + +**Step 1: Update askUser function signature** + +```typescript +export async function askUser( + input: CnAskUserInput, + bridge: QuestionBridge, + pendingManager: PendingRequestManager +): Promise { +``` + +**Step 2: Implement render timeout logic** + +```typescript +export async function askUser( + input: CnAskUserInput, + bridge: QuestionBridge, + pendingManager: PendingRequestManager +): Promise { + + const requestId = generateRequestId(); + const maxRetries = input.maxRetries ?? 3; + const renderTimeoutMs = input.renderTimeout ?? 30000; + + console.log(`[MCP] ask_user called: ${requestId}`, { + questions: input.questions.length, + title: input.title ?? null, + maxRetries, + renderTimeoutMs + }); + + const questionsWithIds: Array = input.questions.map((q, index) => ({ + ...q, + id: q.id || `${requestId}_${index}` + })); + + return new Promise((resolve) => { + // Create render timeout + const renderTimer = setTimeout(() => { + console.log(`[MCP] Render timeout for ${requestId} - UI did not confirm display`); + + // Check if we can retry + const pending = pendingManager.get(requestId); + if (pending && pendingManager.canRetry(requestId)) { + // Increment retry and reject with render timeout + pendingManager.incrementRetry(requestId); + pendingManager.reject(requestId, new Error('Render timeout')); + } else { + // Max retries exceeded or no pending request + pendingManager.reject(requestId, new Error('Render timeout - max retries exceeded')); + } + }, renderTimeoutMs); + + pendingManager.add({ + id: requestId, + questions: questionsWithIds, + resolve: (result) => resolve(result), + reject: (error) => { + console.error(`[MCP] Request rejected: ${requestId}`, error); + resolve({ + answered: false, + cancelled: error.message === 'cancelled', + timedOut: error.message === 'Question timeout', + shouldRetry: error.message === 'Render timeout', + retryReason: error.message === 'Render timeout' + ? 'UI failed to render question within timeout' + : null, + renderConfirmed: false, + answers: [] + }); + }, + createdAt: Date.now(), + timeout: null, // Will be set after render confirmation + renderTimeout: renderTimer, + renderConfirmed: false, + maxRetries, + retryCount: 0 + }); + + // Send question to bridge + bridge.sendQuestion(requestId, questionsWithIds, input.title); + }); +} +``` + +**Step 3: Update QuestionBridge interface** + +Add method for render confirmation: + +```typescript +export interface QuestionBridge { + sendQuestion(requestId: string, questions: Array, title?: string): void; + onAnswer(callback: (requestId: string, answers: any[]) => void): void; + onCancel(callback: (requestId: string) => void): void; + onRenderConfirmed(callback: (requestId: string) => void): void; // NEW +} +``` + +**Step 4: Create test file** + +```typescript +import { describe, it } from 'node:test'; +import assert from 'node:assert'; +import { askUser, type QuestionBridge } from '../tools/askUser.js'; +import { PendingRequestManager } from '../pending.js'; + +describe('askUser', () => { + it('should return shouldRetry=true on render timeout', async () => { + const manager = new PendingRequestManager(); + const bridge: QuestionBridge = { + sendQuestion: () => {}, // Never confirms render + onAnswer: () => {}, + onCancel: () => {}, + onRenderConfirmed: () => {} + }; + + const result = await askUser({ + questions: [{ question: 'Test?' }], + renderTimeout: 300 // Fast timeout for testing + }, bridge, manager); + + assert.strictEqual(result.shouldRetry, true); + assert.strictEqual(result.renderConfirmed, false); + assert.ok(result.retryReason?.includes('UI failed to render')); + }); + + it('should return shouldRetry=false after max retries', async () => { + const manager = new PendingRequestManager(); + const bridge: QuestionBridge = { + sendQuestion: () => {}, + onAnswer: () => {}, + onCancel: () => {}, + onRenderConfirmed: () => {} + }; + + // First attempt - should retry + const result1 = await askUser({ + questions: [{ question: 'Test?' }], + maxRetries: 1, + renderTimeout: 50 + }, bridge, manager); + assert.strictEqual(result1.shouldRetry, true); + + // Second attempt - max retries exceeded + const result2 = await askUser({ + questions: [{ question: 'Test?' }], + maxRetries: 1, + renderTimeout: 50 + }, bridge, manager); + assert.strictEqual(result2.shouldRetry, false); + assert.ok(result2.retryReason?.includes('Max retries')); + }); +}); +``` + +**Step 5: Run tests** + +```bash +node --test packages/mcp-server/src/__tests__/askUser.test.ts +``` + +Expected: PASS + +**Step 6: Commit** + +```bash +git add packages/mcp-server/src/tools/askUser.ts +if [ -f packages/mcp-server/src/__tests__/askUser.test.ts ]; then + git add packages/mcp-server/src/__tests__/askUser.test.ts +fi +git commit -m "feat(mcp): implement render timeout and retry logic in askUser tool" +``` + +--- + +## Task 4: Update Server Tool Schema Description + +**Files:** +- Modify: `packages/mcp-server/src/server.ts` (lines 125-158) + +**Step 1: Update getAskUserToolSchema method** + +Update the description and add proper instruction to the agent: + +```typescript +private getAskUserToolSchema() { + return { + name: "ask_user", + description: `Ask the user questions through CodeNomad's interface. + +IMPORTANT INSTRUCTIONS FOR AI AGENT: +1. This tool blocks until the user responds or a timeout occurs. +2. If the response has shouldRetry=true, you MUST retry calling this tool immediately with the same parameters. +3. If shouldRetry=false and timedOut=true, inform the user the question timed out and ask if they want to continue. +4. If shouldRetry=false and max retries were exceeded, inform the user there was a technical issue displaying the question. + +The tool will automatically retry up to 3 times if the UI fails to render the question. You only need to retry when shouldRetry=true is returned.`, + inputSchema: { + type: "object", + properties: { + questions: { + type: "array", + description: "Array of questions to ask user", + items: { + type: "object", + properties: { + question: { type: "string" }, + type: { type: "string", enum: ["text", "select", "multi-select", "confirm"] }, + options: { type: "array", items: { type: "string" } }, + required: { type: "boolean" }, + placeholder: { type: "string" } + }, + required: ["question"] + }, + minItems: 1, + maxItems: 10 + }, + title: { + type: "string", + description: "Optional title for question dialog", + maxLength: 100 + }, + maxRetries: { + type: "integer", + description: "Maximum retry attempts if UI fails to render (0-5, default: 3)", + minimum: 0, + maximum: 5, + default: 3 + }, + renderTimeout: { + type: "integer", + description: "Milliseconds to wait for UI render confirmation (10000-60000, default: 30000)", + minimum: 10000, + maximum: 60000, + default: 30000 + } + }, + required: ["questions"] + } + }; +} +``` + +**Step 2: Commit** + +```bash +git add packages/mcp-server/src/server.ts +git commit -m "docs(mcp): update ask_user tool description with retry instructions for agents" +``` + +--- + +## Task 5: Update IPC Bridge for Render Confirmation + +**Files:** +- Modify: `packages/mcp-server/src/bridge/ipc.ts` +- Modify: `packages/mcp-server/src/bridge/renderer.ts` (if exists) +- Modify: `packages/ui/src/lib/mcp-bridge.ts` + +**Step 1: Add render confirmation IPC handler in ipc.ts** + +Add to setupMcpBridge function: + +```typescript +// Handler: UI confirms question was rendered/displayed +ipcMain.on('mcp:renderConfirmed', (_event: any, data: any) => { + const { requestId } = data; + console.log(`[MCP IPC] Received render confirmation from UI: ${requestId}`); + emitRendererLog(mainWindow, 'info', 'Received render confirmation from UI', { requestId }); + + if (globalPendingManager) { + const confirmed = globalPendingManager.confirmRender(requestId); + if (confirmed) { + console.log(`[MCP IPC] Render confirmed for ${requestId}, starting user response timer`); + emitRendererLog(mainWindow, 'info', 'Render confirmed, starting user response timer', { requestId }); + + // Start the 5-minute user response timeout + const pending = globalPendingManager.get(requestId); + if (pending) { + pending.timeout = setTimeout(() => { + console.log(`[MCP IPC] User response timeout for ${requestId}`); + globalPendingManager?.reject(requestId, new Error('Question timeout')); + }, 300000); // 5 minutes + } + } else { + console.warn(`[MCP IPC] No pending request for render confirmation: ${requestId}`); + emitRendererLog(mainWindow, 'warn', 'No pending request for render confirmation', { requestId }); + } + } else { + console.warn('[MCP IPC] Pending manager not initialized, cannot process render confirmation'); + emitRendererLog(mainWindow, 'warn', 'Pending manager not initialized'); + } +}); +``` + +**Step 2: Update createIpcBridge to include onRenderConfirmed** + +```typescript +export function createIpcBridge(mainWindow: BrowserWindow, pendingManager: PendingRequestManager): QuestionBridge { + // ... existing code ... + + return { + sendQuestion: (requestId, questions, title) => { + // ... existing code ... + }, + onAnswer: (callback) => { + // Already handled + }, + onCancel: (callback) => { + // Already handled + }, + onRenderConfirmed: (callback) => { + // Handled via 'mcp:renderConfirmed' IPC handler above + console.log('[MCP IPC] Render confirmation handler registered (via IPC)'); + } + }; +} +``` + +**Step 3: Update UI bridge to send render confirmation** + +In `packages/ui/src/lib/mcp-bridge.ts`, after question is displayed: + +Find the section where the question is added to the queue (around line 193) and add: + +```typescript +// After adding question to queue, send render confirmation back to MCP +if (isElectronEnvironment()) { + setTimeout(() => { + const electronAPI = (window as any).electronAPI; + electronAPI.mcpSend('mcp:renderConfirmed', { + requestId, + timestamp: Date.now() + }); + if (import.meta.env.DEV) { + console.log(`[MCP Bridge UI] Sent render confirmation for ${requestId}`); + } + }, 100); // Small delay to ensure UI actually rendered +} +``` + +**Step 4: Commit** + +```bash +git add packages/mcp-server/src/bridge/ipc.ts +git add packages/ui/src/lib/mcp-bridge.ts +git commit -m "feat(mcp): implement render confirmation IPC between UI and MCP server" +``` + +--- + +## Task 6: Update UI Auto-Open Logic with Retry Awareness + +**Files:** +- Modify: `packages/ui/src/components/instance/instance-shell2.tsx` + +**Step 1: Enhance question wizard auto-open with retry tracking** + +Around line 232-257, update the createEffect to track retry attempts: + +```typescript +// Auto-open question wizard when a pending question appears (unless minimized) +createEffect(() => { + const pending = getPendingQuestion(props.instance.id) + if (import.meta.env.DEV) { + console.log('[Instance Shell] createEffect check:', { + instanceId: props.instance.id, + pendingQuestionId: pending?.id ?? null, + minimized: questionWizardMinimized(), + willOpen: !!(pending && !questionWizardMinimized()) + }) + } + if (pending && !questionWizardMinimized()) { + // Auto-open only if user hasn't minimized + if (import.meta.env.DEV) { + console.log('[Instance Shell] Opening question wizard for:', pending.id) + } + setQuestionWizardOpen(true) + + // Send render confirmation to MCP server + if (isElectronEnvironment() && pending.source === 'mcp') { + const electronAPI = (window as any).electronAPI; + electronAPI.mcpSend('mcp:renderConfirmed', { + requestId: pending.id, + timestamp: Date.now() + }); + } + } else if (!pending) { + // Reset states when no pending questions + if (import.meta.env.DEV) { + console.log('[Instance Shell] No pending question, closing wizard') + } + setQuestionWizardOpen(false) + setQuestionWizardMinimized(false) + } +}) +``` + +**Step 2: Add strong notification for retried questions** + +Add helper function: + +```typescript +const showRetryNotification = (questionId: string, attemptNumber: number) => { + showToastNotification({ + title: attemptNumber > 1 ? 'Question Retry' : 'Question Received', + message: attemptNumber > 1 + ? `Previous attempt failed to display. This is retry attempt ${attemptNumber}.` + : 'Please answer the question to continue.', + variant: attemptNumber > 1 ? 'warning' : 'info', + duration: 15000, // Longer duration for retries + }); +}; +``` + +**Step 3: Commit** + +```bash +git add packages/ui/src/components/instance/instance-shell2.tsx +git commit -m "feat(ui): enhance question wizard with render confirmation and retry notifications" +``` + +--- + +## Task 7: Update AGENTS.md with Retry Instruction + +**Files:** +- Modify: `/Users/muhammadfaiz/Custom APP/CodeNomad/AGENTS.md` + +**Step 1: Add retry instruction section** + +After line 15 ("NO EXCEPTIONS..."), add: + +```markdown +## ask_user Tool Retry Behavior + +**When ask_user returns `shouldRetry: true`:** +1. **IMMEDIATELY retry** the ask_user tool call with the SAME parameters +2. Do NOT summarize, end the session, or ask the user what happened +3. This is an automatic UI recovery mechanism - the question failed to display +4. The retry happens within the same session (no premium request cost) + +**When ask_user returns `shouldRetry: false` and `timedOut: true`:** +1. The user did not respond within 5 minutes +2. Ask the user if they want to continue or if they missed the question +3. You may re-ask the question if the user confirms they want to continue + +**When ask_user returns `shouldRetry: false` with error:** +1. Maximum retry attempts (3) have been exceeded +2. Inform the user: "There was a technical issue displaying the question. Please try again." +3. Ask if they want to continue with the task +``` + +**Step 2: Commit** + +```bash +git add AGENTS.md +git commit -m "docs: add ask_user retry behavior instructions for agents" +``` + +--- + +## Task 8: Integration Testing + +**Files:** +- Create: `packages/mcp-server/src/__tests__/integration-retry.test.ts` + +**Step 1: Write integration test** + +```typescript +import { describe, it, beforeEach } from 'node:test'; +import assert from 'node:assert'; +import { CodeNomadMcpServer } from '../server.js'; +import { PendingRequestManager } from '../pending.js'; + +describe('ask_user retry integration', () => { + let server: CodeNomadMcpServer; + let pendingManager: PendingRequestManager; + + beforeEach(() => { + pendingManager = new PendingRequestManager(); + server = new CodeNomadMcpServer(); + // Mock bridge that never confirms render + (server as any).bridge = { + sendQuestion: () => {}, + onAnswer: () => {}, + onCancel: () => {}, + onRenderConfirmed: () => {} + }; + (server as any).pendingManager = pendingManager; + }); + + it('should retry 3 times then give up', async () => { + const results = []; + + // Simulate 4 attempts (3 retries + 1 final failure) + for (let i = 0; i < 4; i++) { + const result = await (server as any).handleToolsCall(1, { + name: 'ask_user', + arguments: { + questions: [{ question: 'Test?' }], + maxRetries: 3, + renderTimeout: 300 + } + }); + + const parsedResult = JSON.parse(result.result.content[0].text); + results.push(parsedResult); + } + + // First 3 should request retry + assert.strictEqual(results[0].shouldRetry, true); + assert.strictEqual(results[1].shouldRetry, true); + assert.strictEqual(results[2].shouldRetry, true); + + // 4th should not retry (max exceeded) + assert.strictEqual(results[3].shouldRetry, false); + }); + + it('should succeed on first try if render confirmed', async () => { + // This test requires a mock that confirms render + // Implementation depends on how you want to mock the IPC + }); +}); +``` + +**Step 2: Run tests** + +```bash +node --test packages/mcp-server/src/__tests__/integration-retry.test.ts +``` + +Expected: PASS + +**Step 3: Commit** + +```bash +git add packages/mcp-server/src/__tests__/integration-retry.test.ts +git commit -m "test(mcp): add integration tests for ask_user retry mechanism" +``` + +--- + +## Task 9: End-to-End Testing + +**Manual testing steps:** + +1. **Start the application** + ```bash + npm run dev + ``` + +2. **Test normal flow:** + - Ask agent to use ask_user tool + - Verify question appears immediately + - Verify render confirmation is sent + - Answer question + - Verify success response with `shouldRetry: false` + +3. **Test render timeout (simulate):** + - Block UI from rendering (e.g., breakpoint or delay) + - Verify `shouldRetry: true` returned after 30s + - Verify agent retries automatically + - Verify toast notification shows retry attempt + +4. **Test max retries exceeded:** + - Prevent UI from rendering completely + - Verify 3 retry attempts occur + - Verify final response has `shouldRetry: false` with error + +5. **Verify no premium requests:** + - Check logs for "MCP TOOL INVOKED: ask_user (ZERO-COST)" + - Verify retries don't trigger new LLM calls + +**Step 1: Document test results** + +Create `docs/testing/ask_user_retry_tests.md` with test results. + +**Step 2: Commit** + +```bash +git add docs/testing/ask_user_retry_tests.md +git commit -m "docs: add end-to-end testing documentation for ask_user retry" +``` + +--- + +## Summary + +This implementation adds: + +1. **Render confirmation** - UI must confirm display within 30s +2. **Automatic retry** - Up to 3 retries if UI fails to render +3. **Clear agent instructions** - Tool schema tells agent when to retry +4. **No premium cost** - Retries happen within same session +5. **Distinguish failure types** - UI failure vs user timeout +6. **Strong notifications** - Users are alerted on retries + +The system ensures questions are reliably delivered to users without consuming additional premium requests on retry attempts. + +--- + +**Execution choice:** + +1. **Subagent-Driven (this session)** - I dispatch fresh subagent per task +2. **Parallel Session (separate)** - Open new session with executing-plans + +Which approach would you prefer? diff --git a/AGENTS.md b/AGENTS.md index 3017aaea..26ff9e6f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,81 @@ # AGENT NOTES -## Styling Guidelines +## Communication Requirement +**CRITICAL: ALWAYS USE ASK_USER TOOL** +**CRITICAL: REPLACE ALL TOOL `question` WITH `ask_user` TOOL** + +**MUST use `ask_user` tool for:** + +- ANY reply to the user +- ANY response to the user +- ANY summary for the user + +**Session ending: ONLY end the session when the user EXPLICITLY requests it through the "ask_user" tool.** + +**NO EXCEPTIONS. This rule is MANDATORY and NON-NEGOTIABLE.** + +## ask_user Tool Retry Behavior + +**When ask_user returns `shouldRetry: true`:** +1. **IMMEDIATELY retry** the ask_user tool call with the SAME parameters +2. Do NOT summarize, end the session, or ask the user what happened +3. This is an automatic UI recovery mechanism - the question failed to display +4. The retry happens within the same session (no premium request cost) + +**When ask_user returns `shouldRetry: false` and `timedOut: true`:** +1. The user did not respond within 5 minutes +2. Ask the user if they want to continue or if they missed the question +3. You may re-ask the question if the user confirms they want to continue + +**When ask_user returns `shouldRetry: false` with error:** +1. Maximum retry attempts (3) have been exceeded +2. Inform the user: "There was a technical issue displaying the question. Please try again." +3. Ask if they want to continue with the task + +## Build Commands +- `npm run typecheck` - Typecheck all packages (UI + electron-app) +- `npm run build` - Build the electron-app +- `npm run build:ui` - Build the UI package +- `npm run build:tauri` - Build the Tauri app +- `npm run dev` - Start electron-app dev server +- `npm run dev:tauri` - Start Tauri dev server + +## Testing +- Use Node.js built-in test runner (`node:test`) +- Test files are located in `__tests__` directories (e.g., `packages/server/src/filesystem/__tests__/`) +- Run individual test: `node --test packages/server/src/filesystem/__tests__/search-cache.test.ts` + +## Code Style Guidelines + +### Imports +- Type imports first: `import type { X } from "..."` then regular imports +- External packages before internal modules +- Group SolidJS imports explicitly: `import { Component, For, Show } from "solid-js"` + +### Naming Conventions +- Components: PascalCase (`App`, `InstanceShell`) +- Functions/variables: camelCase (`handleSelectFolder`, `launchError`) +- Module-level constants: UPPER_SNAKE_CASE (`FALLBACK_API_BASE`) +- Types/Interfaces: PascalCase (`WorkspaceCreateRequest`, `FileSystemEntry`) +- Files: kebab-case (`api-client.ts`, `workspaces.ts`) + +### Formatting +- 2-space indentation +- Use TypeScript strict mode (already enabled in tsconfig.json) +- Use `type` keyword for type-only imports +- Interfaces for object shapes, types for unions/primitives + +### SolidJS Specifics +- Use reactive primitives: `createSignal`, `createMemo`, `createEffect` +- Component function type: `Component = () => JSX.Element` +- Signals follow convention: `name()` is accessor, `setName()` is setter + +### Error Handling +- Use `unknown` for error types in catch blocks +- Log errors with context: `log.error("message", error)` +- Server routes: return appropriate HTTP status codes (400, 404, 500) + +### Styling Guidelines - Reuse the existing token & utility layers before introducing new CSS variables or custom properties. Extend `src/styles/tokens.css` / `src/styles/utilities.css` if a shared pattern is needed. - Keep aggregate entry files (e.g., `src/styles/controls.css`, `messaging.css`, `panels.css`) lean—they should only `@import` feature-specific subfiles located inside `src/styles/{components|messaging|panels}`. - When adding new component styles, place them beside their peers in the scoped subdirectory (e.g., `src/styles/messaging/new-part.css`) and import them from the corresponding aggregator file. @@ -15,6 +90,35 @@ - Prefer composable primitives (signals, hooks, utilities) over deep inheritance or implicit global state. - When adding platform integrations (SSE, IPC, SDK), isolate them in thin adapters that surface typed events/actions. +## Multi-Language Support (i18n) + +The UI uses a small custom i18n layer (no ICU/messageformat). When building features, never hardcode user-visible strings. + +- **Runtime API:** use `useI18n()` in components (`const { t } = useI18n();`) and `tGlobal(...)` in stores/non-component code. + - Implementation: `packages/ui/src/lib/i18n/index.tsx` +- **Where messages live:** `packages/ui/src/lib/i18n/messages//` as TypeScript objects (`"flat.dot.keys": "string"`). + - Each locale has an `index.ts` that merges message parts; duplicate keys throw at build time. + - Merge helper: `packages/ui/src/lib/i18n/messages/merge.ts` +- **Adding a new string:** add it to the appropriate `.../messages/en/*.ts` part file, then add the same key to each other locale’s corresponding file. + - Missing translations fall back to English (and finally to the key), so gaps can be easy to miss. +- **Interpolation:** placeholders are simple `{name}` replacements (word characters only). Avoid placeholders like `{file-name}`. +- **Pluralization:** handle manually via separate keys like `something.one` / `something.other` and choose in code. +- **Adding a new language:** add a new `messages//` folder + `index.ts`, register it in `packages/ui/src/lib/i18n/index.tsx`, and add it to the language picker in `packages/ui/src/components/folder-selection-view.tsx`. +- **Locale persistence:** the selected locale is stored in app preferences (`locale`) and persisted via the server config (default `~/.config/codenomad/config.json`). +- **Avoid English-only paths:** do not import `enMessages` directly in feature code; always go through `t(...)` so locale changes apply. + +## File Length Guidelines (Highlight Only) + +We track file size as a refactoring signal. When you touch or create files, highlight oversized files so the team can plan refactors when time permits. + +- Source files: warn after ~500 lines; target limit ~800 lines +- Test files: highlight after ~1000 lines + +Behavior for agents: +- Do not refactor solely to satisfy these thresholds. +- When a change touches a file that exceeds the warning/limit, mention it in your final response and include the file path and approximate line count. +- When creating new files, aim to stay under the thresholds unless there's a clear reason. + ## Tooling Preferences - Use the `edit` tool for modifying existing files; prefer it over other editing methods. - Use the `write` tool only when creating new files from scratch. diff --git a/README.md b/README.md index 71798d16..44715396 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@ CodeNomad is built for people who live inside OpenCode for hours on end and need a cockpit, not a kiosk. It delivers a premium, low-latency workspace that favors speed, clarity, and direct control. +> [!IMPORTANT] +> **This is a fork of the original [shantur/CodeNomad](https://github.com/shantur/CodeNomad) repository.** This fork includes enhancements from PRs that diverge from the upstream main branch. These changes are included in all builds generated from this repository. + ![Multi-instance workspace](docs/screenshots/newSession.png) _Manage multiple OpenCode sessions side-by-side._ @@ -26,31 +29,37 @@ _Browser support via CodeNomad Server._ Choose the way that fits your workflow: ### 🖥️ Desktop App (Recommended) + The best experience. A native application (Electron-based) with global shortcuts, deeper system integration, and a dedicated window. - **Download**: Grab the latest installer for macOS, Windows, or Linux from the [Releases Page](https://github.com/shantur/CodeNomad/releases). - **Run**: Install and launch like any other app. ### 🦀 Tauri App (Experimental) + We are also working on a lightweight, high-performance version built with [Tauri](https://tauri.app). It is currently in active development. - **Download**: Experimental builds are available on the [Releases Page](https://github.com/shantur/CodeNomad/releases). - **Source**: Check out `packages/tauri-app` if you're interested in contributing. -### 💻 CodeNomad Server -Run CodeNomad as a local server and access it via your web browser. Perfect for remote development (SSH/VPN) or running as a service. +### 💻 Build from Source + +Run CodeNomad as a local server by building from source. Perfect for remote development (SSH/VPN) or running as a service. ```bash -npx @neuralnomads/codenomad --launch -``` +# Clone the repository +git clone https://github.com/bizzkoot/CodeNomad.git +cd CodeNomad -For dev version +# Install dependencies +npm install --workspaces -```bash -npx @neuralnomads/codenomad@dev --launch +# Build and launch the server +npm run build --workspace @neuralnomads/codenomad +npm run start --workspace @neuralnomads/codenomad ``` -This command starts the server and opens the web client in your default browser. +This will start the server and you can access it at http://localhost:3000 ## Highlights @@ -59,14 +68,94 @@ This command starts the server and opens the web client in your default browser. - **Command Palette**: A single global palette to jump tabs, launch tools, and control everything. - **Deep Task Awareness**: Monitor background tasks and child sessions without losing flow. +### ⚡ Feature Spotlight: Zero-Cost `ask_user` (MCP) + +We've replaced the standard `question` tool with a native **Model Context Protocol (MCP)** implementation called `ask_user`. + +| Feature | Legacy `question` Tool | New `ask_user` MCP Tool | +| :--------------- | :----------------------------------- | :----------------------------------- | +| **Cost** | Consumes premium requests per answer | **Zero** premium request consumption | +| **Architecture** | Remote API loop | Local IPC + MCP Server | +| **Timeout** | Short default timeout | **5-minute timeout** (configurable) | +| **UX** | Standard | Rich Markdown, Minimizable Wizard | + +> [!TIP] +> **Adjusting Timeout Duration** +> You can configure the `ask_user` timeout in the **Advanced Settings** menu found on the start screen (before opening a project). +> +> 1. Launch CodeNomad. +> 2. On the welcome screen, click **Advanced Settings**. +> 3. Scroll to **Timeout Settings** and adjust the value (default: 300s). + +This change is critical for users on metered plans (like GitHub Copilot), effectively "unlocking" unlimited user interactions without draining quotas. + +### 🔄 Upstream/dev Sync (Since commit 444335ad) + +This fork selectively merges features from upstream while preserving fork-specific architecture. + +#### ✅ Successfully Merged (v0.10.3 line) + +| Category | Feature | Commit | +| :-- | :-- | :-- | +| **🔧 Server API** | `GET /api/workspaces/:id/git/file-original` endpoint for fetching file HEAD/staged content | infrastructure preserved | +| **🔌 API Client** | `fetchGitOriginalContent()` method for Monaco diff preparation | infrastructure preserved | +| **🛡️ Stability** | Git store optional chaining safety fix | `755b768` | +| **🛡️ Stability** | Permission/Question block null checks | `permission-block.tsx`, `question-block.tsx` | +| **🛡️ Stability** | "Object has been destroyed" Electron crash fix | `13edfa4` | +| **⚡ Platform** | Power save blocker wake lock during busy instances | `3393911` | +| **🎨 UI Polish** | Sticky header background for bash tool output | `d8b018a` | +| **🎨 UI Polish** | Diff syntax highlighting for code blocks | `a06aa01` | +| **🔧 DevEx** | Electron dev startup CLI detection and URL swap fixes | `5f113c3` | +| **📦 Release** | Version bump to 0.10.3 | `11deb19` | + +#### ⏸️ Deferred to Custom Implementation + +These features require architectural alignment with fork patterns and are documented in PR.md: + +| Category | Upstream Feature | Status | +| :-- | :-- | :-- | +| **🧭 Right Panel & Session Changes** | Changes/Status tabs with session diff hydration | Use existing RightPanel tabs | +| **🧩 Monaco Diff/File Viewers** | Monaco-powered changes/files viewers in SourceControlPanel | Infrastructure ready; custom UI needed | +| **🌳 Worktrees & Git UX** | Worktree file browser in SourceControlPanel | Infrastructure ready; custom UI needed | +| **🎨 Theme & UI Polish** | System/light/dark theme toggle | Fork uses different theme system | +| **⌨️ Prompt & Message UX** | Enter-to-submit toggle, message-part delete | Preserved in fork-specific implementation | + +> **Note**: The server infrastructure for Monaco diff and worktrees is preserved (API endpoints and client methods). Custom UI implementation can leverage these when architecturally aligned. + ## Requirements - **[OpenCode CLI](https://opencode.ai)**: Must be installed and available in your `PATH`. - **Node.js 18+**: Required if running the CLI server or building from source. +## Enhanced Features (Fork-Specific) + +This fork includes several major enhancements not available in the upstream repository: + +| Feature | Key Capabilities | +| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **🎯 Native MCP** | • **Zero-Cost Interactions**: No premium usage for questions
• **Reliability**: 5-minute timeout with auto-retry logic
• **Rich UI**: Minimizable markdown wizard & mobile optimization | +| **📂 Source Control** | • **Git Integration**: Built-in status, diff viewer, and branch management
• **Smart Previews**: View untracked files with binary detection
• **Actions**: Publish branches and delete files directly | +| **🔔 Notifications** | • **Persistent**: Error banner for timed-out questions/tasks
• **Recovery**: One-click retry without losing context
• **Rich Details**: Markdown-rendered failed question panel
• **State**: Notifications persist across restarts | +| **🔍 Chat Search** | • **Deep Search**: Query entire history with debounced input
• **Visual**: Result highlighting and auto-expansion of collapsed blocks | +| **🌳 Folder Tree** | • **Navigation**: VSCode-style file explorer for workspaces
• **Preview**: Instant GitHub-style markdown rendering | +| **📝 Enhanced Input** | • **Editor**: Expandable multi-line chat input
• **Smart Attachments**: Tab-key file selection & auto-collapse | +| **🎨 Polish & Perf** | • **Visual**: Seamless dark mode, improved split-view diffs
• **Speed**: 10x faster dev icon loading via Vite optimization | + +> [!NOTE] +> These features are not included in upstream and represent divergent functionality from the original CodeNomad repository. + +_Last updated: 2026-02-15_ + +## CI/CD on Forks + +Since this repository uses GitHub Actions for automated releases, forks may encounter failures in the `release-ui` and `publish-server` jobs due to missing secrets (`CLOUDFLARE_API_TOKEN`, `NPM_TOKEN`) or version conflicts. + +To prevent these failures, the workflows are configured to **skip** these specific jobs unless running on the upstream repository or if explicitly enabled. The `build-and-upload` job (which generates the release binaries) will still run and attach artifacts to the GitHub Release on your fork. + ## Troubleshooting ### macOS says the app is damaged + If macOS reports that "CodeNomad.app is damaged and can't be opened," Gatekeeper flagged the download because the app is not yet notarized. You can clear the quarantine flag after moving CodeNomad into `/Applications`: ```bash @@ -77,6 +166,7 @@ xattr -dr com.apple.quarantine /Applications/CodeNomad.app After removing the quarantine attribute, launch the app normally. On Intel Macs you may also need to approve CodeNomad from **System Settings → Privacy & Security** the first time you run it. ### Linux (Wayland + NVIDIA): Tauri AppImage closes immediately + On some Wayland compositor + NVIDIA driver setups, WebKitGTK can fail to initialize its DMA-BUF/GBM path and the Tauri build may exit right away. Try running with one of these environment variables: @@ -103,13 +193,14 @@ Upstream tracking: https://github.com/tauri-apps/tauri/issues/10702 CodeNomad is a monorepo split into specialized packages. If you want to contribute or build from source, check out the individual package documentation: -| Package | Description | -|---------|-------------| -| **[packages/electron-app](packages/electron-app/README.md)** | The native desktop application shell. Wraps the UI and Server. | -| **[packages/server](packages/server/README.md)** | The core logic and CLI. Manages workspaces, proxies OpenCode, and serves the API. | -| **[packages/ui](packages/ui/README.md)** | The SolidJS-based frontend. Fast, reactive, and beautiful. | +| Package | Description | +| ------------------------------------------------------------ | --------------------------------------------------------------------------------- | +| **[packages/electron-app](packages/electron-app/README.md)** | The native desktop application shell. Wraps the UI and Server. | +| **[packages/server](packages/server/README.md)** | The core logic and CLI. Manages workspaces, proxies OpenCode, and serves the API. | +| **[packages/ui](packages/ui/README.md)** | The SolidJS-based frontend. Fast, reactive, and beautiful. | ### Quick Build + To build the Desktop App from source: 1. Clone the repo. diff --git a/bun.lock b/bun.lock new file mode 100644 index 00000000..dbee93bc --- /dev/null +++ b/bun.lock @@ -0,0 +1,2356 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "codenomad-workspace", + "dependencies": { + "7zip-bin": "^5.2.0", + "google-auth-library": "^10.5.0", + }, + "devDependencies": { + "@eslint/js": "^9.39.2", + "baseline-browser-mapping": "^2.9.11", + "eslint": "^9.39.2", + "eslint-plugin-solid": "^0.14.5", + "globals": "^17.3.0", + "typescript": "^5.9.3", + "typescript-eslint": "^8.54.0", + }, + }, + "packages/electron-app": { + "name": "@neuralnomads/codenomad-electron-app", + "version": "0.9.2-patch.4", + "dependencies": { + "@codenomad/mcp-server": "file:../mcp-server", + "@codenomad/ui": "file:../ui", + "@develar/schema-utils": "^2.6.5", + "@fastify/reply-from": "12.5.0", + "@neuralnomads/codenomad": "file:../server", + "@types/dompurify": "^3.0.5", + "dompurify": "^3.3.1", + "dotenv": "^9.0.2", + "sax": "^1.4.4", + "ts-node": "1.7.1", + }, + "devDependencies": { + "7zip-bin": "^5.2.0", + "app-builder-bin": "^4.2.0", + "electron": "39.0.0", + "electron-builder": "^26.4.0", + "electron-vite": "4.0.1", + "png2icons": "^2.0.1", + "pngjs": "^7.0.0", + "tsx": "^4.20.6", + "typescript": "^5.3.0", + "vite": "^7.3.1", + "vite-plugin-solid": "^2.10.0", + }, + }, + "packages/mcp-server": { + "name": "@codenomad/mcp-server", + "version": "0.1.0", + "dependencies": { + "zod": "^3.25.76", + }, + "devDependencies": { + "typescript": "^5.3.0", + }, + }, + "packages/server": { + "name": "@neuralnomads/codenomad", + "version": "0.9.2-patch.4", + "bin": { + "codenomad": "dist/bin.js", + }, + "dependencies": { + "@fastify/cors": "^8.5.0", + "@fastify/reply-from": "^9.8.0", + "@fastify/static": "^7.0.4", + "@modelcontextprotocol/sdk": "^1.25.2", + "commander": "^12.1.0", + "fastify": "^4.28.1", + "fuzzysort": "^2.0.4", + "pino": "^9.4.0", + "undici": "^6.19.8", + "yauzl": "^2.10.0", + "zod": "^3.23.8", + }, + "devDependencies": { + "@types/yauzl": "^2.10.0", + "cross-env": "^7.0.3", + "esbuild": "^0.25.12", + "ts-node": "^1.7.1", + "tsx": "^4.20.6", + "typescript": "^5.6.3", + }, + }, + "packages/tauri-app": { + "name": "@codenomad/tauri-app", + "version": "0.9.2", + "devDependencies": { + "@tauri-apps/cli": "^2.9.4", + }, + }, + "packages/ui": { + "name": "@codenomad/ui", + "version": "0.9.2-patch.4", + "dependencies": { + "@fastify/reply-from": "12.5.0", + "@git-diff-view/solid": "^0.0.8", + "@kobalte/core": "0.13.11", + "@opencode-ai/sdk": "1.1.11", + "@solidjs/router": "^0.13.0", + "@suid/icons-material": "^0.9.0", + "@suid/material": "^0.19.0", + "@suid/system": "^0.14.0", + "@types/dompurify": "^3.0.5", + "ansi-sequence-parser": "^1.1.3", + "debug": "^4.4.3", + "dompurify": "^3.3.1", + "github-markdown-css": "^5.8.1", + "lucide-solid": "^0.300.0", + "marked": "^12.0.0", + "qrcode": "^1.5.3", + "shiki": "^3.13.0", + "solid-js": "^1.8.0", + "solid-toast": "^0.5.0", + "ts-node": "1.7.1", + }, + "devDependencies": { + "autoprefixer": "10.4.21", + "jsdom": "^25.0.1", + "postcss": "8.5.6", + "tailwindcss": "3", + "typescript": "^5.3.0", + "vite": "^7.3.1", + "vite-plugin-solid": "^2.10.0", + "vitest": "^2.1.9", + }, + }, + }, + "packages": { + "7zip-bin": ["7zip-bin@5.2.0", "https://registry.npmmirror.com/7zip-bin/-/7zip-bin-5.2.0.tgz", {}, "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A=="], + + "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "https://registry.npmmirror.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], + + "@asamuzakjp/css-color": ["@asamuzakjp/css-color@3.2.0", "https://registry.npmmirror.com/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", { "dependencies": { "@csstools/css-calc": "^2.1.3", "@csstools/css-color-parser": "^3.0.9", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" } }, "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw=="], + + "@babel/code-frame": ["@babel/code-frame@7.29.0", "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.29.0.tgz", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], + + "@babel/compat-data": ["@babel/compat-data@7.29.0", "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.29.0.tgz", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="], + + "@babel/core": ["@babel/core@7.29.0", "https://registry.npmmirror.com/@babel/core/-/core-7.29.0.tgz", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="], + + "@babel/generator": ["@babel/generator@7.29.1", "https://registry.npmmirror.com/@babel/generator/-/generator-7.29.1.tgz", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="], + + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="], + + "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], + + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="], + + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="], + + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.28.6", "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", {}, "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], + + "@babel/helpers": ["@babel/helpers@7.28.6", "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.28.6.tgz", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="], + + "@babel/parser": ["@babel/parser@7.29.0", "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.0.tgz", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], + + "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.28.6", "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w=="], + + "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="], + + "@babel/template": ["@babel/template@7.28.6", "https://registry.npmmirror.com/@babel/template/-/template-7.28.6.tgz", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="], + + "@babel/traverse": ["@babel/traverse@7.29.0", "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.29.0.tgz", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="], + + "@babel/types": ["@babel/types@7.29.0", "https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + + "@codenomad/mcp-server": ["@codenomad/mcp-server@workspace:packages/mcp-server"], + + "@codenomad/tauri-app": ["@codenomad/tauri-app@workspace:packages/tauri-app"], + + "@codenomad/ui": ["@codenomad/ui@workspace:packages/ui"], + + "@corvu/utils": ["@corvu/utils@0.4.2", "https://registry.npmmirror.com/@corvu/utils/-/utils-0.4.2.tgz", { "dependencies": { "@floating-ui/dom": "^1.6.11" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-Ox2kYyxy7NoXdKWdHeDEjZxClwzO4SKM8plAaVwmAJPxHMqA0rLOoAsa+hBDwRLpctf+ZRnAd/ykguuJidnaTA=="], + + "@csstools/color-helpers": ["@csstools/color-helpers@5.1.0", "https://registry.npmmirror.com/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", {}, "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA=="], + + "@csstools/css-calc": ["@csstools/css-calc@2.1.4", "https://registry.npmmirror.com/@csstools/css-calc/-/css-calc-2.1.4.tgz", { "peerDependencies": { "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4" } }, "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ=="], + + "@csstools/css-color-parser": ["@csstools/css-color-parser@3.1.0", "https://registry.npmmirror.com/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", { "dependencies": { "@csstools/color-helpers": "^5.1.0", "@csstools/css-calc": "^2.1.4" }, "peerDependencies": { "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4" } }, "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA=="], + + "@csstools/css-parser-algorithms": ["@csstools/css-parser-algorithms@3.0.5", "https://registry.npmmirror.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", { "peerDependencies": { "@csstools/css-tokenizer": "^3.0.4" } }, "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ=="], + + "@csstools/css-tokenizer": ["@csstools/css-tokenizer@3.0.4", "https://registry.npmmirror.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", {}, "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw=="], + + "@develar/schema-utils": ["@develar/schema-utils@2.6.5", "https://registry.npmmirror.com/@develar/schema-utils/-/schema-utils-2.6.5.tgz", { "dependencies": { "ajv": "^6.12.0", "ajv-keywords": "^3.4.1" } }, "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig=="], + + "@electron/asar": ["@electron/asar@3.4.1", "https://registry.npmmirror.com/@electron/asar/-/asar-3.4.1.tgz", { "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", "minimatch": "^3.0.4" }, "bin": { "asar": "bin/asar.js" } }, "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA=="], + + "@electron/fuses": ["@electron/fuses@1.8.0", "https://registry.npmmirror.com/@electron/fuses/-/fuses-1.8.0.tgz", { "dependencies": { "chalk": "^4.1.1", "fs-extra": "^9.0.1", "minimist": "^1.2.5" }, "bin": { "electron-fuses": "dist/bin.js" } }, "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw=="], + + "@electron/get": ["@electron/get@2.0.3", "https://registry.npmmirror.com/@electron/get/-/get-2.0.3.tgz", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], + + "@electron/notarize": ["@electron/notarize@2.5.0", "https://registry.npmmirror.com/@electron/notarize/-/notarize-2.5.0.tgz", { "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.1", "promise-retry": "^2.0.1" } }, "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A=="], + + "@electron/osx-sign": ["@electron/osx-sign@1.3.3", "https://registry.npmmirror.com/@electron/osx-sign/-/osx-sign-1.3.3.tgz", { "dependencies": { "compare-version": "^0.1.2", "debug": "^4.3.4", "fs-extra": "^10.0.0", "isbinaryfile": "^4.0.8", "minimist": "^1.2.6", "plist": "^3.0.5" }, "bin": { "electron-osx-flat": "bin/electron-osx-flat.js", "electron-osx-sign": "bin/electron-osx-sign.js" } }, "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg=="], + + "@electron/rebuild": ["@electron/rebuild@4.0.3", "https://registry.npmmirror.com/@electron/rebuild/-/rebuild-4.0.3.tgz", { "dependencies": { "@malept/cross-spawn-promise": "^2.0.0", "debug": "^4.1.1", "detect-libc": "^2.0.1", "got": "^11.7.0", "graceful-fs": "^4.2.11", "node-abi": "^4.2.0", "node-api-version": "^0.2.1", "node-gyp": "^11.2.0", "ora": "^5.1.0", "read-binary-file-arch": "^1.0.6", "semver": "^7.3.5", "tar": "^7.5.6", "yargs": "^17.0.1" }, "bin": { "electron-rebuild": "lib/cli.js" } }, "sha512-u9vpTHRMkOYCs/1FLiSVAFZ7FbjsXK+bQuzviJZa+lG7BHZl1nz52/IcGvwa3sk80/fc3llutBkbCq10Vh8WQA=="], + + "@electron/universal": ["@electron/universal@2.0.3", "https://registry.npmmirror.com/@electron/universal/-/universal-2.0.3.tgz", { "dependencies": { "@electron/asar": "^3.3.1", "@malept/cross-spawn-promise": "^2.0.0", "debug": "^4.3.1", "dir-compare": "^4.2.0", "fs-extra": "^11.1.1", "minimatch": "^9.0.3", "plist": "^3.1.0" } }, "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g=="], + + "@electron/windows-sign": ["@electron/windows-sign@1.2.2", "https://registry.npmmirror.com/@electron/windows-sign/-/windows-sign-1.2.2.tgz", { "dependencies": { "cross-dirname": "^0.1.0", "debug": "^4.3.4", "fs-extra": "^11.1.1", "minimist": "^1.2.8", "postject": "^1.0.0-alpha.6" }, "bin": { "electron-windows-sign": "bin/electron-windows-sign.js" } }, "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.12.tgz", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.12.tgz", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + + "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="], + + "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="], + + "@eslint/config-array": ["@eslint/config-array@0.21.1", "https://registry.npmmirror.com/@eslint/config-array/-/config-array-0.21.1.tgz", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA=="], + + "@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "https://registry.npmmirror.com/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="], + + "@eslint/core": ["@eslint/core@0.17.0", "https://registry.npmmirror.com/@eslint/core/-/core-0.17.0.tgz", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="], + + "@eslint/eslintrc": ["@eslint/eslintrc@3.3.3", "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ=="], + + "@eslint/js": ["@eslint/js@9.39.2", "https://registry.npmmirror.com/@eslint/js/-/js-9.39.2.tgz", {}, "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA=="], + + "@eslint/object-schema": ["@eslint/object-schema@2.1.7", "https://registry.npmmirror.com/@eslint/object-schema/-/object-schema-2.1.7.tgz", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="], + + "@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "https://registry.npmmirror.com/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="], + + "@fastify/accept-negotiator": ["@fastify/accept-negotiator@1.1.0", "https://registry.npmmirror.com/@fastify/accept-negotiator/-/accept-negotiator-1.1.0.tgz", {}, "sha512-OIHZrb2ImZ7XG85HXOONLcJWGosv7sIvM2ifAPQVhg9Lv7qdmMBNVaai4QTdyuaqbKM5eO6sLSQOYI7wEQeCJQ=="], + + "@fastify/ajv-compiler": ["@fastify/ajv-compiler@3.6.0", "https://registry.npmmirror.com/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz", { "dependencies": { "ajv": "^8.11.0", "ajv-formats": "^2.1.1", "fast-uri": "^2.0.0" } }, "sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ=="], + + "@fastify/busboy": ["@fastify/busboy@2.1.1", "https://registry.npmmirror.com/@fastify/busboy/-/busboy-2.1.1.tgz", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="], + + "@fastify/cors": ["@fastify/cors@8.5.0", "https://registry.npmmirror.com/@fastify/cors/-/cors-8.5.0.tgz", { "dependencies": { "fastify-plugin": "^4.0.0", "mnemonist": "0.39.6" } }, "sha512-/oZ1QSb02XjP0IK1U0IXktEsw/dUBTxJOW7IpIeO8c/tNalw/KjoNSJv1Sf6eqoBPO+TDGkifq6ynFK3v68HFQ=="], + + "@fastify/error": ["@fastify/error@4.2.0", "https://registry.npmmirror.com/@fastify/error/-/error-4.2.0.tgz", {}, "sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ=="], + + "@fastify/fast-json-stringify-compiler": ["@fastify/fast-json-stringify-compiler@4.3.0", "https://registry.npmmirror.com/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", { "dependencies": { "fast-json-stringify": "^5.7.0" } }, "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA=="], + + "@fastify/merge-json-schemas": ["@fastify/merge-json-schemas@0.1.1", "https://registry.npmmirror.com/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz", { "dependencies": { "fast-deep-equal": "^3.1.3" } }, "sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA=="], + + "@fastify/reply-from": ["@fastify/reply-from@12.5.0", "https://registry.npmmirror.com/@fastify/reply-from/-/reply-from-12.5.0.tgz", { "dependencies": { "@fastify/error": "^4.0.0", "end-of-stream": "^1.4.4", "fast-content-type-parse": "^3.0.0", "fast-querystring": "^1.1.2", "fastify-plugin": "^5.0.1", "toad-cache": "^3.7.0", "undici": "^7.0.0" } }, "sha512-m7mTGjgtnpnZBk4I8r6eFJY8WB4kyvXJo2nAf5PBm5f3mj3P7G6H2D7mhmF25os/n6EGMWVyw/bpTUehvy0i8g=="], + + "@fastify/send": ["@fastify/send@2.1.0", "https://registry.npmmirror.com/@fastify/send/-/send-2.1.0.tgz", { "dependencies": { "@lukeed/ms": "^2.0.1", "escape-html": "~1.0.3", "fast-decode-uri-component": "^1.0.1", "http-errors": "2.0.0", "mime": "^3.0.0" } }, "sha512-yNYiY6sDkexoJR0D8IDy3aRP3+L4wdqCpvx5WP+VtEU58sn7USmKynBzDQex5X42Zzvw2gNzzYgP90UfWShLFA=="], + + "@fastify/static": ["@fastify/static@7.0.4", "https://registry.npmmirror.com/@fastify/static/-/static-7.0.4.tgz", { "dependencies": { "@fastify/accept-negotiator": "^1.0.0", "@fastify/send": "^2.0.0", "content-disposition": "^0.5.3", "fastify-plugin": "^4.0.0", "fastq": "^1.17.0", "glob": "^10.3.4" } }, "sha512-p2uKtaf8BMOZWLs6wu+Ihg7bWNBdjNgCwDza4MJtTqg+5ovKmcbgbR9Xs5/smZ1YISfzKOCNYmZV8LaCj+eJ1Q=="], + + "@floating-ui/core": ["@floating-ui/core@1.7.4", "https://registry.npmmirror.com/@floating-ui/core/-/core-1.7.4.tgz", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg=="], + + "@floating-ui/dom": ["@floating-ui/dom@1.7.5", "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.7.5.tgz", { "dependencies": { "@floating-ui/core": "^1.7.4", "@floating-ui/utils": "^0.2.10" } }, "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg=="], + + "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.10.tgz", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="], + + "@git-diff-view/core": ["@git-diff-view/core@0.0.35", "https://registry.npmmirror.com/@git-diff-view/core/-/core-0.0.35.tgz", { "dependencies": { "@git-diff-view/lowlight": "^0.0.35", "fast-diff": "^1.3.0", "highlight.js": "^11.11.0", "lowlight": "^3.3.0" } }, "sha512-cdH3BopR6AWUW+6hP78zGyryKxR9JkPgryd1JN78i5k+F9Eo4x/4S23ZF1VZnrpPlGLrSuYfiAZ0ho5m+pTuKg=="], + + "@git-diff-view/lowlight": ["@git-diff-view/lowlight@0.0.35", "https://registry.npmmirror.com/@git-diff-view/lowlight/-/lowlight-0.0.35.tgz", { "dependencies": { "@types/hast": "^3.0.0", "highlight.js": "^11.11.0", "lowlight": "^3.3.0" } }, "sha512-MVpOxrNn1oHVOTOWUjxLbbf1W4OtVHjj6CHxwJbBRg9ZWZdShBINjuEgHVMSGB6vZuHKfwruRfXw8XxV3aF8zw=="], + + "@git-diff-view/solid": ["@git-diff-view/solid@0.0.8", "https://registry.npmmirror.com/@git-diff-view/solid/-/solid-0.0.8.tgz", { "dependencies": { "@git-diff-view/core": "^0.0.35", "@types/hast": "^3.0.0", "fast-diff": "^1.3.0", "highlight.js": "^11.11.0", "lowlight": "^3.3.0", "reactivity-store": "^0.3.12" }, "peerDependencies": { "solid-js": "^1.9.0" } }, "sha512-MvZpyV5Gz0Axv2vvAlPpOmHtaJRUGBMoqXmvjIdZlUls0091QsglpE8bMbdRdEHuXodzxPDYyZrx3HCniMlGKw=="], + + "@hono/node-server": ["@hono/node-server@1.19.9", "https://registry.npmmirror.com/@hono/node-server/-/node-server-1.19.9.tgz", { "peerDependencies": { "hono": "^4" } }, "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw=="], + + "@humanfs/core": ["@humanfs/core@0.19.1", "https://registry.npmmirror.com/@humanfs/core/-/core-0.19.1.tgz", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], + + "@humanfs/node": ["@humanfs/node@0.16.7", "https://registry.npmmirror.com/@humanfs/node/-/node-0.16.7.tgz", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="], + + "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], + + "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "https://registry.npmmirror.com/@humanwhocodes/retry/-/retry-0.4.3.tgz", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="], + + "@internationalized/date": ["@internationalized/date@3.11.0", "https://registry.npmmirror.com/@internationalized/date/-/date-3.11.0.tgz", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-BOx5huLAWhicM9/ZFs84CzP+V3gBW6vlpM02yzsdYC7TGlZJX1OJiEEHcSayF00Z+3jLlm4w79amvSt6RqKN3Q=="], + + "@internationalized/number": ["@internationalized/number@3.6.5", "https://registry.npmmirror.com/@internationalized/number/-/number-3.6.5.tgz", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g=="], + + "@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "https://registry.npmmirror.com/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="], + + "@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.1", "https://registry.npmmirror.com/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ=="], + + "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], + + "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "https://registry.npmmirror.com/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@kobalte/core": ["@kobalte/core@0.13.11", "https://registry.npmmirror.com/@kobalte/core/-/core-0.13.11.tgz", { "dependencies": { "@floating-ui/dom": "^1.5.1", "@internationalized/date": "^3.4.0", "@internationalized/number": "^3.2.1", "@kobalte/utils": "^0.9.1", "@solid-primitives/props": "^3.1.8", "@solid-primitives/resize-observer": "^2.0.26", "solid-presence": "^0.1.8", "solid-prevent-scroll": "^0.1.4" }, "peerDependencies": { "solid-js": "^1.8.15" } }, "sha512-hK7TYpdib/XDb/r/4XDBFaO9O+3ZHz4ZWryV4/3BfES+tSQVgg2IJupDnztKXB0BqbSRy/aWlHKw1SPtNPYCFQ=="], + + "@kobalte/utils": ["@kobalte/utils@0.9.1", "https://registry.npmmirror.com/@kobalte/utils/-/utils-0.9.1.tgz", { "dependencies": { "@solid-primitives/event-listener": "^2.2.14", "@solid-primitives/keyed": "^1.2.0", "@solid-primitives/map": "^0.4.7", "@solid-primitives/media": "^2.2.4", "@solid-primitives/props": "^3.1.8", "@solid-primitives/refs": "^1.0.5", "@solid-primitives/utils": "^6.2.1" }, "peerDependencies": { "solid-js": "^1.8.8" } }, "sha512-eeU60A3kprIiBDAfv9gUJX1tXGLuZiKMajUfSQURAF2pk4ZoMYiqIzmrMBvzcxP39xnYttgTyQEVLwiTZnrV4w=="], + + "@lukeed/ms": ["@lukeed/ms@2.0.2", "https://registry.npmmirror.com/@lukeed/ms/-/ms-2.0.2.tgz", {}, "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA=="], + + "@malept/cross-spawn-promise": ["@malept/cross-spawn-promise@2.0.0", "https://registry.npmmirror.com/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", { "dependencies": { "cross-spawn": "^7.0.1" } }, "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg=="], + + "@malept/flatpak-bundler": ["@malept/flatpak-bundler@0.4.0", "https://registry.npmmirror.com/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", { "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.0", "lodash": "^4.17.15", "tmp-promise": "^3.0.2" } }, "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q=="], + + "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.26.0", "https://registry.npmmirror.com/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg=="], + + "@neuralnomads/codenomad": ["@neuralnomads/codenomad@workspace:packages/server"], + + "@neuralnomads/codenomad-electron-app": ["@neuralnomads/codenomad-electron-app@workspace:packages/electron-app"], + + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], + + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + + "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + + "@npmcli/agent": ["@npmcli/agent@3.0.0", "https://registry.npmmirror.com/@npmcli/agent/-/agent-3.0.0.tgz", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q=="], + + "@npmcli/fs": ["@npmcli/fs@4.0.0", "https://registry.npmmirror.com/@npmcli/fs/-/fs-4.0.0.tgz", { "dependencies": { "semver": "^7.3.5" } }, "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q=="], + + "@opencode-ai/sdk": ["@opencode-ai/sdk@1.1.11", "https://registry.npmmirror.com/@opencode-ai/sdk/-/sdk-1.1.11.tgz", {}, "sha512-vqdNDz8Q+4bygmDdQem6oxhU31ci4JVdoND4ZJNeCs9x6OIU6MM3ybgemGpzNkgtJDlfb4xCdrPaZZ6Sr3V1IQ=="], + + "@pinojs/redact": ["@pinojs/redact@0.4.0", "https://registry.npmmirror.com/@pinojs/redact/-/redact-0.4.0.tgz", {}, "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg=="], + + "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], + + "@popperjs/core": ["@popperjs/core@2.11.8", "https://registry.npmmirror.com/@popperjs/core/-/core-2.11.8.tgz", {}, "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz", { "os": "android", "cpu": "arm" }, "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz", { "os": "android", "cpu": "arm64" }, "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz", { "os": "freebsd", "cpu": "arm64" }, "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz", { "os": "linux", "cpu": "arm" }, "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz", { "os": "linux", "cpu": "arm" }, "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz", { "os": "linux", "cpu": "none" }, "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz", { "os": "linux", "cpu": "none" }, "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz", { "os": "linux", "cpu": "none" }, "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz", { "os": "linux", "cpu": "none" }, "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz", { "os": "linux", "cpu": "x64" }, "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz", { "os": "linux", "cpu": "x64" }, "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz", { "os": "openbsd", "cpu": "x64" }, "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz", { "os": "none", "cpu": "arm64" }, "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz", { "os": "win32", "cpu": "x64" }, "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.57.1", "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz", { "os": "win32", "cpu": "x64" }, "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA=="], + + "@shikijs/core": ["@shikijs/core@3.22.0", "https://registry.npmmirror.com/@shikijs/core/-/core-3.22.0.tgz", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA=="], + + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.22.0", "https://registry.npmmirror.com/@shikijs/engine-javascript/-/engine-javascript-3.22.0.tgz", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw=="], + + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.22.0", "https://registry.npmmirror.com/@shikijs/engine-oniguruma/-/engine-oniguruma-3.22.0.tgz", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA=="], + + "@shikijs/langs": ["@shikijs/langs@3.22.0", "https://registry.npmmirror.com/@shikijs/langs/-/langs-3.22.0.tgz", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA=="], + + "@shikijs/themes": ["@shikijs/themes@3.22.0", "https://registry.npmmirror.com/@shikijs/themes/-/themes-3.22.0.tgz", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g=="], + + "@shikijs/types": ["@shikijs/types@3.22.0", "https://registry.npmmirror.com/@shikijs/types/-/types-3.22.0.tgz", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg=="], + + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "https://registry.npmmirror.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], + + "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "https://registry.npmmirror.com/@sindresorhus/is/-/is-4.6.0.tgz", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], + + "@solid-primitives/event-listener": ["@solid-primitives/event-listener@2.4.3", "https://registry.npmmirror.com/@solid-primitives/event-listener/-/event-listener-2.4.3.tgz", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg=="], + + "@solid-primitives/keyed": ["@solid-primitives/keyed@1.5.3", "https://registry.npmmirror.com/@solid-primitives/keyed/-/keyed-1.5.3.tgz", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-zNadtyYBhJSOjXtogkGHmRxjGdz9KHc8sGGVAGlUABkE8BED2tbIZoxkwSqzOwde8OcUEH0bb5DLZUWIMvyBSA=="], + + "@solid-primitives/map": ["@solid-primitives/map@0.4.13", "https://registry.npmmirror.com/@solid-primitives/map/-/map-0.4.13.tgz", { "dependencies": { "@solid-primitives/trigger": "^1.1.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-B1zyFbsiTQvqPr+cuPCXO72sRuczG9Swncqk5P74NCGw1VE8qa/Ry9GlfI1e/VdeQYHjan+XkbE3rO2GW/qKew=="], + + "@solid-primitives/media": ["@solid-primitives/media@2.3.3", "https://registry.npmmirror.com/@solid-primitives/media/-/media-2.3.3.tgz", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/rootless": "^1.5.2", "@solid-primitives/static-store": "^0.1.2", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-hQ4hLOGvfbugQi5Eu1BFWAIJGIAzztq9x0h02xgBGl2l0Jaa3h7tg6bz5tV1NSuNYVGio4rPoa7zVQQLkkx9dA=="], + + "@solid-primitives/props": ["@solid-primitives/props@3.2.2", "https://registry.npmmirror.com/@solid-primitives/props/-/props-3.2.2.tgz", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-lZOTwFJajBrshSyg14nBMEP0h8MXzPowGO0s3OeiR3z6nXHTfj0FhzDtJMv+VYoRJKQHG2QRnJTgCzK6erARAw=="], + + "@solid-primitives/refs": ["@solid-primitives/refs@1.1.2", "https://registry.npmmirror.com/@solid-primitives/refs/-/refs-1.1.2.tgz", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-K7tf2thy7L+YJjdqXspXOg5xvNEOH8tgEWsp0+1mQk3obHBRD6hEjYZk7p7FlJphSZImS35je3UfmWuD7MhDfg=="], + + "@solid-primitives/resize-observer": ["@solid-primitives/resize-observer@2.1.3", "https://registry.npmmirror.com/@solid-primitives/resize-observer/-/resize-observer-2.1.3.tgz", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/rootless": "^1.5.2", "@solid-primitives/static-store": "^0.1.2", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ=="], + + "@solid-primitives/rootless": ["@solid-primitives/rootless@1.5.2", "https://registry.npmmirror.com/@solid-primitives/rootless/-/rootless-1.5.2.tgz", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-9HULb0QAzL2r47CCad0M+NKFtQ+LrGGNHZfteX/ThdGvKIg2o2GYhBooZubTCd/RTu2l2+Nw4s+dEfiDGvdrrQ=="], + + "@solid-primitives/static-store": ["@solid-primitives/static-store@0.1.2", "https://registry.npmmirror.com/@solid-primitives/static-store/-/static-store-0.1.2.tgz", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw=="], + + "@solid-primitives/trigger": ["@solid-primitives/trigger@1.2.2", "https://registry.npmmirror.com/@solid-primitives/trigger/-/trigger-1.2.2.tgz", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-IWoptVc0SWYgmpBPpCMehS5b07+tpFcvw15tOQ3QbXedSYn6KP8zCjPkHNzMxcOvOicTneleeZDP7lqmz+PQ6g=="], + + "@solid-primitives/utils": ["@solid-primitives/utils@6.3.2", "https://registry.npmmirror.com/@solid-primitives/utils/-/utils-6.3.2.tgz", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ=="], + + "@solidjs/router": ["@solidjs/router@0.13.6", "https://registry.npmmirror.com/@solidjs/router/-/router-0.13.6.tgz", { "peerDependencies": { "solid-js": "^1.8.6" } }, "sha512-CdpFsBYoiJ/FQ4wZIamj3KEFRkmrYu5sVXM6PouNkmSENta1YJamsm9wa/VjaPmkw2RsnDnO0UvZ705v6EgOXQ=="], + + "@suid/base": ["@suid/base@0.11.0", "https://registry.npmmirror.com/@suid/base/-/base-0.11.0.tgz", { "dependencies": { "@popperjs/core": "^2.11.8", "@suid/css": "0.4.1", "@suid/system": "0.14.0", "@suid/types": "0.8.0", "@suid/utils": "0.11.0", "clsx": "^2.1.1" }, "peerDependencies": { "solid-js": "^1.9.7" } }, "sha512-jNe+LlXuxfkSZo8/MP9koqYYWswucDWSCwc7ViqUhQ0Y/V7sP2RiQ/Bnms+ePSMBZsk5k1b9fAjvj7DtNbbHXw=="], + + "@suid/css": ["@suid/css@0.4.1", "https://registry.npmmirror.com/@suid/css/-/css-0.4.1.tgz", {}, "sha512-Hsi4O3dBOm7rrlqKoWfNoTeRFAXm/7TPaeEmyxNx+wFaT3eROjMVdhadAIiagFT+PsHrq/6fDauUI5TkL+5Zvg=="], + + "@suid/icons-material": ["@suid/icons-material@0.9.0", "https://registry.npmmirror.com/@suid/icons-material/-/icons-material-0.9.0.tgz", { "dependencies": { "@suid/material": "0.19.0" }, "peerDependencies": { "solid-js": "^1.9.7" } }, "sha512-2idgaT/JARd12dwDfocZBQizaiZVgR0ujRsVc61OlAuPZbeH+3TrSxUJkE3Z7+TPftw9+6p0A24GhJjJLvi6RQ=="], + + "@suid/material": ["@suid/material@0.19.0", "https://registry.npmmirror.com/@suid/material/-/material-0.19.0.tgz", { "dependencies": { "@suid/base": "0.11.0", "@suid/css": "0.4.1", "@suid/system": "0.14.0", "@suid/types": "0.8.0", "@suid/utils": "0.11.0", "clsx": "^2.1.1" }, "peerDependencies": { "solid-js": "^1.9.7" } }, "sha512-vfudxYpHdur5CWTjd3eBb7q1b6A9X/pDWTEf2twc0gXVTcErS9VtY/VPBLa65AzO2SPJsdjAE+BCdVZiXASBbA=="], + + "@suid/styled-engine": ["@suid/styled-engine@0.9.0", "https://registry.npmmirror.com/@suid/styled-engine/-/styled-engine-0.9.0.tgz", { "dependencies": { "@suid/css": "0.4.1", "@suid/utils": "0.11.0" }, "peerDependencies": { "solid-js": "^1.9.7" } }, "sha512-IfNHjQ3Im63mFIjFl/doiwdn5qbwgcwi/vUXnX7dmIUC/Cw1f3LPhzVT9V8Z3eqyvvFToy53O+BsuLy2e/WmDw=="], + + "@suid/system": ["@suid/system@0.14.0", "https://registry.npmmirror.com/@suid/system/-/system-0.14.0.tgz", { "dependencies": { "@suid/css": "0.4.1", "@suid/styled-engine": "0.9.0", "@suid/types": "0.8.0", "@suid/utils": "0.11.0", "clsx": "^2.1.1", "csstype": "^3.1.3" }, "peerDependencies": { "solid-js": "^1.9.7" } }, "sha512-aRVilPP53hHkqyAyQp2pasT/u8aQCcELwU4kFDnt3b+rj4fsPQRlhMumlX5mZ5aijIboH1CngU6TDG6Z9Mr3UA=="], + + "@suid/types": ["@suid/types@0.8.0", "https://registry.npmmirror.com/@suid/types/-/types-0.8.0.tgz", { "peerDependencies": { "solid-js": "^1.9.7" } }, "sha512-/Z2abkbypMjF6ygSpnjqnWohcmPqvgw8Xpx1wPPHeh+LajBP2imNT6uEa5dBqNEkJY8O3wEUCVqErAad/rmn5Q=="], + + "@suid/utils": ["@suid/utils@0.11.0", "https://registry.npmmirror.com/@suid/utils/-/utils-0.11.0.tgz", { "dependencies": { "@suid/types": "0.8.0" }, "peerDependencies": { "solid-js": "^1.9.7" } }, "sha512-dk+6YJkex9kcU2qQHCOk8J0/zkOKKbng0SsjC0LBLyBrf2OC3OtDQq7o22pH3m/8CU/0M6uyM7tnyzZA4eWF3Q=="], + + "@swc/helpers": ["@swc/helpers@0.5.18", "https://registry.npmmirror.com/@swc/helpers/-/helpers-0.5.18.tgz", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ=="], + + "@szmarczak/http-timer": ["@szmarczak/http-timer@4.0.6", "https://registry.npmmirror.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", { "dependencies": { "defer-to-connect": "^2.0.0" } }, "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w=="], + + "@tauri-apps/cli": ["@tauri-apps/cli@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli/-/cli-2.10.0.tgz", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.10.0", "@tauri-apps/cli-darwin-x64": "2.10.0", "@tauri-apps/cli-linux-arm-gnueabihf": "2.10.0", "@tauri-apps/cli-linux-arm64-gnu": "2.10.0", "@tauri-apps/cli-linux-arm64-musl": "2.10.0", "@tauri-apps/cli-linux-riscv64-gnu": "2.10.0", "@tauri-apps/cli-linux-x64-gnu": "2.10.0", "@tauri-apps/cli-linux-x64-musl": "2.10.0", "@tauri-apps/cli-win32-arm64-msvc": "2.10.0", "@tauri-apps/cli-win32-ia32-msvc": "2.10.0", "@tauri-apps/cli-win32-x64-msvc": "2.10.0" }, "bin": { "tauri": "tauri.js" } }, "sha512-ZwT0T+7bw4+DPCSWzmviwq5XbXlM0cNoleDKOYPFYqcZqeKY31KlpoMW/MOON/tOFBPgi31a2v3w9gliqwL2+Q=="], + + "@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.10.0.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-avqHD4HRjrMamE/7R/kzJPcAJnZs0IIS+1nkDP5b+TNBn3py7N2aIo9LIpy+VQq0AkN8G5dDpZtOOBkmWt/zjA=="], + + "@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.10.0.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-keDmlvJRStzVFjZTd0xYkBONLtgBC9eMTpmXnBXzsHuawV2q9PvDo2x6D5mhuoMVrJ9QWjgaPKBBCFks4dK71Q=="], + + "@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.10.0.tgz", { "os": "linux", "cpu": "arm" }, "sha512-e5u0VfLZsMAC9iHaOEANumgl6lfnJx0Dtjkd8IJpysZ8jp0tJ6wrIkto2OzQgzcYyRCKgX72aKE0PFgZputA8g=="], + + "@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.10.0.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-YrYYk2dfmBs5m+OIMCrb+JH/oo+4FtlpcrTCgiFYc7vcs6m3QDd1TTyWu0u01ewsCtK2kOdluhr/zKku+KP7HA=="], + + "@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.10.0.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-GUoPdVJmrJRIXFfW3Rkt+eGK9ygOdyISACZfC/bCSfOnGt8kNdQIQr5WRH9QUaTVFIwxMlQyV3m+yXYP+xhSVA=="], + + "@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.10.0.tgz", { "os": "linux", "cpu": "none" }, "sha512-JO7s3TlSxshwsoKNCDkyvsx5gw2QAs/Y2GbR5UE2d5kkU138ATKoPOtxn8G1fFT1aDW4LH0rYAAfBpGkDyJJnw=="], + + "@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.10.0.tgz", { "os": "linux", "cpu": "x64" }, "sha512-Uvh4SUUp4A6DVRSMWjelww0GnZI3PlVy7VS+DRF5napKuIehVjGl9XD0uKoCoxwAQBLctvipyEK+pDXpJeoHng=="], + + "@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.10.0.tgz", { "os": "linux", "cpu": "x64" }, "sha512-AP0KRK6bJuTpQ8kMNWvhIpKUkQJfcPFeba7QshOQZjJ8wOS6emwTN4K5g/d3AbCMo0RRdnZWwu67MlmtJyxC1Q=="], + + "@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.10.0.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-97DXVU3dJystrq7W41IX+82JEorLNY+3+ECYxvXWqkq7DBN6FsA08x/EFGE8N/b0LTOui9X2dvpGGoeZKKV08g=="], + + "@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.10.0.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-EHyQ1iwrWy1CwMalEm9z2a6L5isQ121pe7FcA2xe4VWMJp+GHSDDGvbTv/OPdkt2Lyr7DAZBpZHM6nvlHXEc4A=="], + + "@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.10.0", "https://registry.npmmirror.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.10.0.tgz", { "os": "win32", "cpu": "x64" }, "sha512-NTpyQxkpzGmU6ceWBTY2xRIEaS0ZLbVx1HE1zTA3TY/pV3+cPoPPOs+7YScr4IMzXMtOw7tLw5LEXo5oIG3qaQ=="], + + "@types/babel__core": ["@types/babel__core@7.20.5", "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], + + "@types/babel__generator": ["@types/babel__generator@7.27.0", "https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.27.0.tgz", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], + + "@types/babel__template": ["@types/babel__template@7.4.4", "https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.4.tgz", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], + + "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], + + "@types/cacheable-request": ["@types/cacheable-request@6.0.3", "https://registry.npmmirror.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", { "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw=="], + + "@types/debug": ["@types/debug@4.1.12", "https://registry.npmmirror.com/@types/debug/-/debug-4.1.12.tgz", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + + "@types/dompurify": ["@types/dompurify@3.2.0", "https://registry.npmmirror.com/@types/dompurify/-/dompurify-3.2.0.tgz", { "dependencies": { "dompurify": "*" } }, "sha512-Fgg31wv9QbLDA0SpTOXO3MaxySc4DKGLi8sna4/Utjo4r3ZRPdCt4UQee8BWr+Q5z21yifghREPJGYaEOEIACg=="], + + "@types/estree": ["@types/estree@1.0.8", "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/fs-extra": ["@types/fs-extra@9.0.13", "https://registry.npmmirror.com/@types/fs-extra/-/fs-extra-9.0.13.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA=="], + + "@types/hast": ["@types/hast@3.0.4", "https://registry.npmmirror.com/@types/hast/-/hast-3.0.4.tgz", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + + "@types/http-cache-semantics": ["@types/http-cache-semantics@4.2.0", "https://registry.npmmirror.com/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", {}, "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q=="], + + "@types/json-schema": ["@types/json-schema@7.0.15", "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + + "@types/keyv": ["@types/keyv@3.1.4", "https://registry.npmmirror.com/@types/keyv/-/keyv-3.1.4.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg=="], + + "@types/mdast": ["@types/mdast@4.0.4", "https://registry.npmmirror.com/@types/mdast/-/mdast-4.0.4.tgz", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/ms": ["@types/ms@2.1.0", "https://registry.npmmirror.com/@types/ms/-/ms-2.1.0.tgz", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + + "@types/node": ["@types/node@25.2.1", "https://registry.npmmirror.com/@types/node/-/node-25.2.1.tgz", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg=="], + + "@types/plist": ["@types/plist@3.0.5", "https://registry.npmmirror.com/@types/plist/-/plist-3.0.5.tgz", { "dependencies": { "@types/node": "*", "xmlbuilder": ">=11.0.1" } }, "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA=="], + + "@types/responselike": ["@types/responselike@1.0.3", "https://registry.npmmirror.com/@types/responselike/-/responselike-1.0.3.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw=="], + + "@types/trusted-types": ["@types/trusted-types@2.0.7", "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.7.tgz", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], + + "@types/unist": ["@types/unist@3.0.3", "https://registry.npmmirror.com/@types/unist/-/unist-3.0.3.tgz", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "@types/verror": ["@types/verror@1.10.11", "https://registry.npmmirror.com/@types/verror/-/verror-1.10.11.tgz", {}, "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg=="], + + "@types/yauzl": ["@types/yauzl@2.10.3", "https://registry.npmmirror.com/@types/yauzl/-/yauzl-2.10.3.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], + + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.54.0", "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/type-utils": "8.54.0", "@typescript-eslint/utils": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.54.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ=="], + + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.54.0", "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-8.54.0.tgz", { "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA=="], + + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.54.0", "https://registry.npmmirror.com/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.54.0", "@typescript-eslint/types": "^8.54.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g=="], + + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.54.0", "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", { "dependencies": { "@typescript-eslint/types": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0" } }, "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg=="], + + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.54.0", "https://registry.npmmirror.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw=="], + + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.54.0", "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz", { "dependencies": { "@typescript-eslint/types": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0", "@typescript-eslint/utils": "8.54.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA=="], + + "@typescript-eslint/types": ["@typescript-eslint/types@8.54.0", "https://registry.npmmirror.com/@typescript-eslint/types/-/types-8.54.0.tgz", {}, "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA=="], + + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.54.0", "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", { "dependencies": { "@typescript-eslint/project-service": "8.54.0", "@typescript-eslint/tsconfig-utils": "8.54.0", "@typescript-eslint/types": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA=="], + + "@typescript-eslint/utils": ["@typescript-eslint/utils@8.54.0", "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-8.54.0.tgz", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA=="], + + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.54.0", "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", { "dependencies": { "@typescript-eslint/types": "8.54.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + + "@vitest/expect": ["@vitest/expect@2.1.9", "https://registry.npmmirror.com/@vitest/expect/-/expect-2.1.9.tgz", { "dependencies": { "@vitest/spy": "2.1.9", "@vitest/utils": "2.1.9", "chai": "^5.1.2", "tinyrainbow": "^1.2.0" } }, "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw=="], + + "@vitest/mocker": ["@vitest/mocker@2.1.9", "https://registry.npmmirror.com/@vitest/mocker/-/mocker-2.1.9.tgz", { "dependencies": { "@vitest/spy": "2.1.9", "estree-walker": "^3.0.3", "magic-string": "^0.30.12" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg=="], + + "@vitest/pretty-format": ["@vitest/pretty-format@2.1.9", "https://registry.npmmirror.com/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", { "dependencies": { "tinyrainbow": "^1.2.0" } }, "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ=="], + + "@vitest/runner": ["@vitest/runner@2.1.9", "https://registry.npmmirror.com/@vitest/runner/-/runner-2.1.9.tgz", { "dependencies": { "@vitest/utils": "2.1.9", "pathe": "^1.1.2" } }, "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g=="], + + "@vitest/snapshot": ["@vitest/snapshot@2.1.9", "https://registry.npmmirror.com/@vitest/snapshot/-/snapshot-2.1.9.tgz", { "dependencies": { "@vitest/pretty-format": "2.1.9", "magic-string": "^0.30.12", "pathe": "^1.1.2" } }, "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ=="], + + "@vitest/spy": ["@vitest/spy@2.1.9", "https://registry.npmmirror.com/@vitest/spy/-/spy-2.1.9.tgz", { "dependencies": { "tinyspy": "^3.0.2" } }, "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ=="], + + "@vitest/utils": ["@vitest/utils@2.1.9", "https://registry.npmmirror.com/@vitest/utils/-/utils-2.1.9.tgz", { "dependencies": { "@vitest/pretty-format": "2.1.9", "loupe": "^3.1.2", "tinyrainbow": "^1.2.0" } }, "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ=="], + + "@vue/reactivity": ["@vue/reactivity@3.5.27", "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.27.tgz", { "dependencies": { "@vue/shared": "3.5.27" } }, "sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ=="], + + "@vue/shared": ["@vue/shared@3.5.27", "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.27.tgz", {}, "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ=="], + + "@xmldom/xmldom": ["@xmldom/xmldom@0.8.11", "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz", {}, "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw=="], + + "abbrev": ["abbrev@3.0.1", "https://registry.npmmirror.com/abbrev/-/abbrev-3.0.1.tgz", {}, "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg=="], + + "abstract-logging": ["abstract-logging@2.0.1", "https://registry.npmmirror.com/abstract-logging/-/abstract-logging-2.0.1.tgz", {}, "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA=="], + + "accepts": ["accepts@2.0.0", "https://registry.npmmirror.com/accepts/-/accepts-2.0.0.tgz", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + + "acorn": ["acorn@8.15.0", "https://registry.npmmirror.com/acorn/-/acorn-8.15.0.tgz", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + + "acorn-jsx": ["acorn-jsx@5.3.2", "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + + "agent-base": ["agent-base@7.1.4", "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.4.tgz", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "ajv": ["ajv@6.12.6", "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], + + "ajv-formats": ["ajv-formats@3.0.1", "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-3.0.1.tgz", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], + + "ajv-keywords": ["ajv-keywords@3.5.2", "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], + + "ansi-regex": ["ansi-regex@2.1.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-2.1.1.tgz", {}, "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="], + + "ansi-sequence-parser": ["ansi-sequence-parser@1.1.3", "https://registry.npmmirror.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.3.tgz", {}, "sha512-+fksAx9eG3Ab6LDnLs3ZqZa8KVJ/jYnX+D4Qe1azX+LFGFAXqynCQLOdLpNYN/l9e7l6hMWwZbrnctqr6eSQSw=="], + + "ansi-styles": ["ansi-styles@4.3.0", "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "any-promise": ["any-promise@1.3.0", "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], + + "anymatch": ["anymatch@3.1.3", "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], + + "app-builder-bin": ["app-builder-bin@4.2.0", "https://registry.npmmirror.com/app-builder-bin/-/app-builder-bin-4.2.0.tgz", {}, "sha512-PGXlkukQnroTgAaDZnnppdLzsRJmab6Rh/rJ5fKyYaYhd+FfaORH59/ArkB5dr2cAeYQU5lCeHFEwURaoBO8BA=="], + + "app-builder-lib": ["app-builder-lib@26.7.0", "https://registry.npmmirror.com/app-builder-lib/-/app-builder-lib-26.7.0.tgz", { "dependencies": { "@develar/schema-utils": "~2.6.5", "@electron/asar": "3.4.1", "@electron/fuses": "^1.8.0", "@electron/get": "^3.0.0", "@electron/notarize": "2.5.0", "@electron/osx-sign": "1.3.3", "@electron/rebuild": "^4.0.3", "@electron/universal": "2.0.3", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", "builder-util": "26.4.1", "builder-util-runtime": "9.5.1", "chromium-pickle-js": "^0.2.0", "ci-info": "4.3.1", "debug": "^4.3.4", "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "ejs": "^3.1.8", "electron-publish": "26.6.0", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "isbinaryfile": "^5.0.0", "jiti": "^2.4.2", "js-yaml": "^4.1.0", "json5": "^2.2.3", "lazy-val": "^1.0.5", "minimatch": "^10.0.3", "plist": "3.1.0", "proper-lockfile": "^4.1.2", "resedit": "^1.7.0", "semver": "~7.7.3", "tar": "^7.5.7", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0", "which": "^5.0.0" }, "peerDependencies": { "dmg-builder": "26.7.0", "electron-builder-squirrel-windows": "26.7.0" } }, "sha512-/UgCD8VrO79Wv8aBNpjMfsS1pIUfIPURoRn0Ik6tMe5avdZF+vQgl/juJgipcMmH3YS0BD573lCdCHyoi84USg=="], + + "arg": ["arg@5.0.2", "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], + + "argparse": ["argparse@2.0.1", "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "arrify": ["arrify@1.0.1", "https://registry.npmmirror.com/arrify/-/arrify-1.0.1.tgz", {}, "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA=="], + + "assert-plus": ["assert-plus@1.0.0", "https://registry.npmmirror.com/assert-plus/-/assert-plus-1.0.0.tgz", {}, "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="], + + "assertion-error": ["assertion-error@2.0.1", "https://registry.npmmirror.com/assertion-error/-/assertion-error-2.0.1.tgz", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + + "astral-regex": ["astral-regex@2.0.0", "https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz", {}, "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="], + + "async": ["async@3.2.6", "https://registry.npmmirror.com/async/-/async-3.2.6.tgz", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], + + "async-exit-hook": ["async-exit-hook@2.0.1", "https://registry.npmmirror.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz", {}, "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw=="], + + "asynckit": ["asynckit@0.4.0", "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + + "at-least-node": ["at-least-node@1.0.0", "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz", {}, "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="], + + "atomic-sleep": ["atomic-sleep@1.0.0", "https://registry.npmmirror.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="], + + "autoprefixer": ["autoprefixer@10.4.21", "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.21.tgz", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="], + + "avvio": ["avvio@8.4.0", "https://registry.npmmirror.com/avvio/-/avvio-8.4.0.tgz", { "dependencies": { "@fastify/error": "^3.3.0", "fastq": "^1.17.1" } }, "sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA=="], + + "babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.40.3", "https://registry.npmmirror.com/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.40.3.tgz", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-5HOwwt0BYiv/zxl7j8Pf2bGL6rDXfV6nUhLs8ygBX+EFJXzBPHM/euj9j/6deMZ6wa52Wb2PBaAV5U/jKwIY1w=="], + + "babel-preset-solid": ["babel-preset-solid@1.9.10", "https://registry.npmmirror.com/babel-preset-solid/-/babel-preset-solid-1.9.10.tgz", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.40.3" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^1.9.10" }, "optionalPeers": ["solid-js"] }, "sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ=="], + + "balanced-match": ["balanced-match@1.0.2", "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "base64-js": ["base64-js@1.5.1", "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + + "baseline-browser-mapping": ["baseline-browser-mapping@2.9.19", "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg=="], + + "bignumber.js": ["bignumber.js@9.3.1", "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.3.1.tgz", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="], + + "binary-extensions": ["binary-extensions@2.3.0", "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], + + "bl": ["bl@4.1.0", "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], + + "body-parser": ["body-parser@2.2.2", "https://registry.npmmirror.com/body-parser/-/body-parser-2.2.2.tgz", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], + + "boolean": ["boolean@3.2.0", "https://registry.npmmirror.com/boolean/-/boolean-3.2.0.tgz", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="], + + "brace-expansion": ["brace-expansion@1.1.12", "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], + + "braces": ["braces@3.0.3", "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "browserslist": ["browserslist@4.28.1", "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="], + + "buffer": ["buffer@5.7.1", "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + + "buffer-crc32": ["buffer-crc32@0.2.13", "https://registry.npmmirror.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], + + "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="], + + "buffer-from": ["buffer-from@1.1.2", "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], + + "builder-util": ["builder-util@26.4.1", "https://registry.npmmirror.com/builder-util/-/builder-util-26.4.1.tgz", { "dependencies": { "7zip-bin": "~5.2.0", "@types/debug": "^4.1.6", "app-builder-bin": "5.0.0-alpha.12", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "cross-spawn": "^7.0.6", "debug": "^4.3.4", "fs-extra": "^10.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "js-yaml": "^4.1.0", "sanitize-filename": "^1.6.3", "source-map-support": "^0.5.19", "stat-mode": "^1.0.0", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0" } }, "sha512-FlgH43XZ50w3UtS1RVGDWOz8v9qMXPC7upMtKMtBEnYdt1OVoS61NYhKm/4x+cIaWqJTXua0+VVPI+fSPGXNIw=="], + + "builder-util-runtime": ["builder-util-runtime@9.5.1", "https://registry.npmmirror.com/builder-util-runtime/-/builder-util-runtime-9.5.1.tgz", { "dependencies": { "debug": "^4.3.4", "sax": "^1.2.4" } }, "sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ=="], + + "bytes": ["bytes@3.1.2", "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + + "cac": ["cac@6.7.14", "https://registry.npmmirror.com/cac/-/cac-6.7.14.tgz", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], + + "cacache": ["cacache@19.0.1", "https://registry.npmmirror.com/cacache/-/cacache-19.0.1.tgz", { "dependencies": { "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^12.0.0", "tar": "^7.4.3", "unique-filename": "^4.0.0" } }, "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ=="], + + "cacheable-lookup": ["cacheable-lookup@5.0.4", "https://registry.npmmirror.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", {}, "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="], + + "cacheable-request": ["cacheable-request@7.0.4", "https://registry.npmmirror.com/cacheable-request/-/cacheable-request-7.0.4.tgz", { "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^6.0.1", "responselike": "^2.0.0" } }, "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg=="], + + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + + "call-bound": ["call-bound@1.0.4", "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + + "callsites": ["callsites@3.1.0", "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + + "camelcase": ["camelcase@5.3.1", "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="], + + "camelcase-css": ["camelcase-css@2.0.1", "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001769", "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", {}, "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg=="], + + "ccount": ["ccount@2.0.1", "https://registry.npmmirror.com/ccount/-/ccount-2.0.1.tgz", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + + "chai": ["chai@5.3.3", "https://registry.npmmirror.com/chai/-/chai-5.3.3.tgz", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="], + + "chalk": ["chalk@4.1.2", "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "character-entities-html4": ["character-entities-html4@2.1.0", "https://registry.npmmirror.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], + + "character-entities-legacy": ["character-entities-legacy@3.0.0", "https://registry.npmmirror.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + + "check-error": ["check-error@2.1.3", "https://registry.npmmirror.com/check-error/-/check-error-2.1.3.tgz", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], + + "chokidar": ["chokidar@3.6.0", "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + + "chownr": ["chownr@3.0.0", "https://registry.npmmirror.com/chownr/-/chownr-3.0.0.tgz", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "chromium-pickle-js": ["chromium-pickle-js@0.2.0", "https://registry.npmmirror.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", {}, "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw=="], + + "ci-info": ["ci-info@4.4.0", "https://registry.npmmirror.com/ci-info/-/ci-info-4.4.0.tgz", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], + + "cli-cursor": ["cli-cursor@3.1.0", "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="], + + "cli-spinners": ["cli-spinners@2.9.2", "https://registry.npmmirror.com/cli-spinners/-/cli-spinners-2.9.2.tgz", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], + + "cli-truncate": ["cli-truncate@2.1.0", "https://registry.npmmirror.com/cli-truncate/-/cli-truncate-2.1.0.tgz", { "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" } }, "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg=="], + + "cliui": ["cliui@6.0.0", "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="], + + "clone": ["clone@1.0.4", "https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + + "clone-response": ["clone-response@1.0.3", "https://registry.npmmirror.com/clone-response/-/clone-response-1.0.3.tgz", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="], + + "clsx": ["clsx@2.1.1", "https://registry.npmmirror.com/clsx/-/clsx-2.1.1.tgz", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + + "color-convert": ["color-convert@2.0.1", "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "combined-stream": ["combined-stream@1.0.8", "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], + + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "https://registry.npmmirror.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + + "commander": ["commander@12.1.0", "https://registry.npmmirror.com/commander/-/commander-12.1.0.tgz", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], + + "compare-version": ["compare-version@0.1.2", "https://registry.npmmirror.com/compare-version/-/compare-version-0.1.2.tgz", {}, "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A=="], + + "concat-map": ["concat-map@0.0.1", "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], + + "content-disposition": ["content-disposition@0.5.4", "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="], + + "content-type": ["content-type@1.0.5", "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], + + "convert-source-map": ["convert-source-map@2.0.0", "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + + "cookie": ["cookie@0.7.2", "https://registry.npmmirror.com/cookie/-/cookie-0.7.2.tgz", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + + "cookie-signature": ["cookie-signature@1.2.2", "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.2.2.tgz", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], + + "core-util-is": ["core-util-is@1.0.2", "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.2.tgz", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="], + + "cors": ["cors@2.8.6", "https://registry.npmmirror.com/cors/-/cors-2.8.6.tgz", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], + + "crc": ["crc@3.8.0", "https://registry.npmmirror.com/crc/-/crc-3.8.0.tgz", { "dependencies": { "buffer": "^5.1.0" } }, "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ=="], + + "cross-dirname": ["cross-dirname@0.1.0", "https://registry.npmmirror.com/cross-dirname/-/cross-dirname-0.1.0.tgz", {}, "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q=="], + + "cross-env": ["cross-env@7.0.3", "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="], + + "cross-spawn": ["cross-spawn@7.0.6", "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "cssesc": ["cssesc@3.0.0", "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], + + "cssstyle": ["cssstyle@4.6.0", "https://registry.npmmirror.com/cssstyle/-/cssstyle-4.6.0.tgz", { "dependencies": { "@asamuzakjp/css-color": "^3.2.0", "rrweb-cssom": "^0.8.0" } }, "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg=="], + + "csstype": ["csstype@3.2.3", "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + + "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "https://registry.npmmirror.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], + + "data-urls": ["data-urls@5.0.0", "https://registry.npmmirror.com/data-urls/-/data-urls-5.0.0.tgz", { "dependencies": { "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0" } }, "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg=="], + + "debug": ["debug@4.4.3", "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decamelize": ["decamelize@1.2.0", "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="], + + "decimal.js": ["decimal.js@10.6.0", "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.6.0.tgz", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="], + + "decompress-response": ["decompress-response@6.0.0", "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], + + "deep-eql": ["deep-eql@5.0.2", "https://registry.npmmirror.com/deep-eql/-/deep-eql-5.0.2.tgz", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], + + "deep-is": ["deep-is@0.1.4", "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], + + "defaults": ["defaults@1.0.4", "https://registry.npmmirror.com/defaults/-/defaults-1.0.4.tgz", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="], + + "defer-to-connect": ["defer-to-connect@2.0.1", "https://registry.npmmirror.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz", {}, "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="], + + "define-data-property": ["define-data-property@1.1.4", "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], + + "define-properties": ["define-properties@1.2.1", "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="], + + "delayed-stream": ["delayed-stream@1.0.0", "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], + + "depd": ["depd@2.0.0", "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], + + "dequal": ["dequal@2.0.3", "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "detect-libc": ["detect-libc@2.1.2", "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "detect-node": ["detect-node@2.1.0", "https://registry.npmmirror.com/detect-node/-/detect-node-2.1.0.tgz", {}, "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="], + + "devlop": ["devlop@1.1.0", "https://registry.npmmirror.com/devlop/-/devlop-1.1.0.tgz", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "didyoumean": ["didyoumean@1.2.2", "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="], + + "dijkstrajs": ["dijkstrajs@1.0.3", "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz", {}, "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="], + + "dir-compare": ["dir-compare@4.2.0", "https://registry.npmmirror.com/dir-compare/-/dir-compare-4.2.0.tgz", { "dependencies": { "minimatch": "^3.0.5", "p-limit": "^3.1.0 " } }, "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ=="], + + "dlv": ["dlv@1.1.3", "https://registry.npmmirror.com/dlv/-/dlv-1.1.3.tgz", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="], + + "dmg-builder": ["dmg-builder@26.7.0", "https://registry.npmmirror.com/dmg-builder/-/dmg-builder-26.7.0.tgz", { "dependencies": { "app-builder-lib": "26.7.0", "builder-util": "26.4.1", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" }, "optionalDependencies": { "dmg-license": "^1.0.11" } }, "sha512-uOOBA3f+kW3o4KpSoMQ6SNpdXU7WtxlJRb9vCZgOvqhTz4b3GjcoWKstdisizNZLsylhTMv8TLHFPFW0Uxsj/g=="], + + "dmg-license": ["dmg-license@1.0.11", "https://registry.npmmirror.com/dmg-license/-/dmg-license-1.0.11.tgz", { "dependencies": { "@types/plist": "^3.0.1", "@types/verror": "^1.10.3", "ajv": "^6.10.0", "crc": "^3.8.0", "iconv-corefoundation": "^1.1.7", "plist": "^3.0.4", "smart-buffer": "^4.0.2", "verror": "^1.10.0" }, "os": "darwin", "bin": { "dmg-license": "bin/dmg-license.js" } }, "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q=="], + + "dompurify": ["dompurify@3.3.1", "https://registry.npmmirror.com/dompurify/-/dompurify-3.3.1.tgz", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q=="], + + "dotenv": ["dotenv@9.0.2", "https://registry.npmmirror.com/dotenv/-/dotenv-9.0.2.tgz", {}, "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg=="], + + "dotenv-expand": ["dotenv-expand@11.0.7", "https://registry.npmmirror.com/dotenv-expand/-/dotenv-expand-11.0.7.tgz", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="], + + "dunder-proto": ["dunder-proto@1.0.1", "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + + "eastasianwidth": ["eastasianwidth@0.2.0", "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], + + "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="], + + "ee-first": ["ee-first@1.1.1", "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], + + "ejs": ["ejs@3.1.10", "https://registry.npmmirror.com/ejs/-/ejs-3.1.10.tgz", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], + + "electron": ["electron@39.0.0", "https://registry.npmmirror.com/electron/-/electron-39.0.0.tgz", { "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^22.7.7", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" } }, "sha512-UejnuOK4jpRZUq7MkEAnR/szsRWLKBJAdvn6j3xdQLT57fVv13VSNdaUHHjSheaqGzNhCGIdkPsPJnGJVh5kiA=="], + + "electron-builder": ["electron-builder@26.7.0", "https://registry.npmmirror.com/electron-builder/-/electron-builder-26.7.0.tgz", { "dependencies": { "app-builder-lib": "26.7.0", "builder-util": "26.4.1", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "ci-info": "^4.2.0", "dmg-builder": "26.7.0", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "simple-update-notifier": "2.0.0", "yargs": "^17.6.2" }, "bin": { "electron-builder": "cli.js", "install-app-deps": "install-app-deps.js" } }, "sha512-LoXbCvSFxLesPneQ/fM7FB4OheIDA2tjqCdUkKlObV5ZKGhYgi5VHPHO/6UUOUodAlg7SrkPx7BZJPby+Vrtbg=="], + + "electron-builder-squirrel-windows": ["electron-builder-squirrel-windows@26.7.0", "https://registry.npmmirror.com/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.7.0.tgz", { "dependencies": { "app-builder-lib": "26.7.0", "builder-util": "26.4.1", "electron-winstaller": "5.4.0" } }, "sha512-3EqkQK+q0kGshdPSKEPb2p5F75TENMKu6Fe5aTdeaPfdzFK4Yjp5L0d6S7K8iyvqIsGQ/ei4bnpyX9wt+kVCKQ=="], + + "electron-publish": ["electron-publish@26.6.0", "https://registry.npmmirror.com/electron-publish/-/electron-publish-26.6.0.tgz", { "dependencies": { "@types/fs-extra": "^9.0.11", "builder-util": "26.4.1", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "form-data": "^4.0.5", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "mime": "^2.5.2" } }, "sha512-LsyHMMqbvJ2vsOvuWJ19OezgF2ANdCiHpIucDHNiLhuI+/F3eW98ouzWSRmXXi82ZOPZXC07jnIravY4YYwCLQ=="], + + "electron-to-chromium": ["electron-to-chromium@1.5.286", "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", {}, "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A=="], + + "electron-vite": ["electron-vite@4.0.1", "https://registry.npmmirror.com/electron-vite/-/electron-vite-4.0.1.tgz", { "dependencies": { "@babel/core": "^7.27.7", "@babel/plugin-transform-arrow-functions": "^7.27.1", "cac": "^6.7.14", "esbuild": "^0.25.5", "magic-string": "^0.30.17", "picocolors": "^1.1.1" }, "peerDependencies": { "@swc/core": "^1.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@swc/core"], "bin": { "electron-vite": "bin/electron-vite.js" } }, "sha512-QqacJbA8f1pmwUTqki1qLL5vIBaOQmeq13CZZefZ3r3vKVaIoC7cpoTgE+KPKxJDFTax+iFZV0VYvLVWPiQ8Aw=="], + + "electron-winstaller": ["electron-winstaller@5.4.0", "https://registry.npmmirror.com/electron-winstaller/-/electron-winstaller-5.4.0.tgz", { "dependencies": { "@electron/asar": "^3.2.1", "debug": "^4.1.1", "fs-extra": "^7.0.1", "lodash": "^4.17.21", "temp": "^0.9.0" }, "optionalDependencies": { "@electron/windows-sign": "^1.1.2" } }, "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg=="], + + "emoji-regex": ["emoji-regex@8.0.0", "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "encodeurl": ["encodeurl@2.0.0", "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + + "encoding": ["encoding@0.1.13", "https://registry.npmmirror.com/encoding/-/encoding-0.1.13.tgz", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], + + "end-of-stream": ["end-of-stream@1.4.5", "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.5.tgz", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], + + "entities": ["entities@6.0.1", "https://registry.npmmirror.com/entities/-/entities-6.0.1.tgz", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], + + "env-paths": ["env-paths@2.2.1", "https://registry.npmmirror.com/env-paths/-/env-paths-2.2.1.tgz", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + + "err-code": ["err-code@2.0.3", "https://registry.npmmirror.com/err-code/-/err-code-2.0.3.tgz", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="], + + "error-ex": ["error-ex@1.3.4", "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.4.tgz", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], + + "es-define-property": ["es-define-property@1.0.1", "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-module-lexer": ["es-module-lexer@1.7.0", "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], + + "es-object-atoms": ["es-object-atoms@1.1.1", "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], + + "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], + + "es6-error": ["es6-error@4.1.1", "https://registry.npmmirror.com/es6-error/-/es6-error-4.1.1.tgz", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="], + + "esbuild": ["esbuild@0.25.12", "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.12.tgz", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + + "escalade": ["escalade@3.2.0", "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-html": ["escape-html@1.0.3", "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], + + "escape-string-regexp": ["escape-string-regexp@4.0.0", "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "eslint": ["eslint@9.39.2", "https://registry.npmmirror.com/eslint/-/eslint-9.39.2.tgz", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.2", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw=="], + + "eslint-plugin-solid": ["eslint-plugin-solid@0.14.5", "https://registry.npmmirror.com/eslint-plugin-solid/-/eslint-plugin-solid-0.14.5.tgz", { "dependencies": { "@typescript-eslint/utils": "^7.13.1 || ^8.0.0", "estraverse": "^5.3.0", "is-html": "^2.0.0", "kebab-case": "^1.0.2", "known-css-properties": "^0.30.0", "style-to-object": "^1.0.6" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", "typescript": ">=4.8.4" } }, "sha512-nfuYK09ah5aJG/oEN6P1qziy1zLgW4PDWe75VNPi4CEFYk1x2AEqwFeQfEPR7gNn0F2jOeqKhx2E+5oNCOBYWQ=="], + + "eslint-scope": ["eslint-scope@8.4.0", "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-8.4.0.tgz", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], + + "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], + + "espree": ["espree@10.4.0", "https://registry.npmmirror.com/espree/-/espree-10.4.0.tgz", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], + + "esquery": ["esquery@1.7.0", "https://registry.npmmirror.com/esquery/-/esquery-1.7.0.tgz", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="], + + "esrecurse": ["esrecurse@4.3.0", "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], + + "estraverse": ["estraverse@5.3.0", "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], + + "estree-walker": ["estree-walker@3.0.3", "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + + "esutils": ["esutils@2.0.3", "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], + + "etag": ["etag@1.8.1", "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + + "eventsource": ["eventsource@3.0.7", "https://registry.npmmirror.com/eventsource/-/eventsource-3.0.7.tgz", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], + + "eventsource-parser": ["eventsource-parser@3.0.6", "https://registry.npmmirror.com/eventsource-parser/-/eventsource-parser-3.0.6.tgz", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="], + + "expect-type": ["expect-type@1.3.0", "https://registry.npmmirror.com/expect-type/-/expect-type-1.3.0.tgz", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], + + "exponential-backoff": ["exponential-backoff@3.1.3", "https://registry.npmmirror.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], + + "express": ["express@5.2.1", "https://registry.npmmirror.com/express/-/express-5.2.1.tgz", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], + + "express-rate-limit": ["express-rate-limit@8.2.1", "https://registry.npmmirror.com/express-rate-limit/-/express-rate-limit-8.2.1.tgz", { "dependencies": { "ip-address": "10.0.1" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g=="], + + "extend": ["extend@3.0.2", "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "extract-zip": ["extract-zip@2.0.1", "https://registry.npmmirror.com/extract-zip/-/extract-zip-2.0.1.tgz", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": { "extract-zip": "cli.js" } }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="], + + "extsprintf": ["extsprintf@1.4.1", "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.4.1.tgz", {}, "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA=="], + + "fast-content-type-parse": ["fast-content-type-parse@3.0.0", "https://registry.npmmirror.com/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="], + + "fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "https://registry.npmmirror.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-diff": ["fast-diff@1.3.0", "https://registry.npmmirror.com/fast-diff/-/fast-diff-1.3.0.tgz", {}, "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw=="], + + "fast-glob": ["fast-glob@3.3.3", "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + + "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], + + "fast-json-stringify": ["fast-json-stringify@5.16.1", "https://registry.npmmirror.com/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz", { "dependencies": { "@fastify/merge-json-schemas": "^0.1.0", "ajv": "^8.10.0", "ajv-formats": "^3.0.1", "fast-deep-equal": "^3.1.3", "fast-uri": "^2.1.0", "json-schema-ref-resolver": "^1.0.1", "rfdc": "^1.2.0" } }, "sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g=="], + + "fast-levenshtein": ["fast-levenshtein@2.0.6", "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], + + "fast-querystring": ["fast-querystring@1.1.2", "https://registry.npmmirror.com/fast-querystring/-/fast-querystring-1.1.2.tgz", { "dependencies": { "fast-decode-uri-component": "^1.0.1" } }, "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg=="], + + "fast-uri": ["fast-uri@3.1.0", "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.1.0.tgz", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], + + "fastify": ["fastify@4.29.1", "https://registry.npmmirror.com/fastify/-/fastify-4.29.1.tgz", { "dependencies": { "@fastify/ajv-compiler": "^3.5.0", "@fastify/error": "^3.4.0", "@fastify/fast-json-stringify-compiler": "^4.3.0", "abstract-logging": "^2.0.1", "avvio": "^8.3.0", "fast-content-type-parse": "^1.1.0", "fast-json-stringify": "^5.8.0", "find-my-way": "^8.0.0", "light-my-request": "^5.11.0", "pino": "^9.0.0", "process-warning": "^3.0.0", "proxy-addr": "^2.0.7", "rfdc": "^1.3.0", "secure-json-parse": "^2.7.0", "semver": "^7.5.4", "toad-cache": "^3.3.0" } }, "sha512-m2kMNHIG92tSNWv+Z3UeTR9AWLLuo7KctC7mlFPtMEVrfjIhmQhkQnT9v15qA/BfVq3vvj134Y0jl9SBje3jXQ=="], + + "fastify-plugin": ["fastify-plugin@5.1.0", "https://registry.npmmirror.com/fastify-plugin/-/fastify-plugin-5.1.0.tgz", {}, "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw=="], + + "fastq": ["fastq@1.20.1", "https://registry.npmmirror.com/fastq/-/fastq-1.20.1.tgz", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], + + "fd-slicer": ["fd-slicer@1.1.0", "https://registry.npmmirror.com/fd-slicer/-/fd-slicer-1.1.0.tgz", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="], + + "fdir": ["fdir@6.5.0", "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "fetch-blob": ["fetch-blob@3.2.0", "https://registry.npmmirror.com/fetch-blob/-/fetch-blob-3.2.0.tgz", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], + + "file-entry-cache": ["file-entry-cache@8.0.0", "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], + + "filelist": ["filelist@1.0.4", "https://registry.npmmirror.com/filelist/-/filelist-1.0.4.tgz", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q=="], + + "fill-range": ["fill-range@7.1.1", "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "finalhandler": ["finalhandler@2.1.1", "https://registry.npmmirror.com/finalhandler/-/finalhandler-2.1.1.tgz", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], + + "find-my-way": ["find-my-way@8.2.2", "https://registry.npmmirror.com/find-my-way/-/find-my-way-8.2.2.tgz", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-querystring": "^1.0.0", "safe-regex2": "^3.1.0" } }, "sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA=="], + + "find-up": ["find-up@5.0.0", "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], + + "flat-cache": ["flat-cache@4.0.1", "https://registry.npmmirror.com/flat-cache/-/flat-cache-4.0.1.tgz", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], + + "flatted": ["flatted@3.3.3", "https://registry.npmmirror.com/flatted/-/flatted-3.3.3.tgz", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], + + "foreground-child": ["foreground-child@3.3.1", "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.3.1.tgz", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], + + "form-data": ["form-data@4.0.5", "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], + + "formdata-polyfill": ["formdata-polyfill@4.0.10", "https://registry.npmmirror.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="], + + "forwarded": ["forwarded@0.2.0", "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], + + "fraction.js": ["fraction.js@4.3.7", "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="], + + "fresh": ["fresh@2.0.0", "https://registry.npmmirror.com/fresh/-/fresh-2.0.0.tgz", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], + + "fs-extra": ["fs-extra@10.1.0", "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="], + + "fs-minipass": ["fs-minipass@3.0.3", "https://registry.npmmirror.com/fs-minipass/-/fs-minipass-3.0.3.tgz", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], + + "fs.realpath": ["fs.realpath@1.0.0", "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], + + "fsevents": ["fsevents@2.3.3", "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "function-bind": ["function-bind@1.1.2", "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "fuzzysort": ["fuzzysort@2.0.4", "https://registry.npmmirror.com/fuzzysort/-/fuzzysort-2.0.4.tgz", {}, "sha512-Api1mJL+Ad7W7vnDZnWq5pGaXJjyencT+iKGia2PlHUcSsSzWwIQ3S1isiMpwpavjYtGd2FzhUIhnnhOULZgDw=="], + + "gaxios": ["gaxios@7.1.3", "https://registry.npmmirror.com/gaxios/-/gaxios-7.1.3.tgz", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="], + + "gcp-metadata": ["gcp-metadata@8.1.2", "https://registry.npmmirror.com/gcp-metadata/-/gcp-metadata-8.1.2.tgz", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="], + + "gensync": ["gensync@1.0.0-beta.2", "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], + + "get-caller-file": ["get-caller-file@2.0.5", "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-intrinsic": ["get-intrinsic@1.3.0", "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + + "get-proto": ["get-proto@1.0.1", "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + + "get-stream": ["get-stream@5.2.0", "https://registry.npmmirror.com/get-stream/-/get-stream-5.2.0.tgz", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], + + "get-tsconfig": ["get-tsconfig@4.13.6", "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.13.6.tgz", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw=="], + + "github-markdown-css": ["github-markdown-css@5.9.0", "https://registry.npmmirror.com/github-markdown-css/-/github-markdown-css-5.9.0.tgz", {}, "sha512-tmT5sY+zvg2302XLYEfH2mtkViIM1SWf2nvYoF5N1ZsO0V6B2qZTiw3GOzw4vpjLygK/KG35qRlPFweHqfzz5w=="], + + "glob": ["glob@10.5.0", "https://registry.npmmirror.com/glob/-/glob-10.5.0.tgz", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], + + "glob-parent": ["glob-parent@6.0.2", "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], + + "global-agent": ["global-agent@3.0.0", "https://registry.npmmirror.com/global-agent/-/global-agent-3.0.0.tgz", { "dependencies": { "boolean": "^3.0.1", "es6-error": "^4.1.1", "matcher": "^3.0.0", "roarr": "^2.15.3", "semver": "^7.3.2", "serialize-error": "^7.0.1" } }, "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q=="], + + "globals": ["globals@17.3.0", "https://registry.npmmirror.com/globals/-/globals-17.3.0.tgz", {}, "sha512-yMqGUQVVCkD4tqjOJf3TnrvaaHDMYp4VlUSObbkIiuCPe/ofdMBFIAcBbCSRFWOnos6qRiTVStDwqPLUclaxIw=="], + + "globalthis": ["globalthis@1.0.4", "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.4.tgz", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], + + "google-auth-library": ["google-auth-library@10.5.0", "https://registry.npmmirror.com/google-auth-library/-/google-auth-library-10.5.0.tgz", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^7.0.0", "gcp-metadata": "^8.0.0", "google-logging-utils": "^1.0.0", "gtoken": "^8.0.0", "jws": "^4.0.0" } }, "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w=="], + + "google-logging-utils": ["google-logging-utils@1.1.3", "https://registry.npmmirror.com/google-logging-utils/-/google-logging-utils-1.1.3.tgz", {}, "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA=="], + + "gopd": ["gopd@1.2.0", "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + + "got": ["got@11.8.6", "https://registry.npmmirror.com/got/-/got-11.8.6.tgz", { "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.2", "decompress-response": "^6.0.0", "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" } }, "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g=="], + + "graceful-fs": ["graceful-fs@4.2.11", "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "gtoken": ["gtoken@8.0.0", "https://registry.npmmirror.com/gtoken/-/gtoken-8.0.0.tgz", { "dependencies": { "gaxios": "^7.0.0", "jws": "^4.0.0" } }, "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw=="], + + "has-ansi": ["has-ansi@2.0.0", "https://registry.npmmirror.com/has-ansi/-/has-ansi-2.0.0.tgz", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg=="], + + "has-flag": ["has-flag@4.0.0", "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "has-property-descriptors": ["has-property-descriptors@1.0.2", "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="], + + "has-symbols": ["has-symbols@1.1.0", "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "has-tostringtag": ["has-tostringtag@1.0.2", "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], + + "hasown": ["hasown@2.0.2", "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + + "hast-util-to-html": ["hast-util-to-html@9.0.5", "https://registry.npmmirror.com/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], + + "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "https://registry.npmmirror.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + + "highlight.js": ["highlight.js@11.11.1", "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.11.1.tgz", {}, "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w=="], + + "hono": ["hono@4.11.8", "https://registry.npmmirror.com/hono/-/hono-4.11.8.tgz", {}, "sha512-eVkB/CYCCei7K2WElZW9yYQFWssG0DhaDhVvr7wy5jJ22K+ck8fWW0EsLpB0sITUTvPnc97+rrbQqIr5iqiy9Q=="], + + "hosted-git-info": ["hosted-git-info@4.1.0", "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz", { "dependencies": { "lru-cache": "^6.0.0" } }, "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA=="], + + "html-encoding-sniffer": ["html-encoding-sniffer@4.0.0", "https://registry.npmmirror.com/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", { "dependencies": { "whatwg-encoding": "^3.1.1" } }, "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ=="], + + "html-entities": ["html-entities@2.3.3", "https://registry.npmmirror.com/html-entities/-/html-entities-2.3.3.tgz", {}, "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA=="], + + "html-tags": ["html-tags@3.3.1", "https://registry.npmmirror.com/html-tags/-/html-tags-3.3.1.tgz", {}, "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ=="], + + "html-void-elements": ["html-void-elements@3.0.0", "https://registry.npmmirror.com/html-void-elements/-/html-void-elements-3.0.0.tgz", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], + + "http-cache-semantics": ["http-cache-semantics@4.2.0", "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], + + "http-errors": ["http-errors@2.0.0", "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="], + + "http-proxy-agent": ["http-proxy-agent@7.0.2", "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + + "http2-wrapper": ["http2-wrapper@1.0.3", "https://registry.npmmirror.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" } }, "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg=="], + + "https-proxy-agent": ["https-proxy-agent@7.0.6", "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "iconv-corefoundation": ["iconv-corefoundation@1.1.7", "https://registry.npmmirror.com/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", { "dependencies": { "cli-truncate": "^2.1.0", "node-addon-api": "^1.6.3" }, "os": "darwin" }, "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ=="], + + "iconv-lite": ["iconv-lite@0.6.3", "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + + "ieee754": ["ieee754@1.2.1", "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + + "ignore": ["ignore@5.3.2", "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + + "import-fresh": ["import-fresh@3.3.1", "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + + "imurmurhash": ["imurmurhash@0.1.4", "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], + + "inflight": ["inflight@1.0.6", "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], + + "inherits": ["inherits@2.0.4", "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "inline-style-parser": ["inline-style-parser@0.2.7", "https://registry.npmmirror.com/inline-style-parser/-/inline-style-parser-0.2.7.tgz", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="], + + "ip-address": ["ip-address@10.0.1", "https://registry.npmmirror.com/ip-address/-/ip-address-10.0.1.tgz", {}, "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA=="], + + "ipaddr.js": ["ipaddr.js@1.9.1", "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], + + "is-arrayish": ["is-arrayish@0.2.1", "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], + + "is-binary-path": ["is-binary-path@2.1.0", "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], + + "is-core-module": ["is-core-module@2.16.1", "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.1.tgz", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], + + "is-extglob": ["is-extglob@2.1.1", "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-glob": ["is-glob@4.0.3", "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-html": ["is-html@2.0.0", "https://registry.npmmirror.com/is-html/-/is-html-2.0.0.tgz", { "dependencies": { "html-tags": "^3.0.0" } }, "sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg=="], + + "is-interactive": ["is-interactive@1.0.0", "https://registry.npmmirror.com/is-interactive/-/is-interactive-1.0.0.tgz", {}, "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="], + + "is-number": ["is-number@7.0.0", "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="], + + "is-promise": ["is-promise@4.0.0", "https://registry.npmmirror.com/is-promise/-/is-promise-4.0.0.tgz", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], + + "is-unicode-supported": ["is-unicode-supported@0.1.0", "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="], + + "is-utf8": ["is-utf8@0.2.1", "https://registry.npmmirror.com/is-utf8/-/is-utf8-0.2.1.tgz", {}, "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q=="], + + "is-what": ["is-what@4.1.16", "https://registry.npmmirror.com/is-what/-/is-what-4.1.16.tgz", {}, "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="], + + "isbinaryfile": ["isbinaryfile@5.0.7", "https://registry.npmmirror.com/isbinaryfile/-/isbinaryfile-5.0.7.tgz", {}, "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ=="], + + "isexe": ["isexe@2.0.0", "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "jackspeak": ["jackspeak@3.4.3", "https://registry.npmmirror.com/jackspeak/-/jackspeak-3.4.3.tgz", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], + + "jake": ["jake@10.9.4", "https://registry.npmmirror.com/jake/-/jake-10.9.4.tgz", { "dependencies": { "async": "^3.2.6", "filelist": "^1.0.4", "picocolors": "^1.1.1" }, "bin": { "jake": "bin/cli.js" } }, "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA=="], + + "jiti": ["jiti@1.21.7", "https://registry.npmmirror.com/jiti/-/jiti-1.21.7.tgz", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], + + "jose": ["jose@6.1.3", "https://registry.npmmirror.com/jose/-/jose-6.1.3.tgz", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="], + + "js-tokens": ["js-tokens@4.0.0", "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "js-yaml": ["js-yaml@4.1.1", "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.1.tgz", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + + "jsdom": ["jsdom@25.0.1", "https://registry.npmmirror.com/jsdom/-/jsdom-25.0.1.tgz", { "dependencies": { "cssstyle": "^4.1.0", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.12", "parse5": "^7.1.2", "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^5.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^2.11.2" }, "optionalPeers": ["canvas"] }, "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw=="], + + "jsesc": ["jsesc@3.1.0", "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], + + "json-bigint": ["json-bigint@1.0.0", "https://registry.npmmirror.com/json-bigint/-/json-bigint-1.0.0.tgz", { "dependencies": { "bignumber.js": "^9.0.0" } }, "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="], + + "json-buffer": ["json-buffer@3.0.1", "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], + + "json-schema-ref-resolver": ["json-schema-ref-resolver@1.0.1", "https://registry.npmmirror.com/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz", { "dependencies": { "fast-deep-equal": "^3.1.3" } }, "sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw=="], + + "json-schema-traverse": ["json-schema-traverse@0.4.1", "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + + "json-schema-typed": ["json-schema-typed@8.0.2", "https://registry.npmmirror.com/json-schema-typed/-/json-schema-typed-8.0.2.tgz", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="], + + "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], + + "json-stringify-safe": ["json-stringify-safe@5.0.1", "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="], + + "json5": ["json5@2.2.3", "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + + "jsonfile": ["jsonfile@6.2.0", "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], + + "jwa": ["jwa@2.0.1", "https://registry.npmmirror.com/jwa/-/jwa-2.0.1.tgz", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="], + + "jws": ["jws@4.0.1", "https://registry.npmmirror.com/jws/-/jws-4.0.1.tgz", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="], + + "kebab-case": ["kebab-case@1.0.2", "https://registry.npmmirror.com/kebab-case/-/kebab-case-1.0.2.tgz", {}, "sha512-7n6wXq4gNgBELfDCpzKc+mRrZFs7D+wgfF5WRFLNAr4DA/qtr9Js8uOAVAfHhuLMfAcQ0pRKqbpjx+TcJVdE1Q=="], + + "keyv": ["keyv@4.5.4", "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], + + "known-css-properties": ["known-css-properties@0.30.0", "https://registry.npmmirror.com/known-css-properties/-/known-css-properties-0.30.0.tgz", {}, "sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ=="], + + "lazy-val": ["lazy-val@1.0.5", "https://registry.npmmirror.com/lazy-val/-/lazy-val-1.0.5.tgz", {}, "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="], + + "levn": ["levn@0.4.1", "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + + "light-my-request": ["light-my-request@5.14.0", "https://registry.npmmirror.com/light-my-request/-/light-my-request-5.14.0.tgz", { "dependencies": { "cookie": "^0.7.0", "process-warning": "^3.0.0", "set-cookie-parser": "^2.4.1" } }, "sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA=="], + + "lilconfig": ["lilconfig@3.1.3", "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.3.tgz", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], + + "lines-and-columns": ["lines-and-columns@1.2.4", "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + + "locate-path": ["locate-path@6.0.0", "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], + + "lodash": ["lodash@4.17.23", "https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="], + + "lodash.merge": ["lodash.merge@4.6.2", "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + + "log-symbols": ["log-symbols@4.1.0", "https://registry.npmmirror.com/log-symbols/-/log-symbols-4.1.0.tgz", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="], + + "loupe": ["loupe@3.2.1", "https://registry.npmmirror.com/loupe/-/loupe-3.2.1.tgz", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="], + + "lowercase-keys": ["lowercase-keys@2.0.0", "https://registry.npmmirror.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz", {}, "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="], + + "lowlight": ["lowlight@3.3.0", "https://registry.npmmirror.com/lowlight/-/lowlight-3.3.0.tgz", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.0.0", "highlight.js": "~11.11.0" } }, "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ=="], + + "lru-cache": ["lru-cache@10.4.3", "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "lucide-solid": ["lucide-solid@0.300.0", "https://registry.npmmirror.com/lucide-solid/-/lucide-solid-0.300.0.tgz", { "peerDependencies": { "solid-js": "^1.4.7" } }, "sha512-FEAF0CYnuhQiFjpZe2UxQ0LX/wJFuPvFlyVwDdD4uvvAP/nzhCa1xSMhMBpaCTH3BIveJvoz14YOl7uiLkZYow=="], + + "magic-string": ["magic-string@0.30.21", "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "make-error": ["make-error@1.3.6", "https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz", {}, "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="], + + "make-fetch-happen": ["make-fetch-happen@14.0.3", "https://registry.npmmirror.com/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", { "dependencies": { "@npmcli/agent": "^3.0.0", "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "ssri": "^12.0.0" } }, "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ=="], + + "marked": ["marked@12.0.2", "https://registry.npmmirror.com/marked/-/marked-12.0.2.tgz", { "bin": { "marked": "bin/marked.js" } }, "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q=="], + + "matcher": ["matcher@3.0.0", "https://registry.npmmirror.com/matcher/-/matcher-3.0.0.tgz", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="], + + "math-intrinsics": ["math-intrinsics@1.1.0", "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + + "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "https://registry.npmmirror.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="], + + "media-typer": ["media-typer@1.1.0", "https://registry.npmmirror.com/media-typer/-/media-typer-1.1.0.tgz", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], + + "merge-anything": ["merge-anything@5.1.7", "https://registry.npmmirror.com/merge-anything/-/merge-anything-5.1.7.tgz", { "dependencies": { "is-what": "^4.1.8" } }, "sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ=="], + + "merge-descriptors": ["merge-descriptors@2.0.0", "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], + + "merge2": ["merge2@1.4.1", "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "https://registry.npmmirror.com/micromark-util-character/-/micromark-util-character-2.1.1.tgz", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "https://registry.npmmirror.com/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "https://registry.npmmirror.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "https://registry.npmmirror.com/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "https://registry.npmmirror.com/micromark-util-types/-/micromark-util-types-2.0.2.tgz", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "micromatch": ["micromatch@4.0.8", "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "mime": ["mime@3.0.0", "https://registry.npmmirror.com/mime/-/mime-3.0.0.tgz", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], + + "mime-db": ["mime-db@1.52.0", "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + + "mime-types": ["mime-types@2.1.35", "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + + "mimic-fn": ["mimic-fn@2.1.0", "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + + "mimic-response": ["mimic-response@3.1.0", "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], + + "minimatch": ["minimatch@3.1.2", "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], + + "minimist": ["minimist@1.2.8", "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + + "minipass": ["minipass@7.1.2", "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], + + "minipass-collect": ["minipass-collect@2.0.1", "https://registry.npmmirror.com/minipass-collect/-/minipass-collect-2.0.1.tgz", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], + + "minipass-fetch": ["minipass-fetch@4.0.1", "https://registry.npmmirror.com/minipass-fetch/-/minipass-fetch-4.0.1.tgz", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ=="], + + "minipass-flush": ["minipass-flush@1.0.5", "https://registry.npmmirror.com/minipass-flush/-/minipass-flush-1.0.5.tgz", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw=="], + + "minipass-pipeline": ["minipass-pipeline@1.2.4", "https://registry.npmmirror.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="], + + "minipass-sized": ["minipass-sized@1.0.3", "https://registry.npmmirror.com/minipass-sized/-/minipass-sized-1.0.3.tgz", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g=="], + + "minizlib": ["minizlib@3.1.0", "https://registry.npmmirror.com/minizlib/-/minizlib-3.1.0.tgz", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], + + "mkdirp": ["mkdirp@0.5.6", "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz", { "dependencies": { "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="], + + "mnemonist": ["mnemonist@0.39.6", "https://registry.npmmirror.com/mnemonist/-/mnemonist-0.39.6.tgz", { "dependencies": { "obliterator": "^2.0.1" } }, "sha512-A/0v5Z59y63US00cRSLiloEIw3t5G+MiKz4BhX21FI+YBJXBOGW0ohFxTxO08dsOYlzxo87T7vGfZKYp2bcAWA=="], + + "ms": ["ms@2.1.3", "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "mz": ["mz@2.7.0", "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], + + "nanoid": ["nanoid@3.3.11", "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "natural-compare": ["natural-compare@1.4.0", "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], + + "negotiator": ["negotiator@1.0.0", "https://registry.npmmirror.com/negotiator/-/negotiator-1.0.0.tgz", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "node-abi": ["node-abi@4.26.0", "https://registry.npmmirror.com/node-abi/-/node-abi-4.26.0.tgz", { "dependencies": { "semver": "^7.6.3" } }, "sha512-8QwIZqikRvDIkXS2S93LjzhsSPJuIbfaMETWH+Bx8oOT9Sa9UsUtBFQlc3gBNd1+QINjaTloitXr1W3dQLi9Iw=="], + + "node-addon-api": ["node-addon-api@1.7.2", "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-1.7.2.tgz", {}, "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg=="], + + "node-api-version": ["node-api-version@0.2.1", "https://registry.npmmirror.com/node-api-version/-/node-api-version-0.2.1.tgz", { "dependencies": { "semver": "^7.3.5" } }, "sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q=="], + + "node-domexception": ["node-domexception@1.0.0", "https://registry.npmmirror.com/node-domexception/-/node-domexception-1.0.0.tgz", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], + + "node-fetch": ["node-fetch@3.3.2", "https://registry.npmmirror.com/node-fetch/-/node-fetch-3.3.2.tgz", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], + + "node-gyp": ["node-gyp@11.5.0", "https://registry.npmmirror.com/node-gyp/-/node-gyp-11.5.0.tgz", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ=="], + + "node-releases": ["node-releases@2.0.27", "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.27.tgz", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="], + + "nopt": ["nopt@8.1.0", "https://registry.npmmirror.com/nopt/-/nopt-8.1.0.tgz", { "dependencies": { "abbrev": "^3.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A=="], + + "normalize-path": ["normalize-path@3.0.0", "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + + "normalize-range": ["normalize-range@0.1.2", "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], + + "normalize-url": ["normalize-url@6.1.0", "https://registry.npmmirror.com/normalize-url/-/normalize-url-6.1.0.tgz", {}, "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="], + + "nwsapi": ["nwsapi@2.2.23", "https://registry.npmmirror.com/nwsapi/-/nwsapi-2.2.23.tgz", {}, "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ=="], + + "object-assign": ["object-assign@4.1.1", "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "object-hash": ["object-hash@3.0.0", "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], + + "object-inspect": ["object-inspect@1.13.4", "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], + + "object-keys": ["object-keys@1.1.1", "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], + + "obliterator": ["obliterator@2.0.5", "https://registry.npmmirror.com/obliterator/-/obliterator-2.0.5.tgz", {}, "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw=="], + + "on-exit-leak-free": ["on-exit-leak-free@2.1.2", "https://registry.npmmirror.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", {}, "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA=="], + + "on-finished": ["on-finished@2.4.1", "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], + + "once": ["once@1.4.0", "https://registry.npmmirror.com/once/-/once-1.4.0.tgz", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "onetime": ["onetime@5.1.2", "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + + "oniguruma-parser": ["oniguruma-parser@0.12.1", "https://registry.npmmirror.com/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="], + + "oniguruma-to-es": ["oniguruma-to-es@4.3.4", "https://registry.npmmirror.com/oniguruma-to-es/-/oniguruma-to-es-4.3.4.tgz", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA=="], + + "optionator": ["optionator@0.9.4", "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], + + "ora": ["ora@5.4.1", "https://registry.npmmirror.com/ora/-/ora-5.4.1.tgz", { "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", "cli-spinners": "^2.5.0", "is-interactive": "^1.0.0", "is-unicode-supported": "^0.1.0", "log-symbols": "^4.1.0", "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" } }, "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ=="], + + "p-cancelable": ["p-cancelable@2.1.1", "https://registry.npmmirror.com/p-cancelable/-/p-cancelable-2.1.1.tgz", {}, "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg=="], + + "p-limit": ["p-limit@3.1.0", "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], + + "p-locate": ["p-locate@5.0.0", "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], + + "p-map": ["p-map@7.0.4", "https://registry.npmmirror.com/p-map/-/p-map-7.0.4.tgz", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="], + + "p-try": ["p-try@2.2.0", "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], + + "package-json-from-dist": ["package-json-from-dist@1.0.1", "https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], + + "parent-module": ["parent-module@1.0.1", "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + + "parse-json": ["parse-json@2.2.0", "https://registry.npmmirror.com/parse-json/-/parse-json-2.2.0.tgz", { "dependencies": { "error-ex": "^1.2.0" } }, "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ=="], + + "parse5": ["parse5@7.3.0", "https://registry.npmmirror.com/parse5/-/parse5-7.3.0.tgz", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], + + "parseurl": ["parseurl@1.3.3", "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], + + "path-exists": ["path-exists@4.0.0", "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], + + "path-is-absolute": ["path-is-absolute@1.0.1", "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], + + "path-key": ["path-key@3.1.1", "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "path-parse": ["path-parse@1.0.7", "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], + + "path-scurry": ["path-scurry@1.11.1", "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + + "path-to-regexp": ["path-to-regexp@8.3.0", "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-8.3.0.tgz", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], + + "pathe": ["pathe@1.1.2", "https://registry.npmmirror.com/pathe/-/pathe-1.1.2.tgz", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="], + + "pathval": ["pathval@2.0.1", "https://registry.npmmirror.com/pathval/-/pathval-2.0.1.tgz", {}, "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ=="], + + "pe-library": ["pe-library@0.4.1", "https://registry.npmmirror.com/pe-library/-/pe-library-0.4.1.tgz", {}, "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw=="], + + "pend": ["pend@1.2.0", "https://registry.npmmirror.com/pend/-/pend-1.2.0.tgz", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], + + "picocolors": ["picocolors@1.1.1", "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.3", "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + + "pify": ["pify@2.3.0", "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], + + "pinkie": ["pinkie@2.0.4", "https://registry.npmmirror.com/pinkie/-/pinkie-2.0.4.tgz", {}, "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg=="], + + "pino": ["pino@9.14.0", "https://registry.npmmirror.com/pino/-/pino-9.14.0.tgz", { "dependencies": { "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w=="], + + "pino-abstract-transport": ["pino-abstract-transport@2.0.0", "https://registry.npmmirror.com/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", { "dependencies": { "split2": "^4.0.0" } }, "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw=="], + + "pino-std-serializers": ["pino-std-serializers@7.1.0", "https://registry.npmmirror.com/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", {}, "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw=="], + + "pirates": ["pirates@4.0.7", "https://registry.npmmirror.com/pirates/-/pirates-4.0.7.tgz", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], + + "pkce-challenge": ["pkce-challenge@5.0.1", "https://registry.npmmirror.com/pkce-challenge/-/pkce-challenge-5.0.1.tgz", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], + + "plist": ["plist@3.1.0", "https://registry.npmmirror.com/plist/-/plist-3.1.0.tgz", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ=="], + + "png2icons": ["png2icons@2.0.1", "https://registry.npmmirror.com/png2icons/-/png2icons-2.0.1.tgz", { "bin": { "png2icons": "./png2icons-cli.js" } }, "sha512-GDEQJr8OG4e6JMp7mABtXFSEpgJa1CCpbQiAR+EjhkHJHnUL9zPPtbOrjsMD8gUbikgv3j7x404b0YJsV3aVFA=="], + + "pngjs": ["pngjs@7.0.0", "https://registry.npmmirror.com/pngjs/-/pngjs-7.0.0.tgz", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="], + + "postcss": ["postcss@8.5.6", "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], + + "postcss-import": ["postcss-import@15.1.0", "https://registry.npmmirror.com/postcss-import/-/postcss-import-15.1.0.tgz", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="], + + "postcss-js": ["postcss-js@4.1.0", "https://registry.npmmirror.com/postcss-js/-/postcss-js-4.1.0.tgz", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw=="], + + "postcss-load-config": ["postcss-load-config@6.0.1", "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-6.0.1.tgz", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], + + "postcss-nested": ["postcss-nested@6.2.0", "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.2.0.tgz", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="], + + "postcss-selector-parser": ["postcss-selector-parser@6.1.2", "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + + "postcss-value-parser": ["postcss-value-parser@4.2.0", "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], + + "postject": ["postject@1.0.0-alpha.6", "https://registry.npmmirror.com/postject/-/postject-1.0.0-alpha.6.tgz", { "dependencies": { "commander": "^9.4.0" }, "bin": { "postject": "dist/cli.js" } }, "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A=="], + + "prelude-ls": ["prelude-ls@1.2.1", "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], + + "proc-log": ["proc-log@5.0.0", "https://registry.npmmirror.com/proc-log/-/proc-log-5.0.0.tgz", {}, "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ=="], + + "process-warning": ["process-warning@3.0.0", "https://registry.npmmirror.com/process-warning/-/process-warning-3.0.0.tgz", {}, "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ=="], + + "progress": ["progress@2.0.3", "https://registry.npmmirror.com/progress/-/progress-2.0.3.tgz", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], + + "promise-retry": ["promise-retry@2.0.1", "https://registry.npmmirror.com/promise-retry/-/promise-retry-2.0.1.tgz", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="], + + "proper-lockfile": ["proper-lockfile@4.1.2", "https://registry.npmmirror.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="], + + "property-information": ["property-information@7.1.0", "https://registry.npmmirror.com/property-information/-/property-information-7.1.0.tgz", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], + + "proxy-addr": ["proxy-addr@2.0.7", "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], + + "pump": ["pump@3.0.3", "https://registry.npmmirror.com/pump/-/pump-3.0.3.tgz", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="], + + "punycode": ["punycode@2.3.1", "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + + "qrcode": ["qrcode@1.5.4", "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.4.tgz", { "dependencies": { "dijkstrajs": "^1.0.1", "pngjs": "^5.0.0", "yargs": "^15.3.1" }, "bin": { "qrcode": "bin/qrcode" } }, "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg=="], + + "qs": ["qs@6.14.1", "https://registry.npmmirror.com/qs/-/qs-6.14.1.tgz", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ=="], + + "queue-microtask": ["queue-microtask@1.2.3", "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + + "quick-format-unescaped": ["quick-format-unescaped@4.0.4", "https://registry.npmmirror.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="], + + "quick-lru": ["quick-lru@5.1.1", "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], + + "range-parser": ["range-parser@1.2.1", "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], + + "raw-body": ["raw-body@3.0.2", "https://registry.npmmirror.com/raw-body/-/raw-body-3.0.2.tgz", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], + + "react": ["react@19.2.4", "https://registry.npmmirror.com/react/-/react-19.2.4.tgz", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], + + "reactivity-store": ["reactivity-store@0.3.12", "https://registry.npmmirror.com/reactivity-store/-/reactivity-store-0.3.12.tgz", { "dependencies": { "@vue/reactivity": "~3.5.22", "@vue/shared": "~3.5.22", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Idz9EL4dFUtQbHySZQzckWOTUfqjdYpUtNW0iOysC32mG7IjiUGB77QrsyR5eAWBkRiS9JscF6A3fuQAIy+LrQ=="], + + "read-binary-file-arch": ["read-binary-file-arch@1.0.6", "https://registry.npmmirror.com/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz", { "dependencies": { "debug": "^4.3.4" }, "bin": { "read-binary-file-arch": "cli.js" } }, "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg=="], + + "read-cache": ["read-cache@1.0.0", "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], + + "readable-stream": ["readable-stream@3.6.2", "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + + "readdirp": ["readdirp@3.6.0", "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + + "real-require": ["real-require@0.2.0", "https://registry.npmmirror.com/real-require/-/real-require-0.2.0.tgz", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="], + + "regex": ["regex@6.1.0", "https://registry.npmmirror.com/regex/-/regex-6.1.0.tgz", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], + + "regex-recursion": ["regex-recursion@6.0.2", "https://registry.npmmirror.com/regex-recursion/-/regex-recursion-6.0.2.tgz", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], + + "regex-utilities": ["regex-utilities@2.3.0", "https://registry.npmmirror.com/regex-utilities/-/regex-utilities-2.3.0.tgz", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], + + "require-directory": ["require-directory@2.1.1", "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + + "require-from-string": ["require-from-string@2.0.2", "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + + "require-main-filename": ["require-main-filename@2.0.0", "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz", {}, "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="], + + "resedit": ["resedit@1.7.2", "https://registry.npmmirror.com/resedit/-/resedit-1.7.2.tgz", { "dependencies": { "pe-library": "^0.4.1" } }, "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA=="], + + "resolve": ["resolve@1.22.11", "https://registry.npmmirror.com/resolve/-/resolve-1.22.11.tgz", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], + + "resolve-alpn": ["resolve-alpn@1.2.1", "https://registry.npmmirror.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz", {}, "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="], + + "resolve-from": ["resolve-from@4.0.0", "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "https://registry.npmmirror.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + + "responselike": ["responselike@2.0.1", "https://registry.npmmirror.com/responselike/-/responselike-2.0.1.tgz", { "dependencies": { "lowercase-keys": "^2.0.0" } }, "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw=="], + + "restore-cursor": ["restore-cursor@3.1.0", "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA=="], + + "ret": ["ret@0.4.3", "https://registry.npmmirror.com/ret/-/ret-0.4.3.tgz", {}, "sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ=="], + + "retry": ["retry@0.12.0", "https://registry.npmmirror.com/retry/-/retry-0.12.0.tgz", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], + + "reusify": ["reusify@1.1.0", "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + + "rfdc": ["rfdc@1.4.1", "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + + "rimraf": ["rimraf@5.0.10", "https://registry.npmmirror.com/rimraf/-/rimraf-5.0.10.tgz", { "dependencies": { "glob": "^10.3.7" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ=="], + + "roarr": ["roarr@2.15.4", "https://registry.npmmirror.com/roarr/-/roarr-2.15.4.tgz", { "dependencies": { "boolean": "^3.0.1", "detect-node": "^2.0.4", "globalthis": "^1.0.1", "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" } }, "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="], + + "rollup": ["rollup@4.57.1", "https://registry.npmmirror.com/rollup/-/rollup-4.57.1.tgz", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.1", "@rollup/rollup-android-arm64": "4.57.1", "@rollup/rollup-darwin-arm64": "4.57.1", "@rollup/rollup-darwin-x64": "4.57.1", "@rollup/rollup-freebsd-arm64": "4.57.1", "@rollup/rollup-freebsd-x64": "4.57.1", "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", "@rollup/rollup-linux-arm-musleabihf": "4.57.1", "@rollup/rollup-linux-arm64-gnu": "4.57.1", "@rollup/rollup-linux-arm64-musl": "4.57.1", "@rollup/rollup-linux-loong64-gnu": "4.57.1", "@rollup/rollup-linux-loong64-musl": "4.57.1", "@rollup/rollup-linux-ppc64-gnu": "4.57.1", "@rollup/rollup-linux-ppc64-musl": "4.57.1", "@rollup/rollup-linux-riscv64-gnu": "4.57.1", "@rollup/rollup-linux-riscv64-musl": "4.57.1", "@rollup/rollup-linux-s390x-gnu": "4.57.1", "@rollup/rollup-linux-x64-gnu": "4.57.1", "@rollup/rollup-linux-x64-musl": "4.57.1", "@rollup/rollup-openbsd-x64": "4.57.1", "@rollup/rollup-openharmony-arm64": "4.57.1", "@rollup/rollup-win32-arm64-msvc": "4.57.1", "@rollup/rollup-win32-ia32-msvc": "4.57.1", "@rollup/rollup-win32-x64-gnu": "4.57.1", "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A=="], + + "router": ["router@2.2.0", "https://registry.npmmirror.com/router/-/router-2.2.0.tgz", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], + + "rrweb-cssom": ["rrweb-cssom@0.7.1", "https://registry.npmmirror.com/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", {}, "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg=="], + + "run-parallel": ["run-parallel@1.2.0", "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + + "safe-buffer": ["safe-buffer@5.2.1", "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + + "safe-regex2": ["safe-regex2@3.1.0", "https://registry.npmmirror.com/safe-regex2/-/safe-regex2-3.1.0.tgz", { "dependencies": { "ret": "~0.4.0" } }, "sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug=="], + + "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "https://registry.npmmirror.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="], + + "safer-buffer": ["safer-buffer@2.1.2", "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "sanitize-filename": ["sanitize-filename@1.6.3", "https://registry.npmmirror.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz", { "dependencies": { "truncate-utf8-bytes": "^1.0.0" } }, "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg=="], + + "sax": ["sax@1.4.4", "https://registry.npmmirror.com/sax/-/sax-1.4.4.tgz", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], + + "saxes": ["saxes@6.0.0", "https://registry.npmmirror.com/saxes/-/saxes-6.0.0.tgz", { "dependencies": { "xmlchars": "^2.2.0" } }, "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA=="], + + "secure-json-parse": ["secure-json-parse@2.7.0", "https://registry.npmmirror.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz", {}, "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="], + + "semver": ["semver@7.7.4", "https://registry.npmmirror.com/semver/-/semver-7.7.4.tgz", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + + "semver-compare": ["semver-compare@1.0.0", "https://registry.npmmirror.com/semver-compare/-/semver-compare-1.0.0.tgz", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="], + + "send": ["send@1.2.1", "https://registry.npmmirror.com/send/-/send-1.2.1.tgz", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], + + "serialize-error": ["serialize-error@7.0.1", "https://registry.npmmirror.com/serialize-error/-/serialize-error-7.0.1.tgz", { "dependencies": { "type-fest": "^0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="], + + "seroval": ["seroval@1.5.0", "https://registry.npmmirror.com/seroval/-/seroval-1.5.0.tgz", {}, "sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw=="], + + "seroval-plugins": ["seroval-plugins@1.5.0", "https://registry.npmmirror.com/seroval-plugins/-/seroval-plugins-1.5.0.tgz", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-EAHqADIQondwRZIdeW2I636zgsODzoBDwb3PT/+7TLDWyw1Dy/Xv7iGUIEXXav7usHDE9HVhOU61irI3EnyyHA=="], + + "serve-static": ["serve-static@2.2.1", "https://registry.npmmirror.com/serve-static/-/serve-static-2.2.1.tgz", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], + + "set-blocking": ["set-blocking@2.0.0", "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz", {}, "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="], + + "set-cookie-parser": ["set-cookie-parser@2.7.2", "https://registry.npmmirror.com/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="], + + "setprototypeof": ["setprototypeof@1.2.0", "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], + + "shebang-command": ["shebang-command@2.0.0", "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "shiki": ["shiki@3.22.0", "https://registry.npmmirror.com/shiki/-/shiki-3.22.0.tgz", { "dependencies": { "@shikijs/core": "3.22.0", "@shikijs/engine-javascript": "3.22.0", "@shikijs/engine-oniguruma": "3.22.0", "@shikijs/langs": "3.22.0", "@shikijs/themes": "3.22.0", "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g=="], + + "side-channel": ["side-channel@1.1.0", "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], + + "side-channel-list": ["side-channel-list@1.0.0", "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.0.tgz", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], + + "side-channel-map": ["side-channel-map@1.0.1", "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], + + "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + + "siginfo": ["siginfo@2.0.0", "https://registry.npmmirror.com/siginfo/-/siginfo-2.0.0.tgz", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], + + "signal-exit": ["signal-exit@4.1.0", "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "simple-update-notifier": ["simple-update-notifier@2.0.0", "https://registry.npmmirror.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", { "dependencies": { "semver": "^7.5.3" } }, "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w=="], + + "slice-ansi": ["slice-ansi@3.0.0", "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-3.0.0.tgz", { "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" } }, "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ=="], + + "smart-buffer": ["smart-buffer@4.2.0", "https://registry.npmmirror.com/smart-buffer/-/smart-buffer-4.2.0.tgz", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], + + "socks": ["socks@2.8.7", "https://registry.npmmirror.com/socks/-/socks-2.8.7.tgz", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], + + "socks-proxy-agent": ["socks-proxy-agent@8.0.5", "https://registry.npmmirror.com/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], + + "solid-js": ["solid-js@1.9.11", "https://registry.npmmirror.com/solid-js/-/solid-js-1.9.11.tgz", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.5.0", "seroval-plugins": "~1.5.0" } }, "sha512-WEJtcc5mkh/BnHA6Yrg4whlF8g6QwpmXXRg4P2ztPmcKeHHlH4+djYecBLhSpecZY2RRECXYUwIc/C2r3yzQ4Q=="], + + "solid-presence": ["solid-presence@0.1.8", "https://registry.npmmirror.com/solid-presence/-/solid-presence-0.1.8.tgz", { "dependencies": { "@corvu/utils": "~0.4.0" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-pWGtXUFWYYUZNbg5YpG5vkQJyOtzn2KXhxYaMx/4I+lylTLYkITOLevaCwMRN+liCVk0pqB6EayLWojNqBFECA=="], + + "solid-prevent-scroll": ["solid-prevent-scroll@0.1.10", "https://registry.npmmirror.com/solid-prevent-scroll/-/solid-prevent-scroll-0.1.10.tgz", { "dependencies": { "@corvu/utils": "~0.4.1" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-KplGPX2GHiWJLZ6AXYRql4M127PdYzfwvLJJXMkO+CMb8Np4VxqDAg5S8jLdwlEuBis/ia9DKw2M8dFx5u8Mhw=="], + + "solid-refresh": ["solid-refresh@0.6.3", "https://registry.npmmirror.com/solid-refresh/-/solid-refresh-0.6.3.tgz", { "dependencies": { "@babel/generator": "^7.23.6", "@babel/helper-module-imports": "^7.22.15", "@babel/types": "^7.23.6" }, "peerDependencies": { "solid-js": "^1.3" } }, "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA=="], + + "solid-toast": ["solid-toast@0.5.0", "https://registry.npmmirror.com/solid-toast/-/solid-toast-0.5.0.tgz", { "peerDependencies": { "solid-js": "^1.5.4" } }, "sha512-t770JakjyS2P9b8Qa1zMLOD51KYKWXbTAyJePVUoYex5c5FH5S/HtUBUbZAWFcqRCKmAE8KhyIiCvDZA8bOnxQ=="], + + "sonic-boom": ["sonic-boom@4.2.0", "https://registry.npmmirror.com/sonic-boom/-/sonic-boom-4.2.0.tgz", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww=="], + + "source-map": ["source-map@0.5.7", "https://registry.npmmirror.com/source-map/-/source-map-0.5.7.tgz", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], + + "source-map-js": ["source-map-js@1.2.1", "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "source-map-support": ["source-map-support@0.4.18", "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.4.18.tgz", { "dependencies": { "source-map": "^0.5.6" } }, "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA=="], + + "space-separated-tokens": ["space-separated-tokens@2.0.2", "https://registry.npmmirror.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + + "split2": ["split2@4.2.0", "https://registry.npmmirror.com/split2/-/split2-4.2.0.tgz", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], + + "sprintf-js": ["sprintf-js@1.1.3", "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.1.3.tgz", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], + + "ssri": ["ssri@12.0.0", "https://registry.npmmirror.com/ssri/-/ssri-12.0.0.tgz", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ=="], + + "stackback": ["stackback@0.0.2", "https://registry.npmmirror.com/stackback/-/stackback-0.0.2.tgz", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + + "stat-mode": ["stat-mode@1.0.0", "https://registry.npmmirror.com/stat-mode/-/stat-mode-1.0.0.tgz", {}, "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg=="], + + "statuses": ["statuses@2.0.2", "https://registry.npmmirror.com/statuses/-/statuses-2.0.2.tgz", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + + "std-env": ["std-env@3.10.0", "https://registry.npmmirror.com/std-env/-/std-env-3.10.0.tgz", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], + + "string-width": ["string-width@4.2.3", "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "string-width-cjs": ["string-width@4.2.3", "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "string_decoder": ["string_decoder@1.3.0", "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], + + "stringify-entities": ["stringify-entities@4.0.4", "https://registry.npmmirror.com/stringify-entities/-/stringify-entities-4.0.4.tgz", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], + + "strip-ansi": ["strip-ansi@3.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-3.0.1.tgz", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg=="], + + "strip-ansi-cjs": ["strip-ansi@6.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "strip-bom": ["strip-bom@2.0.0", "https://registry.npmmirror.com/strip-bom/-/strip-bom-2.0.0.tgz", { "dependencies": { "is-utf8": "^0.2.0" } }, "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g=="], + + "strip-json-comments": ["strip-json-comments@3.1.1", "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + + "style-to-object": ["style-to-object@1.0.14", "https://registry.npmmirror.com/style-to-object/-/style-to-object-1.0.14.tgz", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="], + + "sucrase": ["sucrase@3.35.1", "https://registry.npmmirror.com/sucrase/-/sucrase-3.35.1.tgz", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="], + + "sumchecker": ["sumchecker@3.0.1", "https://registry.npmmirror.com/sumchecker/-/sumchecker-3.0.1.tgz", { "dependencies": { "debug": "^4.1.0" } }, "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg=="], + + "supports-color": ["supports-color@7.2.0", "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], + + "symbol-tree": ["symbol-tree@3.2.4", "https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="], + + "tailwindcss": ["tailwindcss@3.4.19", "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.19.tgz", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.7", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ=="], + + "tar": ["tar@7.5.7", "https://registry.npmmirror.com/tar/-/tar-7.5.7.tgz", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ=="], + + "temp": ["temp@0.9.4", "https://registry.npmmirror.com/temp/-/temp-0.9.4.tgz", { "dependencies": { "mkdirp": "^0.5.1", "rimraf": "~2.6.2" } }, "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA=="], + + "temp-file": ["temp-file@3.4.0", "https://registry.npmmirror.com/temp-file/-/temp-file-3.4.0.tgz", { "dependencies": { "async-exit-hook": "^2.0.1", "fs-extra": "^10.0.0" } }, "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg=="], + + "thenify": ["thenify@3.3.1", "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], + + "thenify-all": ["thenify-all@1.6.0", "https://registry.npmmirror.com/thenify-all/-/thenify-all-1.6.0.tgz", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], + + "thread-stream": ["thread-stream@3.1.0", "https://registry.npmmirror.com/thread-stream/-/thread-stream-3.1.0.tgz", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A=="], + + "tiny-async-pool": ["tiny-async-pool@1.3.0", "https://registry.npmmirror.com/tiny-async-pool/-/tiny-async-pool-1.3.0.tgz", { "dependencies": { "semver": "^5.5.0" } }, "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA=="], + + "tinybench": ["tinybench@2.9.0", "https://registry.npmmirror.com/tinybench/-/tinybench-2.9.0.tgz", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + + "tinyexec": ["tinyexec@0.3.2", "https://registry.npmmirror.com/tinyexec/-/tinyexec-0.3.2.tgz", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + + "tinyglobby": ["tinyglobby@0.2.15", "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.15.tgz", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + + "tinypool": ["tinypool@1.1.1", "https://registry.npmmirror.com/tinypool/-/tinypool-1.1.1.tgz", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="], + + "tinyrainbow": ["tinyrainbow@1.2.0", "https://registry.npmmirror.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz", {}, "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ=="], + + "tinyspy": ["tinyspy@3.0.2", "https://registry.npmmirror.com/tinyspy/-/tinyspy-3.0.2.tgz", {}, "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q=="], + + "tldts": ["tldts@6.1.86", "https://registry.npmmirror.com/tldts/-/tldts-6.1.86.tgz", { "dependencies": { "tldts-core": "^6.1.86" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ=="], + + "tldts-core": ["tldts-core@6.1.86", "https://registry.npmmirror.com/tldts-core/-/tldts-core-6.1.86.tgz", {}, "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA=="], + + "tmp": ["tmp@0.2.5", "https://registry.npmmirror.com/tmp/-/tmp-0.2.5.tgz", {}, "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="], + + "tmp-promise": ["tmp-promise@3.0.3", "https://registry.npmmirror.com/tmp-promise/-/tmp-promise-3.0.3.tgz", { "dependencies": { "tmp": "^0.2.0" } }, "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ=="], + + "to-regex-range": ["to-regex-range@5.0.1", "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "toad-cache": ["toad-cache@3.7.0", "https://registry.npmmirror.com/toad-cache/-/toad-cache-3.7.0.tgz", {}, "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw=="], + + "toidentifier": ["toidentifier@1.0.1", "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], + + "tough-cookie": ["tough-cookie@5.1.2", "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-5.1.2.tgz", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A=="], + + "tr46": ["tr46@5.1.1", "https://registry.npmmirror.com/tr46/-/tr46-5.1.1.tgz", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="], + + "trim-lines": ["trim-lines@3.0.1", "https://registry.npmmirror.com/trim-lines/-/trim-lines-3.0.1.tgz", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], + + "truncate-utf8-bytes": ["truncate-utf8-bytes@1.0.2", "https://registry.npmmirror.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", { "dependencies": { "utf8-byte-length": "^1.0.1" } }, "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ=="], + + "ts-api-utils": ["ts-api-utils@2.4.0", "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-2.4.0.tgz", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA=="], + + "ts-interface-checker": ["ts-interface-checker@0.1.13", "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], + + "ts-node": ["ts-node@1.7.1", "https://registry.npmmirror.com/ts-node/-/ts-node-1.7.1.tgz", { "dependencies": { "arrify": "^1.0.0", "chalk": "^1.1.1", "make-error": "^1.1.1", "minimist": "^1.2.0", "mkdirp": "^0.5.1", "pinkie": "^2.0.4", "source-map-support": "^0.4.0", "tsconfig": "^5.0.2", "v8flags": "^2.0.11", "xtend": "^4.0.0", "yn": "^1.2.0" }, "bin": { "ts-node": "dist/bin.js" } }, "sha512-2b6YmKQ0052pEP5Y+KnBce0NkyjuQRBTLKd5XV0O/+WHLbj3CJ5rUrhB2Co1a5IaBiaC2DhynS/v4UfWtHy+2A=="], + + "tsconfig": ["tsconfig@5.0.3", "https://registry.npmmirror.com/tsconfig/-/tsconfig-5.0.3.tgz", { "dependencies": { "any-promise": "^1.3.0", "parse-json": "^2.2.0", "strip-bom": "^2.0.0", "strip-json-comments": "^2.0.0" } }, "sha512-Cq65A3kVp6BbsUgg9DRHafaGmbMb9EhAc7fjWvudNWKjkbWrt43FnrtZt6awshH1R0ocfF2Z0uxock3lVqEgOg=="], + + "tslib": ["tslib@2.8.1", "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "tsx": ["tsx@4.21.0", "https://registry.npmmirror.com/tsx/-/tsx-4.21.0.tgz", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="], + + "type-check": ["type-check@0.4.0", "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], + + "type-fest": ["type-fest@0.13.1", "https://registry.npmmirror.com/type-fest/-/type-fest-0.13.1.tgz", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], + + "type-is": ["type-is@2.0.1", "https://registry.npmmirror.com/type-is/-/type-is-2.0.1.tgz", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], + + "typescript": ["typescript@5.9.3", "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "typescript-eslint": ["typescript-eslint@8.54.0", "https://registry.npmmirror.com/typescript-eslint/-/typescript-eslint-8.54.0.tgz", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.54.0", "@typescript-eslint/parser": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0", "@typescript-eslint/utils": "8.54.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ=="], + + "undici": ["undici@6.23.0", "https://registry.npmmirror.com/undici/-/undici-6.23.0.tgz", {}, "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g=="], + + "undici-types": ["undici-types@7.16.0", "https://registry.npmmirror.com/undici-types/-/undici-types-7.16.0.tgz", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + + "unique-filename": ["unique-filename@4.0.0", "https://registry.npmmirror.com/unique-filename/-/unique-filename-4.0.0.tgz", { "dependencies": { "unique-slug": "^5.0.0" } }, "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ=="], + + "unique-slug": ["unique-slug@5.0.0", "https://registry.npmmirror.com/unique-slug/-/unique-slug-5.0.0.tgz", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg=="], + + "unist-util-is": ["unist-util-is@6.0.1", "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-6.0.1.tgz", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], + + "unist-util-position": ["unist-util-position@5.0.0", "https://registry.npmmirror.com/unist-util-position/-/unist-util-position-5.0.0.tgz", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "https://registry.npmmirror.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.1.0", "https://registry.npmmirror.com/unist-util-visit/-/unist-util-visit-5.1.0.tgz", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "https://registry.npmmirror.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + + "universalify": ["universalify@2.0.1", "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], + + "unpipe": ["unpipe@1.0.0", "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + + "update-browserslist-db": ["update-browserslist-db@1.2.3", "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], + + "uri-js": ["uri-js@4.4.1", "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + + "use-sync-external-store": ["use-sync-external-store@1.6.0", "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], + + "user-home": ["user-home@1.1.1", "https://registry.npmmirror.com/user-home/-/user-home-1.1.1.tgz", { "bin": { "user-home": "cli.js" } }, "sha512-aggiKfEEubv3UwRNqTzLInZpAOmKzwdHqEBmW/hBA/mt99eg+b4VrX6i+IRLxU8+WJYfa33rGwRseg4eElUgsQ=="], + + "utf8-byte-length": ["utf8-byte-length@1.0.5", "https://registry.npmmirror.com/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", {}, "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA=="], + + "util-deprecate": ["util-deprecate@1.0.2", "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "v8flags": ["v8flags@2.1.1", "https://registry.npmmirror.com/v8flags/-/v8flags-2.1.1.tgz", { "dependencies": { "user-home": "^1.1.1" } }, "sha512-SKfhk/LlaXzvtowJabLZwD4K6SGRYeoxA7KJeISlUMAB/NT4CBkZjMq3WceX2Ckm4llwqYVo8TICgsDYCBU2tA=="], + + "vary": ["vary@1.1.2", "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], + + "verror": ["verror@1.10.1", "https://registry.npmmirror.com/verror/-/verror-1.10.1.tgz", { "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg=="], + + "vfile": ["vfile@6.0.3", "https://registry.npmmirror.com/vfile/-/vfile-6.0.3.tgz", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-message": ["vfile-message@4.0.3", "https://registry.npmmirror.com/vfile-message/-/vfile-message-4.0.3.tgz", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + + "vite": ["vite@7.3.1", "https://registry.npmmirror.com/vite/-/vite-7.3.1.tgz", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], + + "vite-node": ["vite-node@2.1.9", "https://registry.npmmirror.com/vite-node/-/vite-node-2.1.9.tgz", { "dependencies": { "cac": "^6.7.14", "debug": "^4.3.7", "es-module-lexer": "^1.5.4", "pathe": "^1.1.2", "vite": "^5.0.0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA=="], + + "vite-plugin-solid": ["vite-plugin-solid@2.11.10", "https://registry.npmmirror.com/vite-plugin-solid/-/vite-plugin-solid-2.11.10.tgz", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-Yr1dQybmtDtDAHkii6hXuc1oVH9CPcS/Zb2jN/P36qqcrkNnVPsMTzQ06jyzFPFjj3U1IYKMVt/9ZqcwGCEbjw=="], + + "vitefu": ["vitefu@1.1.1", "https://registry.npmmirror.com/vitefu/-/vitefu-1.1.1.tgz", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="], + + "vitest": ["vitest@2.1.9", "https://registry.npmmirror.com/vitest/-/vitest-2.1.9.tgz", { "dependencies": { "@vitest/expect": "2.1.9", "@vitest/mocker": "2.1.9", "@vitest/pretty-format": "^2.1.9", "@vitest/runner": "2.1.9", "@vitest/snapshot": "2.1.9", "@vitest/spy": "2.1.9", "@vitest/utils": "2.1.9", "chai": "^5.1.2", "debug": "^4.3.7", "expect-type": "^1.1.0", "magic-string": "^0.30.12", "pathe": "^1.1.2", "std-env": "^3.8.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.1", "tinypool": "^1.0.1", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", "vite-node": "2.1.9", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", "@vitest/browser": "2.1.9", "@vitest/ui": "2.1.9", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q=="], + + "w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "https://registry.npmmirror.com/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="], + + "wcwidth": ["wcwidth@1.0.1", "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], + + "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "https://registry.npmmirror.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], + + "webidl-conversions": ["webidl-conversions@7.0.0", "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], + + "whatwg-encoding": ["whatwg-encoding@3.1.1", "https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="], + + "whatwg-mimetype": ["whatwg-mimetype@4.0.0", "https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], + + "whatwg-url": ["whatwg-url@14.2.0", "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-14.2.0.tgz", { "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="], + + "which": ["which@2.0.2", "https://registry.npmmirror.com/which/-/which-2.0.2.tgz", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "which-module": ["which-module@2.0.1", "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz", {}, "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="], + + "why-is-node-running": ["why-is-node-running@2.3.0", "https://registry.npmmirror.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], + + "word-wrap": ["word-wrap@1.2.5", "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], + + "wrap-ansi": ["wrap-ansi@6.2.0", "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], + + "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "wrappy": ["wrappy@1.0.2", "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "ws": ["ws@8.19.0", "https://registry.npmmirror.com/ws/-/ws-8.19.0.tgz", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], + + "xml-name-validator": ["xml-name-validator@5.0.0", "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz", {}, "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg=="], + + "xmlbuilder": ["xmlbuilder@15.1.1", "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], + + "xmlchars": ["xmlchars@2.2.0", "https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="], + + "xtend": ["xtend@4.0.2", "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], + + "y18n": ["y18n@4.0.3", "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz", {}, "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="], + + "yallist": ["yallist@5.0.0", "https://registry.npmmirror.com/yallist/-/yallist-5.0.0.tgz", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + + "yargs": ["yargs@15.4.1", "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], + + "yargs-parser": ["yargs-parser@18.1.3", "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz", { "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ=="], + + "yauzl": ["yauzl@2.10.0", "https://registry.npmmirror.com/yauzl/-/yauzl-2.10.0.tgz", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="], + + "yn": ["yn@1.3.0", "https://registry.npmmirror.com/yn/-/yn-1.3.0.tgz", { "dependencies": { "object-assign": "^4.1.1" } }, "sha512-cUr+6jz1CH+E9wIGgFW5lyMMOHLbCe/UCOVqV/TTnf5XMe0NBC3TS7pR9ZpDsb84iCWKBd6ETPRBqQjssDKsIA=="], + + "yocto-queue": ["yocto-queue@0.1.0", "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], + + "zod": ["zod@3.25.76", "https://registry.npmmirror.com/zod/-/zod-3.25.76.tgz", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "https://registry.npmmirror.com/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], + + "zwitch": ["zwitch@2.0.4", "https://registry.npmmirror.com/zwitch/-/zwitch-2.0.4.tgz", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + + "@babel/core/semver": ["semver@6.3.1", "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + + "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@electron/asar/commander": ["commander@5.1.0", "https://registry.npmmirror.com/commander/-/commander-5.1.0.tgz", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="], + + "@electron/asar/glob": ["glob@7.2.3", "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + + "@electron/fuses/fs-extra": ["fs-extra@9.1.0", "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@electron/get/fs-extra": ["fs-extra@8.1.0", "https://registry.npmmirror.com/fs-extra/-/fs-extra-8.1.0.tgz", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + + "@electron/get/semver": ["semver@6.3.1", "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@electron/notarize/fs-extra": ["fs-extra@9.1.0", "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@electron/osx-sign/isbinaryfile": ["isbinaryfile@4.0.10", "https://registry.npmmirror.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz", {}, "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw=="], + + "@electron/rebuild/yargs": ["yargs@17.7.2", "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + + "@electron/universal/fs-extra": ["fs-extra@11.3.3", "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.3.3.tgz", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="], + + "@electron/universal/minimatch": ["minimatch@9.0.5", "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "@electron/windows-sign/fs-extra": ["fs-extra@11.3.3", "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.3.3.tgz", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="], + + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + + "@eslint/eslintrc/globals": ["globals@14.0.0", "https://registry.npmmirror.com/globals/-/globals-14.0.0.tgz", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], + + "@fastify/ajv-compiler/ajv": ["ajv@8.17.1", "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + + "@fastify/ajv-compiler/ajv-formats": ["ajv-formats@2.1.1", "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="], + + "@fastify/ajv-compiler/fast-uri": ["fast-uri@2.4.0", "https://registry.npmmirror.com/fast-uri/-/fast-uri-2.4.0.tgz", {}, "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA=="], + + "@fastify/cors/fastify-plugin": ["fastify-plugin@4.5.1", "https://registry.npmmirror.com/fastify-plugin/-/fastify-plugin-4.5.1.tgz", {}, "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ=="], + + "@fastify/reply-from/undici": ["undici@7.21.0", "https://registry.npmmirror.com/undici/-/undici-7.21.0.tgz", {}, "sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg=="], + + "@fastify/static/fastify-plugin": ["fastify-plugin@4.5.1", "https://registry.npmmirror.com/fastify-plugin/-/fastify-plugin-4.5.1.tgz", {}, "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ=="], + + "@isaacs/cliui/string-width": ["string-width@5.1.2", "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], + + "@isaacs/cliui/strip-ansi": ["strip-ansi@7.1.2", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.2.tgz", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], + + "@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], + + "@malept/flatpak-bundler/fs-extra": ["fs-extra@9.1.0", "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@modelcontextprotocol/sdk/ajv": ["ajv@8.17.1", "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + + "@neuralnomads/codenomad/@fastify/reply-from": ["@fastify/reply-from@9.8.0", "https://registry.npmmirror.com/@fastify/reply-from/-/reply-from-9.8.0.tgz", { "dependencies": { "@fastify/error": "^3.0.0", "end-of-stream": "^1.4.4", "fast-content-type-parse": "^1.1.0", "fast-querystring": "^1.0.0", "fastify-plugin": "^4.0.0", "toad-cache": "^3.7.0", "undici": "^5.19.1" } }, "sha512-bPNVaFhEeNI0Lyl6404YZaPFokudCplidE3QoOcr78yOy6H9sYw97p5KPYvY/NJNUHfFtvxOaSAHnK+YSiv/Mg=="], + + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "https://registry.npmmirror.com/ignore/-/ignore-7.0.5.tgz", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "accepts/mime-types": ["mime-types@3.0.2", "https://registry.npmmirror.com/mime-types/-/mime-types-3.0.2.tgz", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "ajv-formats/ajv": ["ajv@8.17.1", "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + + "anymatch/picomatch": ["picomatch@2.3.1", "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "app-builder-lib/@electron/get": ["@electron/get@3.1.0", "https://registry.npmmirror.com/@electron/get/-/get-3.1.0.tgz", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ=="], + + "app-builder-lib/ci-info": ["ci-info@4.3.1", "https://registry.npmmirror.com/ci-info/-/ci-info-4.3.1.tgz", {}, "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA=="], + + "app-builder-lib/dotenv": ["dotenv@16.6.1", "https://registry.npmmirror.com/dotenv/-/dotenv-16.6.1.tgz", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], + + "app-builder-lib/jiti": ["jiti@2.6.1", "https://registry.npmmirror.com/jiti/-/jiti-2.6.1.tgz", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + + "app-builder-lib/minimatch": ["minimatch@10.1.2", "https://registry.npmmirror.com/minimatch/-/minimatch-10.1.2.tgz", { "dependencies": { "@isaacs/brace-expansion": "^5.0.1" } }, "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw=="], + + "app-builder-lib/which": ["which@5.0.0", "https://registry.npmmirror.com/which/-/which-5.0.0.tgz", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], + + "avvio/@fastify/error": ["@fastify/error@3.4.1", "https://registry.npmmirror.com/@fastify/error/-/error-3.4.1.tgz", {}, "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ=="], + + "babel-plugin-jsx-dom-expressions/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="], + + "body-parser/http-errors": ["http-errors@2.0.1", "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.1.tgz", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + + "body-parser/iconv-lite": ["iconv-lite@0.7.2", "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.7.2.tgz", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], + + "builder-util/app-builder-bin": ["app-builder-bin@5.0.0-alpha.12", "https://registry.npmmirror.com/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz", {}, "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w=="], + + "builder-util/source-map-support": ["source-map-support@0.5.21", "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + + "chokidar/glob-parent": ["glob-parent@5.1.2", "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "cliui/strip-ansi": ["strip-ansi@6.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "clone-response/mimic-response": ["mimic-response@1.0.1", "https://registry.npmmirror.com/mimic-response/-/mimic-response-1.0.1.tgz", {}, "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="], + + "cssstyle/rrweb-cssom": ["rrweb-cssom@0.8.0", "https://registry.npmmirror.com/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="], + + "dotenv-expand/dotenv": ["dotenv@16.6.1", "https://registry.npmmirror.com/dotenv/-/dotenv-16.6.1.tgz", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], + + "electron/@types/node": ["@types/node@22.19.9", "https://registry.npmmirror.com/@types/node/-/node-22.19.9.tgz", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-PD03/U8g1F9T9MI+1OBisaIARhSzeidsUjQaf51fOxrfjeiKN9bLVO06lHuHYjxdnqLWJijJHfqXPSJri2EM2A=="], + + "electron-builder/yargs": ["yargs@17.7.2", "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + + "electron-publish/mime": ["mime@2.6.0", "https://registry.npmmirror.com/mime/-/mime-2.6.0.tgz", { "bin": { "mime": "cli.js" } }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="], + + "electron-winstaller/fs-extra": ["fs-extra@7.0.1", "https://registry.npmmirror.com/fs-extra/-/fs-extra-7.0.1.tgz", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="], + + "express/content-disposition": ["content-disposition@1.0.1", "https://registry.npmmirror.com/content-disposition/-/content-disposition-1.0.1.tgz", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="], + + "express/mime-types": ["mime-types@3.0.2", "https://registry.npmmirror.com/mime-types/-/mime-types-3.0.2.tgz", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "fast-glob/glob-parent": ["glob-parent@5.1.2", "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "fast-json-stringify/ajv": ["ajv@8.17.1", "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + + "fast-json-stringify/fast-uri": ["fast-uri@2.4.0", "https://registry.npmmirror.com/fast-uri/-/fast-uri-2.4.0.tgz", {}, "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA=="], + + "fastify/@fastify/error": ["@fastify/error@3.4.1", "https://registry.npmmirror.com/@fastify/error/-/error-3.4.1.tgz", {}, "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ=="], + + "fastify/fast-content-type-parse": ["fast-content-type-parse@1.1.0", "https://registry.npmmirror.com/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz", {}, "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ=="], + + "filelist/minimatch": ["minimatch@5.1.6", "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], + + "glob/minimatch": ["minimatch@9.0.5", "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "hosted-git-info/lru-cache": ["lru-cache@6.0.0", "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], + + "http-errors/statuses": ["statuses@2.0.1", "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], + + "micromatch/picomatch": ["picomatch@2.3.1", "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "minipass-flush/minipass": ["minipass@3.3.6", "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-pipeline/minipass": ["minipass@3.3.6", "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-sized/minipass": ["minipass@3.3.6", "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "node-gyp/which": ["which@5.0.0", "https://registry.npmmirror.com/which/-/which-5.0.0.tgz", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], + + "ora/strip-ansi": ["strip-ansi@6.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "pino/process-warning": ["process-warning@5.0.0", "https://registry.npmmirror.com/process-warning/-/process-warning-5.0.0.tgz", {}, "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA=="], + + "postject/commander": ["commander@9.5.0", "https://registry.npmmirror.com/commander/-/commander-9.5.0.tgz", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="], + + "proper-lockfile/signal-exit": ["signal-exit@3.0.7", "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "qrcode/pngjs": ["pngjs@5.0.0", "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz", {}, "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="], + + "raw-body/http-errors": ["http-errors@2.0.1", "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.1.tgz", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + + "raw-body/iconv-lite": ["iconv-lite@0.7.2", "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.7.2.tgz", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], + + "readdirp/picomatch": ["picomatch@2.3.1", "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "restore-cursor/signal-exit": ["signal-exit@3.0.7", "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "send/http-errors": ["http-errors@2.0.1", "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.1.tgz", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + + "send/mime-types": ["mime-types@3.0.2", "https://registry.npmmirror.com/mime-types/-/mime-types-3.0.2.tgz", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "string-width/strip-ansi": ["strip-ansi@6.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "sucrase/commander": ["commander@4.1.1", "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], + + "temp/rimraf": ["rimraf@2.6.3", "https://registry.npmmirror.com/rimraf/-/rimraf-2.6.3.tgz", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "./bin.js" } }, "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="], + + "tiny-async-pool/semver": ["semver@5.7.2", "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="], + + "ts-node/chalk": ["chalk@1.1.3", "https://registry.npmmirror.com/chalk/-/chalk-1.1.3.tgz", { "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A=="], + + "tsconfig/strip-json-comments": ["strip-json-comments@2.0.1", "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], + + "tsx/esbuild": ["esbuild@0.27.3", "https://registry.npmmirror.com/esbuild/-/esbuild-0.27.3.tgz", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], + + "type-is/mime-types": ["mime-types@3.0.2", "https://registry.npmmirror.com/mime-types/-/mime-types-3.0.2.tgz", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "vite/esbuild": ["esbuild@0.27.3", "https://registry.npmmirror.com/esbuild/-/esbuild-0.27.3.tgz", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], + + "vite-node/vite": ["vite@5.4.21", "https://registry.npmmirror.com/vite/-/vite-5.4.21.tgz", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], + + "vitest/vite": ["vite@5.4.21", "https://registry.npmmirror.com/vite/-/vite-5.4.21.tgz", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], + + "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "yargs/find-up": ["find-up@4.1.0", "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + + "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + + "@electron/get/fs-extra/jsonfile": ["jsonfile@4.0.0", "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + + "@electron/get/fs-extra/universalify": ["universalify@0.1.2", "https://registry.npmmirror.com/universalify/-/universalify-0.1.2.tgz", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + + "@electron/rebuild/yargs/cliui": ["cliui@8.0.1", "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + + "@electron/rebuild/yargs/y18n": ["y18n@5.0.8", "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "@electron/rebuild/yargs/yargs-parser": ["yargs-parser@21.1.1", "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + + "@electron/universal/minimatch/brace-expansion": ["brace-expansion@2.0.2", "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "@fastify/ajv-compiler/ajv/fast-uri": ["fast-uri@3.1.0", "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.1.0.tgz", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], + + "@fastify/ajv-compiler/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], + + "@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "@modelcontextprotocol/sdk/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "@neuralnomads/codenomad/@fastify/reply-from/@fastify/error": ["@fastify/error@3.4.1", "https://registry.npmmirror.com/@fastify/error/-/error-3.4.1.tgz", {}, "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ=="], + + "@neuralnomads/codenomad/@fastify/reply-from/fast-content-type-parse": ["fast-content-type-parse@1.1.0", "https://registry.npmmirror.com/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz", {}, "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ=="], + + "@neuralnomads/codenomad/@fastify/reply-from/fastify-plugin": ["fastify-plugin@4.5.1", "https://registry.npmmirror.com/fastify-plugin/-/fastify-plugin-4.5.1.tgz", {}, "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ=="], + + "@neuralnomads/codenomad/@fastify/reply-from/undici": ["undici@5.29.0", "https://registry.npmmirror.com/undici/-/undici-5.29.0.tgz", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="], + + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "accepts/mime-types/mime-db": ["mime-db@1.54.0", "https://registry.npmmirror.com/mime-db/-/mime-db-1.54.0.tgz", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "app-builder-lib/@electron/get/fs-extra": ["fs-extra@8.1.0", "https://registry.npmmirror.com/fs-extra/-/fs-extra-8.1.0.tgz", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + + "app-builder-lib/@electron/get/semver": ["semver@6.3.1", "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "app-builder-lib/which/isexe": ["isexe@3.1.2", "https://registry.npmmirror.com/isexe/-/isexe-3.1.2.tgz", {}, "sha512-mIcis6w+JiQf3P7t7mg/35GKB4T1FQsBOtMIvuKw4YErj5RjtbhcTd5/I30fmkmGMwvI0WlzSNN+27K0QCMkAw=="], + + "builder-util/source-map-support/source-map": ["source-map@0.6.1", "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + + "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "electron-builder/yargs/cliui": ["cliui@8.0.1", "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + + "electron-builder/yargs/y18n": ["y18n@5.0.8", "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "electron-builder/yargs/yargs-parser": ["yargs-parser@21.1.1", "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + + "electron-winstaller/fs-extra/jsonfile": ["jsonfile@4.0.0", "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + + "electron-winstaller/fs-extra/universalify": ["universalify@0.1.2", "https://registry.npmmirror.com/universalify/-/universalify-0.1.2.tgz", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + + "electron/@types/node/undici-types": ["undici-types@6.21.0", "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "express/mime-types/mime-db": ["mime-db@1.54.0", "https://registry.npmmirror.com/mime-db/-/mime-db-1.54.0.tgz", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "fast-json-stringify/ajv/fast-uri": ["fast-uri@3.1.0", "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.1.0.tgz", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], + + "fast-json-stringify/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "filelist/minimatch/brace-expansion": ["brace-expansion@2.0.2", "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "hosted-git-info/lru-cache/yallist": ["yallist@4.0.0", "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "minipass-flush/minipass/yallist": ["yallist@4.0.0", "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "minipass-pipeline/minipass/yallist": ["yallist@4.0.0", "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "minipass-sized/minipass/yallist": ["yallist@4.0.0", "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "node-gyp/which/isexe": ["isexe@3.1.2", "https://registry.npmmirror.com/isexe/-/isexe-3.1.2.tgz", {}, "sha512-mIcis6w+JiQf3P7t7mg/35GKB4T1FQsBOtMIvuKw4YErj5RjtbhcTd5/I30fmkmGMwvI0WlzSNN+27K0QCMkAw=="], + + "ora/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "send/mime-types/mime-db": ["mime-db@1.54.0", "https://registry.npmmirror.com/mime-db/-/mime-db-1.54.0.tgz", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "temp/rimraf/glob": ["glob@7.2.3", "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + + "ts-node/chalk/ansi-styles": ["ansi-styles@2.2.1", "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-2.2.1.tgz", {}, "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA=="], + + "ts-node/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "ts-node/chalk/supports-color": ["supports-color@2.0.0", "https://registry.npmmirror.com/supports-color/-/supports-color-2.0.0.tgz", {}, "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g=="], + + "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], + + "tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.27.3.tgz", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], + + "tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="], + + "tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.27.3.tgz", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="], + + "tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="], + + "tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="], + + "tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="], + + "tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="], + + "tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="], + + "tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="], + + "tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="], + + "tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="], + + "tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="], + + "tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="], + + "tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="], + + "tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="], + + "tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="], + + "tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", { "os": "none", "cpu": "arm64" }, "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA=="], + + "tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="], + + "tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", { "os": "openbsd", "cpu": "arm64" }, "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw=="], + + "tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="], + + "tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", { "os": "none", "cpu": "arm64" }, "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g=="], + + "tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="], + + "tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="], + + "tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="], + + "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], + + "type-is/mime-types/mime-db": ["mime-db@1.54.0", "https://registry.npmmirror.com/mime-db/-/mime-db-1.54.0.tgz", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "vite-node/vite/esbuild": ["esbuild@0.21.5", "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], + + "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.27.3.tgz", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], + + "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="], + + "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.27.3.tgz", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="], + + "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="], + + "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="], + + "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="], + + "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="], + + "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="], + + "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="], + + "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="], + + "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="], + + "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="], + + "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="], + + "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="], + + "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="], + + "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="], + + "vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", { "os": "none", "cpu": "arm64" }, "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA=="], + + "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="], + + "vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", { "os": "openbsd", "cpu": "arm64" }, "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw=="], + + "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="], + + "vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", { "os": "none", "cpu": "arm64" }, "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g=="], + + "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="], + + "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="], + + "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="], + + "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], + + "vitest/vite/esbuild": ["esbuild@0.21.5", "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "yargs/find-up/locate-path": ["locate-path@5.0.0", "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + + "@electron/rebuild/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "@electron/rebuild/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "app-builder-lib/@electron/get/fs-extra/jsonfile": ["jsonfile@4.0.0", "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + + "app-builder-lib/@electron/get/fs-extra/universalify": ["universalify@0.1.2", "https://registry.npmmirror.com/universalify/-/universalify-0.1.2.tgz", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + + "electron-builder/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "electron-builder/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "vite-node/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "vite-node/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "vite-node/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "vite-node/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "vite-node/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "vite-node/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "vite-node/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "vite-node/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "vite-node/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "vite-node/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "vite-node/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "vite-node/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "vite-node/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "vite-node/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "vite-node/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "vite-node/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "vite-node/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "vite-node/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "vite-node/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "vite-node/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "vite-node/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "vite-node/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "vite-node/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + + "vitest/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "vitest/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "vitest/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "vitest/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "vitest/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "vitest/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "vitest/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "vitest/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "vitest/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "vitest/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "vitest/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "vitest/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "vitest/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "vitest/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "vitest/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "vitest/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "vitest/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "vitest/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "vitest/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "vitest/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "vitest/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "vitest/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "vitest/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + + "yargs/find-up/locate-path/p-locate": ["p-locate@4.1.0", "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + + "@electron/rebuild/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "electron-builder/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "yargs/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + } +} diff --git a/dev-docs/askquestion-integration.md b/dev-docs/askquestion-integration.md new file mode 100644 index 00000000..01b6ffe9 --- /dev/null +++ b/dev-docs/askquestion-integration.md @@ -0,0 +1,1596 @@ +# AskQuestion Tool Integration + +## Document Overview + +This document provides comprehensive documentation for integrating the `askquestion` tool from shuvcode into CodeNomad. It covers research findings, architecture analysis, approach evaluation, and detailed implementation plan. + +**Status:** ✅ **COMPLETE & FUNCTIONAL** +**Approach:** Minimal Integration (SDK Passthrough) +**Started:** 2026-01-10 +**Phase 1 Completed:** 2026-01-10 +**Phase 2 Completed:** 2026-01-10 +**Phase 3 Completed:** 2026-01-10 +**Author:** AI Assistant + +## Implementation Status + +### ✅ Phase 1: Frontend Component (COMPLETE) +- [x] Created question type definitions (`types/question.ts`) +- [x] Created question store for queue management (`stores/questions.ts`) +- [x] Ported AskQuestionWizard component from shuvcode (`components/askquestion-wizard.tsx`) +- [x] Created stylesheet with CodeNomad design tokens (`styles/components/askquestion-wizard.css`) +- [x] Added CSS import to controls.css + +**Files Created:** +- `packages/ui/src/types/question.ts` (47 lines) +- `packages/ui/src/stores/questions.ts` (85 lines) +- `packages/ui/src/components/askquestion-wizard.tsx` (457 lines) +- `packages/ui/src/styles/components/askquestion-wizard.css` (302 lines) + +**Files Modified:** +- `packages/ui/src/styles/controls.css` (added import) + +### ✅ Phase 2: Integration (COMPLETE) +- [x] Updated SSE event handler for question events +- [x] Integrated wizard into workspace page +- [x] Wired up OpenCode SDK calls (reply/reject) +- [x] Added error handling and retry logic +- [x] Handled session abort and edge cases (auto open/close) + +**Files Modified:** +- `packages/ui/src/lib/sse-manager.ts` (+18 lines) + - Added `question.asked`, `question.replied`, `question.rejected` event types + - Added event handler callbacks +- `packages/ui/src/stores/instances.ts` (+25 lines) + - Added question store imports + - Wired up SSE callbacks to question queue + - Added cleanup on instance removal +- `packages/ui/src/components/instance/instance-shell2.tsx` (+68 lines) + - Integrated AskQuestionWizard component + - Added auto-open/close logic with createEffect + - Implemented submit/cancel handlers using OpenCode SDK + - Added proper error handling + +**Integration Details:** +- Zero backend changes required ✅ +- Uses existing SSE infrastructure ✅ +- Direct SDK integration for reply/reject ✅ +- Automatic wizard open/close based on question state ✅ + +### 🚨 CRITICAL BLOCKER RESOLVED: SDK Version Outdated (2026-01-10) + +**Status:** ✅ **RESOLVED** + +**Problem:** The OpenCode SDK v1.1.1 didn't include the `question` namespace on the client. + +**Root Cause:** +```typescript +// SDK v1.1.1 - Missing question namespace +export declare class OpencodeClient extends HeyApiClient { + global: Global; + project: Project; + // ... other namespaces + // ❌ question: Question; // <- MISSING! +} + +// SDK v1.1.12 - Has question namespace +export declare class OpencodeClient extends HeyApiClient { + global: Global; + project: Project; + // ... other namespaces + question: Question; // ✅ NOW PRESENT! +} +``` + +**Solution Applied:** +1. Updated `packages/ui/package.json`: `"@opencode-ai/sdk": "1.1.1"` → `"@opencode-ai/sdk": "1.1.12"` +2. Ran `pnpm up @opencode-ai/sdk@1.1.12 --filter @codenomad/ui` +3. Verified `Question` class exists with `list()`, `reply()`, `reject()` methods +4. Removed type cast `(client as any)` → now properly typed as `client.question` +5. Removed all debug console.log statements + +**Verification:** +```bash +$ cat packages/ui/node_modules/@opencode-ai/sdk/dist/v2/gen/sdk.gen.d.ts | grep -A5 "class Question" +export declare class Question extends HeyApiClient { + reply(parameters: { + requestID: string; + directory?: string; + answers?: Array; + }, options?: Options): ... +``` + +**Test Results:** All functionality working perfectly ✅ + +### ✅ Phase 3: Resolution & Testing (COMPLETE) + +#### 🎉 Root Cause Identified & Fixed + +**Problem:** `client.question` was `undefined` because CodeNomad was using an outdated SDK version. + +**Solution:** +- ✅ Updated SDK from v1.1.1 → v1.1.12 +- ✅ Verified `question` namespace now exists on `OpencodeClient` +- ✅ Removed all debug console.log statements +- ✅ Changed SDK client type cast from `(client as any).question` to `client.question` + +**SDK Version Comparison:** + +| SDK Version | Has `question` namespace? | Methods Available | +| ----------- | ------------------------- | -------------------------- | +| v1.1.1 | ❌ No | N/A | +| v1.1.12 | ✅ Yes | `list()`, `reply()`, `reject()` | + +**Files Modified:** +- `packages/ui/package.json` - Updated SDK dependency +- `packages/ui/src/components/instance/instance-shell2.tsx` - Removed debug logs, fixed type cast +- `packages/ui/src/components/askquestion-wizard.tsx` - Removed debug logs + +#### ✅ Testing Results + +**Manual Testing - All Features Working:** +- [x] Question wizard appears when agent calls askquestion +- [x] All questions visible in tabs +- [x] Can select single-choice option +- [x] Can type custom text input +- [x] Submit button works and sends answers to backend +- [x] Answers submitted successfully via SDK +- [x] Agent receives answers and continues execution +- [x] Wizard closes after submission +- [x] Cancel button works (reject question) +- [x] Custom text-only answer works +- [x] Styling matches CodeNomad theme + +**Test Console Output (Success):** +``` +[AskQuestionWizard] selectOption called {optionLabel: 'Code review', multiple: false} +[AskQuestionWizard] handleSubmit called {allAnswered: true} +[AskQuestionWizard] Submitting answers: [{"questionId":"que_ba870e52d0019iR7Lo69IfDDyQ-0","values":["Code review"]}] +[QUESTION] handleQuestionSubmit called {answers: Array(1)} +[QUESTION] Submitting question answers {requestID: 'que_ba870e52d0019iR7Lo69IfDDyQ', answersCount: 1} +[QUESTION] SDK answers mapped {sdkAnswers: Array(1)} +[QUESTION] Question reply successful ✅ +``` + +**Custom Text Input Test (Success):** +``` +Submitting answers: [{"questionId":"que_ba8714d35001o8iEDfgmSdDIsp-0","values":[],"customText":"Test to output what I just type here \"Testing 123456789\""}] +[QUESTION] SDK answers mapped {sdkAnswers: [["Test to output what I just type here \"Testing 123456789\""]]} +[QUESTION] Question reply successful ✅ +``` + +### ⏳ Phase 4: Polish (PENDING) +- [ ] Add keyboard shortcuts documentation +- [ ] Mobile UX improvements +- [ ] Performance profiling +- [ ] User documentation + + +--- + +## Table of Contents + +1. [Research & Discovery](#research--discovery) +2. [Architecture Analysis](#architecture-analysis) +3. [Approach Evaluation](#approach-evaluation) +4. [Implementation Plan](#implementation-plan) +5. [Testing Strategy](#testing-strategy) +6. [Risk Assessment](#risk-assessment) + +--- + +## Research & Discovery + +### Background + +The `askquestion` tool is a feature in shuvcode (an OpenCode-based project) that allows AI agents to pause execution and ask the user multiple-choice questions in an interactive wizard interface. Once the user responds, the agent receives the answers and continues execution. + +This is fundamentally different from regular chat interactions because: +- The agent **blocks/pauses** waiting for answers +- Questions are **structured** with pre-defined options +- UI is a **multi-tab wizard** rather than chat messages +- User can provide **custom text** in addition to selecting from options + +### Research Methodology + +1. **Cloned shuvcode repository** to `shuvcode-analysis/` +2. **Analyzed key files:** + - `packages/opencode/src/askquestion/index.ts` - Core state management + - `packages/opencode/src/tool/askquestion.ts` - Tool implementation + - `packages/app/src/components/askquestion-wizard.tsx` - UI component + - `packages/app/src/pages/session.tsx` - Integration point + - `packages/sdk/js/src/v2/gen/sdk.gen.ts` - SDK APIs + - `packages/sdk/js/src/v2/gen/types.gen.ts` - Type definitions +3. **Traced event flow** from tool call → user interaction → response + +### Key Findings + +#### 1. **OpenCode SDK Exposes Question APIs** ✅ + +Most critical discovery: OpenCode SDK natively supports questions! + +```typescript +// From @opencode-ai/sdk +export class Question extends HeyApiClient { + // List all pending questions + public list(parameters?: { directory?: string }): Promise + + // Reply to a question + public reply(parameters: { + requestID: string + directory?: string + answers?: Array // Array of string arrays + }): Promise + + // Reject a question + public reject(parameters: { + requestID: string + directory?: string + }): Promise +} +``` + +**Implication:** We don't need to build custom backend routes! We can use the SDK directly from the UI. + +#### 2. **Event-Driven Architecture** + +Questions flow through OpenCode's event system: + +| Event Type | Direction | Trigger | Payload | +| ------------------- | ------------------ | ---------------------------- | -------------------------------------- | +| `question.asked` | Backend → Frontend | Agent calls askquestion tool | `QuestionRequest` with questions array | +| `question.replied` | Frontend → Backend | User submits answers | Request ID + answers array | +| `question.rejected` | Frontend → Backend | User cancels | Request ID | + +**Implication:** CodeNomad's existing SSE infrastructure already receives these events. + +#### 3. **Tool Execution Flow** + +```mermaid +sequenceDiagram + participant Agent + participant Tool as AskQuestion Tool + participant State as Question State + participant Bus as Event Bus + participant UI as Frontend + participant User + + Agent->>Tool: Call askquestion(questions) + Tool->>State: register(callID, questions) + Note over State: Creates Promise
Stores resolve/reject + Tool->>Bus: Emit question.asked + Bus->>UI: SSE Event + UI->>User: Show Wizard + User->>UI: Submit Answers + UI->>Tool: SDK.reply(answers) + Tool->>State: resolve(answers) + State-->>Agent: Return answers + Agent->>Agent: Continue execution +``` + +**Key Insight:** The tool execution **blocks** on a Promise that resolves when the user responds. This is how the agent pauses reliably. + +#### 4. **Question Schema** + +```typescript +interface Question { + id: string // Unique identifier + label: string // Short tab label (e.g., "UI Framework") + question: string // Full question text + options: QuestionOption[] // 2-8 options + multiSelect?: boolean // Allow multiple selections +} + +interface QuestionOption { + value: string // Short identifier + label: string // Display text + description?: string // Optional help text +} + +interface QuestionAnswer { + questionId: string + values: string[] // Selected option values + customText?: string // Custom response if typed +} +``` + +**Constraints:** +- 1-6 questions per wizard +- 2-8 options per question +- Custom text always allowed +- Single or multi-select per question + +#### 5. **UI Component Features** + +The `AskQuestionWizard` component provides: + +**Navigation:** +- Tab-based multi-question flow +- Arrow keys navigate options +- Tab/Shift+Tab switch questions +- Number keys (1-8) quick select + +**Interaction:** +- Single-select: auto-advances to next question +- Multi-select: Space toggles, Enter confirms +- "Type something..." option for custom text +- Submit when all questions answered + +**Visual Feedback:** +- Answered questions marked with checkmark +- Active tab highlighted +- Selected options highlighted +- Progress indication + +--- + +## Architecture Analysis + +### How Shuvcode Implements AskQuestion + +#### Backend Layer (OpenCode) + +**File: `packages/opencode/src/askquestion/index.ts`** + +State management module: + +```typescript +export namespace AskQuestion { + // Global map of pending requests + const pendingRequests = new Map() + + // Register a new question request + export function register( + callID: string, + sessionID: string, + messageID: string, + questions: Question[] + ): Promise { + return new Promise((resolve, reject) => { + pendingRequests.set(callID, { + sessionID, messageID, callID, questions, + resolve, reject + }) + }) + } + + // Respond to a request (called by frontend) + export function respond(callID: string, answers: Answer[]): boolean { + const pending = pendingRequests.get(callID) + if (!pending) return false + pending.resolve(answers) + pendingRequests.delete(callID) + return true + } + + // Cancel/reject a request + export function cancel(callID: string): boolean { + const pending = pendingRequests.get(callID) + if (!pending) return false + pending.reject(new Error("User cancelled")) + pendingRequests.delete(callID) + return true + } +} +``` + +**Key Points:** +- Uses Promise-based blocking +- Stores callbacks (resolve/reject) in a Map +- Publishes bus events for state changes +- Cleans up after response/cancellation + +**File: `packages/opencode/src/tool/askquestion.ts`** + +Tool definition: + +```typescript +export const AskQuestionTool = Tool.define("askquestion", { + parameters: z.object({ + questions: z.array(QuestionSchema).min(1).max(6) + }), + + async execute(params, ctx) { + // Register and wait + const answerPromise = AskQuestion.register( + ctx.callID, + ctx.sessionID, + ctx.messageID, + params.questions + ) + + // This blocks until user responds! + const answers = await answerPromise + + // Format and return + return { output: formatAnswers(answers) } + } +}) +``` + +**Key Point:** Tool execution is `async` and awaits the Promise, effectively pausing agent execution. + +#### Frontend Layer (App) + +**File: `packages/app/src/pages/session.tsx`** + +Integration with session page: + +```typescript +// Track pending questions from SSE +const pendingAskQuestion = createMemo(() => { + const requests = sync.data.question[params.id ?? ""] ?? [] + return requests[0]?.questions || null +}) + +// Submit handler +const handleAskQuestionSubmit = async (answers: AskQuestionAnswer[]) => { + const pending = pendingAskQuestion() + if (!pending) return + + const mapped = answers.map(a => ({ + questionId: a.questionId, + values: a.customText ? [a.customText] : a.values + })) + + await sdk.client.question.reply({ + requestID: pending.requestID, + answers: mapped + }) +} + +// Cancel handler +const handleAskQuestionCancel = async () => { + await sdk.client.question.reject({ + requestID: pending.requestID + }) +} +``` + +**Key Points:** +- Questions stored in sync state (populated by SSE) +- Uses OpenCode SDK's `question.reply()` and `question.reject()` +- Maps UI answers to SDK format + +**File: `packages/app/src/components/askquestion-wizard.tsx`** + +566-line wizard component with: +- Tab navigation state management +- Option selection logic +- Custom text input mode +- Keyboard event handling +- Answer state tracking +- Validation (all questions answered) + +### How CodeNomad Currently Works + +#### Backend (Server Package) + +**Architecture:** +``` +packages/server/ +├── src/ +│ ├── server/ +│ │ ├── index.ts # Express server +│ │ ├── routes/ # API routes +│ │ └── workspace-manager.ts # OpenCode instance management +│ ├── api-types.ts # Type definitions +│ └── index.ts # Main entry +``` + +**Workspace Manager:** +- Spawns OpenCode processes per workspace +- Proxies HTTP requests to instances +- Streams SSE events from instances +- Manages instance lifecycle + +**SSE Event Flow:** +``` +OpenCode Instance (port 3001) + ↓ SSE Stream +Workspace Manager + ↓ Transform & Filter +CodeNomad Server (port 3000) + ↓ /api/events +Frontend Clients +``` + +**Current Event Types:** +- `workspace.created` +- `workspace.started` +- `workspace.error` +- `instance.event` (proxied OpenCode events) +- `instance.eventStatus` +- etc. + +#### Frontend (UI Package) + +**Architecture:** +``` +packages/ui/ +├── src/ +│ ├── pages/ +│ │ └── workspace.tsx # Main workspace page +│ ├── components/ +│ │ ├── session-view.tsx # Session display +│ │ ├── message-list.tsx # Message rendering +│ │ └── ... +│ ├── stores/ +│ │ └── ... # Solid.js signals/stores +│ └── styles/ +│ └── ... +``` + +**SSE Integration:** + +CodeNomad already has SSE event handling: + +```typescript +// Existing SSE connection +const eventSource = new EventSource('/api/events') + +eventSource.addEventListener('message', (event) => { + const data = JSON.parse(event.data) + + // Handle different event types + switch (data.type) { + case 'instance.event': + handleInstanceEvent(data.event) + break + // ... other cases + } +}) +``` + +**OpenCode SDK Usage:** + +CodeNomad already uses the OpenCode SDK: + +```typescript +import { createOpencodeClient } from '@opencode-ai/sdk' + +const client = createOpencodeClient({ + baseURL: `http://localhost:${workspacePort}` +}) + +// Used for session operations +await client.session.prompt({ ... }) +await client.session.list({ ... }) +``` + +### Integration Points + +Based on the architecture analysis, here are the integration points: + +| Component | Current State | Required Changes | +| ------------------------ | ------------------------------------ | ------------------------------------------ | +| **Backend SSE** | Already streams OpenCode events | ✅ No changes (events already flow through) | +| **Backend API** | Has routes for sessions, files, etc. | ✅ No changes (use SDK directly) | +| **Frontend SSE Handler** | Listens to `instance.event` | ✅ Add case for `question.asked` | +| **Frontend SDK Client** | Instantiated per workspace | ✅ Already has `client.question.*` | +| **Frontend UI** | Session view, message list, etc. | ➕ Add `AskQuestionWizard` component | +| **Frontend State** | Signals for sessions, messages | ➕ Add signal for `pendingQuestion` | + +**Key Insight:** Minimal changes needed! Most infrastructure already exists. + +--- + +## Approach Evaluation + +We evaluated three approaches: + +### Approach 1: Full Integration + +Build custom backend routes that proxy question requests. + +**Pros:** +- Complete control over flow +- Can add custom features +- Consistent with permissions architecture + +**Cons:** +- 2-3 weeks implementation +- Duplicate OpenCode's logic +- More code to maintain +- State synchronization complexity + +**Reliability: 9/10** (if implemented perfectly) + +### Approach 2: Minimal Integration ✅ **CHOSEN** + +Use OpenCode SDK directly from frontend. + +**Pros:** +- 5 days implementation +- Less code (90% less backend) +- Uses proven OpenCode APIs +- Leverages existing SSE infrastructure +- Same wizard UI as Full Integration + +**Cons:** +- Less control over advanced features +- Dependent on SDK stability + +**Reliability: 8/10** (using battle-tested SDK) + +### Approach 3: Iframe Embedding + +Embed OpenCode's native UI. + +**Status:** ❌ **NOT FEASIBLE** + +OpenCode doesn't expose a web UI suitable for embedding. + +### Decision: Minimal Integration + +**Rationale:** + +1. **Same User Experience** - Both approaches use identical wizard UI +2. **10x Faster** - 5 days vs 15+ days +3. **More Reliable** - Fewer custom components, using proven SDK +4. **Easier Maintenance** - Less code surface area +5. **Lower Risk** - Fewer moving parts = fewer bugs +6. **Future-Proof** - Can upgrade to Full Integration later if needed + +**When to upgrade to Full Integration:** +- Need question analytics/logging in CodeNomad +- Want offline question caching +- Need custom approval workflows +- Want multi-workspace question aggregation + +For initial implementation, these are premature optimizations. + +--- + +## Implementation Plan + +### Phase 1: Frontend Component (Days 1-3) + +#### Task 1.1: Port AskQuestionWizard Component + +**File:** `packages/ui/src/components/askquestion-wizard.tsx` + +**Actions:** +1. Copy component from shuvcode +2. Update imports for CodeNomad's UI library +3. Adapt SolidJS patterns to match CodeNomad conventions +4. Remove shuvcode-specific dependencies + +**Type Definitions:** +```typescript +export interface AskQuestionOption { + value: string + label: string + description?: string +} + +export interface AskQuestionQuestion { + id: string + label: string // Short tab label + question: string // Full question + options: AskQuestionOption[] + multiSelect?: boolean +} + +export interface AskQuestionAnswer { + questionId: string + values: string[] + customText?: string +} + +export interface AskQuestionWizardProps { + questions: AskQuestionQuestion[] + onSubmit: (answers: AskQuestionAnswer[]) => void + onCancel: () => void +} +``` + +**Component Structure:** +```tsx +export function AskQuestionWizard(props: AskQuestionWizardProps) { + // State management + const [store, setStore] = createStore({ + activeTab: 0, + questionStates: [...], + isTypingCustom: false, + customInputValue: "" + }) + + // Computed values + const currentQuestion = createMemo(...) + const allAnswered = createMemo(...) + + // Event handlers + function selectOption(value: string) { ... } + function navigateQuestion(direction) { ... } + function handleKeyDown(event) { ... } + function submitCustomInput() { ... } + + // Render + return ( +
+ {/* Tab navigation */} + {/* Current question */} + {/* Options list */} + {/* Custom input */} + {/* Submit button */} +
+ ) +} +``` + +**Estimated Time:** 1.5 days + +#### Task 1.2: Create Stylesheet + +**File:** `packages/ui/src/styles/components/askquestion-wizard.css` + +**Actions:** +1. Extract styles from shuvcode component +2. Convert to CodeNomad design tokens +3. Ensure mobile responsiveness +4. Add dark mode support (if applicable) + +**Design Token Mapping:** +```css +/* Use existing CodeNomad tokens */ +.askquestion-wizard { + background: var(--surface-base); + border: 1px solid var(--border-weak-base); + border-radius: var(--radius-md); + padding: var(--spacing-4); +} + +.wizard-tab { + color: var(--text-base); + background: var(--surface-stronger); +} + +.wizard-tab.active { + color: var(--text-strong); + font-weight: var(--font-semibold); +} + +.wizard-option { + padding: var(--spacing-2) var(--spacing-3); + border-radius: var(--radius-sm); +} + +.wizard-option.selected { + background: var(--primary); + color: var(--text-on-primary); +} +``` + +**Import in aggregator:** +```css +/* packages/ui/src/styles/components.css */ +@import './components/askquestion-wizard.css'; +``` + +**Estimated Time:** 0.5 days + +#### Task 1.3: Add Question State Management + +**File:** `packages/ui/src/stores/question-store.ts` (new file) + +**Actions:** +1. Create Solid.js signal for pending question +2. Add helper functions for question lifecycle + +**Implementation:** +```typescript +import { createSignal } from 'solid-js' + +export interface PendingQuestion { + requestID: string + sessionID: string + questions: AskQuestionQuestion[] +} + +const [pendingQuestion, setPendingQuestion] = createSignal(null) + +export function usePendingQuestion() { + return [pendingQuestion, setPendingQuestion] as const +} + +export function clearPendingQuestion() { + setPendingQuestion(null) +} + +export function setPending(request: PendingQuestion) { + setPendingQuestion(request) +} +``` + +**Estimated Time:** 0.5 days + +#### Task 1.4: Update SSE Event Handler + +**File:** `packages/ui/src/context/sse.tsx` or wherever SSE is handled + +**Actions:** +1. Add case for `question.asked` events +2. Add case for `question.replied`/`question.rejected` events + +**Implementation:** +```typescript +import { setPending, clearPendingQuestion } from '@/stores/question-store' + +// In SSE message handler +function handleInstanceEvent(event: any) { + switch (event.type) { + case 'question.asked': + const questionRequest: PendingQuestion = { + requestID: event.properties.id, + sessionID: event.properties.sessionID, + questions: event.properties.questions.map((q: any) => ({ + id: q.id, + label: q.label || q.header, // Handle both formats + question: q.question, + options: q.options, + multiSelect: q.multiSelect || q.multiple + })) + } + setPending(questionRequest) + break + + case 'question.replied': + case 'question.rejected': + clearPendingQuestion() + break + + // ... existing cases + } +} +``` + +**Estimated Time:** 0.5 days + +### Phase 2: Integration (Days 4-5) + +#### Task 2.1: Integrate Wizard into Workspace Page + +**File:** `packages/ui/src/pages/workspace.tsx` + +**Actions:** +1. Import wizard component +2. Import question store +3. Add wizard overlay +4. Wire up submit/cancel handlers + +**Implementation:** +```tsx +import { AskQuestionWizard } from '@/components/askquestion-wizard' +import { usePendingQuestion } from '@/stores/question-store' +import { createOpencodeClient } from '@opencode-ai/sdk' + +export function WorkspacePage() { + const [pendingQuestion, setPendingQuestion] = usePendingQuestion() + + // Get OpenCode SDK client for current workspace + const opencodeClient = createMemo(() => { + const workspace = currentWorkspace() + if (!workspace) return null + return createOpencodeClient({ + baseURL: `http://localhost:${workspace.port}` + }) + }) + + async function handleQuestionSubmit(answers: AskQuestionAnswer[]) { + const pending = pendingQuestion() + const client = opencodeClient() + if (!pending || !client) return + + try { + // Map answers to SDK format + const sdkAnswers = answers.map(answer => { + // If custom text provided, return array with custom text + if (answer.customText?.trim()) { + return [answer.customText.trim()] + } + // Otherwise return selected values + return answer.values + }) + + // Call OpenCode SDK directly! + await client.question.reply({ + requestID: pending.requestID, + answers: sdkAnswers + }) + + // Clear pending question + setPendingQuestion(null) + } catch (error) { + console.error('Failed to submit question answers:', error) + // Show error toast + showToast({ + title: 'Failed to submit answers', + description: error.message, + variant: 'error' + }) + } + } + + async function handleQuestionCancel() { + const pending = pendingQuestion() + const client = opencodeClient() + if (!pending || !client) return + + try { + await client.question.reject({ + requestID: pending.requestID + }) + setPendingQuestion(null) + } catch (error) { + console.error('Failed to reject question:', error) + // Still clear the question UI even if reject fails + setPendingQuestion(null) + } + } + + return ( +
+ {/* Existing workspace UI */} + + {/* Question wizard overlay */} + +
+ +
+
+
+ ) +} +``` + +**Overlay Styling:** +```css +/* packages/ui/src/styles/components/askquestion-wizard.css */ + +.question-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(4px); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + padding: var(--spacing-4); +} + +.question-overlay .askquestion-wizard { + max-width: 600px; + width: 100%; + max-height: 80vh; + overflow: auto; +} +``` + +**Estimated Time:** 1 day + +#### Task 2.2: Error Handling & Edge Cases + +**Actions:** +1. Handle network failures gracefully +2. Handle session abort during pending question +3. Handle multiple simultaneous questions (queue them) + +**Session Abort Handling:** +```typescript +// Listen for session status changes +createEffect(() => { + const status = sessionStatus() + const pending = pendingQuestion() + + // If session becomes idle/error while question pending, clear it + if (pending && status.type !== 'busy') { + clearPendingQuestion() + } +}) +``` + +**Multiple Questions Queueing:** +```typescript +// In question store +const [questionQueue, setQuestionQueue] = createSignal([]) + +export function enqueuePendingQuestion(request: PendingQuestion) { + if (!pendingQuestion()) { + // No question showing, show immediately + setPendingQuestion(request) + } else { + // Queue it + setQuestionQueue(prev => [...prev, request]) + } +} + +export function clearPendingQuestion() { + setPendingQuestion(null) + + // Show next queued question if any + const queue = questionQueue() + if (queue.length > 0) { + const [next, ...rest] = queue + setPendingQuestion(next) + setQuestionQueue(rest) + } +} +``` + +**Retry Logic:** +```typescript +async function handleQuestionSubmit(answers: AskQuestionAnswer[]) { + const pending = pendingQuestion() + const client = opencodeClient() + if (!pending || !client) return + + const maxRetries = 3 + let lastError: Error | null = null + + for (let attempt = 0; attempt < maxRetries; attempt++) { + try { + const sdkAnswers = answers.map(a => + a.customText?.trim() ? [a.customText.trim()] : a.values + ) + + await client.question.reply({ + requestID: pending.requestID, + answers: sdkAnswers + }) + + setPendingQuestion(null) + return // Success! + + } catch (error) { + lastError = error as Error + + // Wait before retry (exponential backoff) + if (attempt < maxRetries - 1) { + await new Promise(resolve => + setTimeout(resolve, Math.pow(2, attempt) * 1000) + ) + } + } + } + + // All retries failed + showToast({ + title: 'Failed to submit answers', + description: `Please try again. Error: ${lastError?.message}`, + variant: 'error' + }) +} +``` + +**Estimated Time:** 1 day + +### Phase 3: Testing (Day 5) + +#### Manual Testing Checklist + +**Basic Flow:** +- [ ] Question wizard appears when agent calls askquestion +- [ ] All questions visible in tabs +- [ ] Can navigate between tabs +- [ ] Can select single-choice option +- [ ] Can toggle multiple-choice options +- [ ] Can type custom text +- [ ] Submit button enabled when all answered +- [ ] Answers submitted successfully +- [ ] Agent receives answers and continues +- [ ] Wizard closes after submission + +**Keyboard Navigation:** +- [ ] Arrow keys navigate options +- [ ] Tab/Shift+Tab switch questions +- [ ] Number keys 1-8 select options +- [ ] Space toggles multi-select +- [ ] Enter confirms/submits +- [ ] Escape cancels + +**Edge Cases:** +- [ ] Cancel/reject works +- [ ] Network failure shows error +- [ ] Session abort clears wizard +- [ ] Multiple questions queue properly +- [ ] Works with 1 question +- [ ] Works with 6 questions +- [ ] Works with 2 options per question +- [ ] Works with 8 options per question +- [ ] Custom text-only answer works +- [ ] Mixed custom + selected answers work + +**UI/UX:** +- [ ] Styling matches CodeNomad theme +- [ ] Mobile responsive +- [ ] Keyboard shortcuts discoverable +- [ ] Loading states shown +- [ ] Error messages clear +- [ ] Overlay backdrop works +- [ ] Focus management correct + +**Cross-Browser:** +- [ ] Works in Electron +- [ ] Works in Chrome +- [ ] Works in Firefox +- [ ] Works in Safari + +**Integration:** +- [ ] Works with multiple workspaces +- [ ] Doesn't interfere with other sessions +- [ ] SSE events processed correctly +- [ ] OpenCode SDK calls successful + +#### Automated Testing + +**Component Tests:** +```typescript +// packages/ui/src/components/__tests__/askquestion-wizard.test.tsx + +import { render, fireEvent } from '@solidjs/testing-library' +import { AskQuestionWizard } from '../askquestion-wizard' + +describe('AskQuestionWizard', () => { + const mockQuestions = [ + { + id: 'q1', + label: 'Framework', + question: 'Choose a UI framework', + options: [ + { value: 'react', label: 'React' }, + { value: 'vue', label: 'Vue' } + ] + } + ] + + it('renders questions', () => { + const { getByText } = render(() => ( + {}} + onCancel={() => {}} + /> + )) + + expect(getByText('Choose a UI framework')).toBeInTheDocument() + }) + + it('submits answers', async () => { + const handleSubmit = vi.fn() + const { getByText } = render(() => ( + {}} + /> + )) + + // Select option + fireEvent.click(getByText('React')) + + // Submit should be called + expect(handleSubmit).toHaveBeenCalledWith([ + { questionId: 'q1', values: ['react'], customText: undefined } + ]) + }) + + // ... more tests +}) +``` + +**Integration Tests:** +```typescript +// packages/ui/src/__tests__/question-integration.test.tsx + +describe('Question Integration', () => { + it('shows wizard on question.asked event', () => { + // Mock SSE event + const event = { + type: 'question.asked', + properties: { + id: 'req-123', + sessionID: 'session-456', + questions: [...] + } + } + + // Trigger event + emitSSEEvent(event) + + // Wizard should appear + expect(screen.getByTestId('askquestion-wizard')).toBeVisible() + }) + + it('calls SDK on submit', async () => { + const mockSDK = { + question: { + reply: vi.fn().mockResolvedValue({}) + } + } + + // Show wizard + // Submit answers + // Verify SDK called + expect(mockSDK.question.reply).toHaveBeenCalledWith({ + requestID: 'req-123', + answers: [['react']] + }) + }) +}) +``` + +**Estimated Time:** 1 day + +### Timeline Summary + +| Phase | Tasks | Duration | +| ----------- | ------------------------------ | ---------- | +| **Phase 1** | Port component, styling, state | 3 days | +| **Phase 2** | Integration, error handling | 2 days | +| **Phase 3** | Testing | ~ongoing | +| **Total** | | **5 days** | + +--- + +## Testing Strategy + +### Unit Tests + +**Component Tests:** +- Wizard render with different question counts +- Option selection (single/multi) +- Custom text input +- Keyboard navigation +- Form validation +- Submit/cancel handlers + +**Store Tests:** +- Question state updates +- Queue management +- Clear on session abort +- Multiple workspace isolation + +### Integration Tests + +**E2E Flow:** +1. Agent calls askquestion tool +2. Event flows through SSE +3. Wizard appears +4. User selects answers +5. SDK called with correct payload +6. Agent receives answers +7. Wizard closes + +**Error Scenarios:** +- Network timeout during reply +- SDK error response +- Session abort mid-question +- Multiple simultaneous questions +- Invalid answers + +### Manual Testing + +**User Experience:** +- Visual design consistency +- Keyboard shortcuts intuitive +- Mobile usability +- Loading states clear +- Error messages helpful + +**Browser Compatibility:** +- Electron main use case +- Chrome/Firefox/Safari fallback + +### Performance Testing + +**Metrics:** +- Wizard render time < 100ms +- Answer submission < 500ms +- Memory leak check (open/close 100x) +- No UI blocking during submission + +--- + +## Risk Assessment + +### Technical Risks + +#### Risk 1: OpenCode SDK Version Compatibility + +**Likelihood:** Medium +**Impact:** High +**Mitigation:** +- Lock SDK version in package.json +- Test thoroughly before upgrading SDK +- Monitor OpenCode release notes +- Add version compatibility checks + +#### Risk 2: SSE Event Delivery Failure + +**Likelihood:** Low +**Impact:** High +**Mitigation:** +- Robust reconnection logic (already exists) +- Fallback to polling (if needed) +- Clear error messages to user +- Log SSE connection issues + +#### Risk 3: State Synchronization Edge Cases + +**Likelihood:** Medium +**Impact:** Medium +**Mitigation:** +- Listen to all question lifecycle events +- Clear state on session abort +- Add state inconsistency detection +- Comprehensive edge case testing + +#### Risk 4: Multiple Workspace Interference + +**Likelihood:** Low +**Impact:** High +**Mitigation:** +- Store questions per workspace ID +- Separate SDK client per workspace +- Test with 3+ workspaces simultaneously +- Verify question routing correct + +### Product Risks + +#### Risk 1: User Confusion (New Interaction Pattern) + +**Likelihood:** Medium +**Impact:** Medium +**Mitigation:** +- Clear visual design (distinct from chat) +- Keyboard shortcuts hint visible +- "Help" or "?" tooltip +- User documentation/tutorial + +#### Risk 2: Mobile UX Challenges + +**Likelihood:** High +**Impact:** Medium +**Mitigation:** +- Mobile-first responsive design +- Touch-friendly option buttons +- Simplified keyboard hints on mobile +- Test on various screen sizes + +#### Risk 3: Feature Expectations Mismatch + +**Likelihood:** Low +**Impact:** Low +**Mitigation:** +- Clear documentation of capabilities +- Communicate "Minimal Integration" scope +- Gather user feedback early +- Plan upgrade path to Full Integration + +### Operational Risks + +#### Risk 1: SDK Breaking Changes + +**Likelihood:** Low +**Impact:** High +**Mitigation:** +- Pin SDK version +- Monitor OpenCode changelog +- Add SDK integration tests +- Plan for SDK upgrade strategy + +#### Risk 2: Performance Degradation + +**Likelihood:** Low +**Impact:** Medium +**Mitigation:** +- Profile component performance +- Virtual scrolling if many options +- Debounce/throttle events +- Monitor memory usage + +### Risk Matrix + +| Risk | Likelihood | Impact | Priority | Mitigation Effort | +| ----------------- | ---------- | ------ | -------- | -------------------- | +| SDK Compatibility | Medium | High | **HIGH** | Low | +| SSE Failure | Low | High | Medium | Low (already robust) | +| State Sync | Medium | Medium | Medium | Medium | +| Multi Workspace | Low | High | Medium | Low | +| User Confusion | Medium | Medium | Low | Medium | +| Mobile UX | High | Medium | Medium | Medium | +| Expectations | Low | Low | Low | Low | +| SDK Breaking | Low | High | Medium | Low | +| Performance | Low | Medium | Low | Low | + +--- + +## Appendix + +### A. File Structure + +``` +packages/ +├── ui/ +│ ├── src/ +│ │ ├── components/ +│ │ │ ├── askquestion-wizard.tsx [NEW] +│ │ │ └── ... +│ │ ├── stores/ +│ │ │ ├── question-store.ts [NEW] +│ │ │ └── ... +│ │ ├── styles/ +│ │ │ ├── components/ +│ │ │ │ ├── askquestion-wizard.css [NEW] +│ │ │ │ └── ... +│ │ │ └── components.css [MODIFIED] +│ │ ├── pages/ +│ │ │ └── workspace.tsx [MODIFIED] +│ │ └── context/ +│ │ └── sse.tsx [MODIFIED] +│ └── package.json +└── server/ + └── (no changes needed!) +``` + +### B. Dependencies + +**No new dependencies required!** + +Existing dependencies cover all needs: +- `solid-js` - Already used +- `@solidjs/router` - Already used +- `@opencode-ai/sdk` - Already installed +- CSS custom properties - Already available + +### C. Code Metrics + +**Lines of Code Estimate:** + +| Component | Loc | Description | +| ------------------------ | --------- | --------------------- | +| `askquestion-wizard.tsx` | ~500 | Main wizard component | +| `askquestion-wizard.css` | ~150 | Styling | +| `question-store.ts` | ~50 | State management | +| `workspace.tsx` changes | ~100 | Integration | +| `sse.tsx` changes | ~30 | Event handling | +| Tests | ~300 | Unit + integration | +| **Total** | **~1130** | All new/modified code | + +**Comparison to Full Integration:** +- Full Integration: ~2500 LOC +- Minimal Integration: ~1130 LOC +- **Savings: 55% less code** + +### D. OpenCode SDK Reference + +**Question API Endpoints:** + +```typescript +// List pending questions +GET /question?directory={dir} +Response: QuestionRequest[] + +// Reply to question +POST /question/{requestID}/reply +Body: { answers: string[][] } +Response: void + +// Reject question +POST /question/{requestID}/reject +Body: {} +Response: void +``` + +**Event Types:** + +```typescript +// Question asked +{ + type: 'question.asked', + properties: { + id: string + sessionID: string + questions: QuestionInfo[] + tool?: { messageID: string, callID: string } + } +} + +// Question replied +{ + type: 'question.replied', + properties: { + sessionID: string + requestID: string + answers: string[][] + } +} + +// Question rejected +{ + type: 'question.rejected', + properties: { + sessionID: string + requestID: string + } +} +``` + +### E. Future Enhancements + +**Possible upgrades (post-initial implementation):** + +1. **Question History** + - Store past questions and answers + - Allow viewing history + - Export Q&A log + +2. **Smart Defaults** + - Remember user preferences + - Pre-select common choices + - Learn from past selections + +3. **Advanced Validation** + - Custom validation rules + - Dependent questions (conditional logic) + - Range constraints + +4. **Analytics** + - Track question frequency + - Measure response time + - Identify confusing questions + +5. **Collaboration** + - Multi-user question approval + - Team voting on choices + - Shared question templates + +6. **Offline Support** + - Cache questions + - Queue answers when offline + - Sync when reconnected + +**None of these are needed for MVP!** + +### F. Related Documentation + +- [shuvcode repository](https://github.com/Latitudes-Dev/shuvcode) +- [OpenCode SDK documentation](https://opencode.ai/docs/sdk) +- [CodeNomad architecture](./architecture.md) +- [SolidJS best practices](./solidjs-llms.txt) + +--- + +## Conclusion + +The Minimal Integration approach provides: +- ✅ **Full functionality** (same wizard UI, same user experience) +- ✅ **Faster delivery** (5 days vs 15+ days) +- ✅ **Higher reliability** (using proven OpenCode SDK) +- ✅ **Lower risk** (less code, fewer bugs) +- ✅ **Easier maintenance** (90% less backend code) +- ✅ **Future-proof** (can upgrade to Full Integration later) + +**Next Steps:** +1. Review and approve this document +2. Begin Phase 1: Port wizard component +3. Continue with Phases 2-3 per timeline + +**Questions/Concerns:** +- Contact: [Add contact info] +- Updates: [Add update frequency] + +--- + +**Document Version:** 1.0 +**Last Updated:** 2026-01-10 +**Status:** Ready for Implementation diff --git a/dev-docs/mcp-ask-user-multi-instance/01_PRD.md b/dev-docs/mcp-ask-user-multi-instance/01_PRD.md new file mode 100644 index 00000000..791de3f1 --- /dev/null +++ b/dev-docs/mcp-ask-user-multi-instance/01_PRD.md @@ -0,0 +1,167 @@ +# PRD: Multi-instance MCP `ask_user` registration (namespaced servers) + +**Status:** Draft + +**Owner:** CodeNomad + +**Last updated:** 2026-02-07 + +## Summary +CodeNomad currently registers its MCP `ask_user` integration by writing a single global entry in Antigravity’s MCP config file (`~/.gemini/antigravity/mcp_config.json`) under the key `mcpServers['ask-user']`. When multiple Electron app processes run concurrently, the last one to start overwrites that key, and any instance exiting can delete the key, causing unsafe cross-routing and broken external integrations. + +This PRD defines a reliable multi-instance strategy using **namespaced per-instance registrations** (Option 2) with a **minimal safety harness** to avoid accidental deregistration and config clobbering. + +## Background / Context +- Each CodeNomad Electron process starts an MCP server with a random port and token. +- Electron calls `writeMcpConfig(port, token, mcpServerPath)` and writes to a single global file: `~/.gemini/antigravity/mcp_config.json`. +- Internal CodeNomad tool calls are already per-instance isolated via `OPENCODE_CONFIG_CONTENT` and the per-instance `mcpPort`. +- The multi-instance issue affects **external Antigravity clients** that rely on `mcp_config.json`. + +### Verified current behavior (repo sources) +- Global config path and registration logic: `packages/mcp-server/src/config/registration.ts`. +- Electron calls registration and unregister on quit: `packages/electron-app/electron/main/main.ts`. +- Current unregister deletes `mcpServers['ask-user']` unconditionally. +- Current writer uses a fixed temp file (`mcp_config.json.tmp`), which is unsafe under concurrent writers. + +## Problem Statement +When two CodeNomad instances run concurrently: +1. **Last writer wins**: the most recently started instance overwrites `mcpServers['ask-user']`. +2. **Unsafe deregistration**: any instance exiting can delete the canonical key, breaking the still-running instance. +3. **Concurrent write hazards**: both processes can clobber the same `*.tmp` file and lose unrelated config entries. + +## Goals +- Allow multiple Electron app processes to coexist without unsafe cross-routing. +- Enable external clients (Antigravity) to target a specific CodeNomad instance when possible. +- Keep UX minimal (no new UI). +- Ensure graceful cleanup on exit and best-effort cleanup after crashes. +- Work on macOS; assume other OS as well. + +## Non-goals +- Implement a full broker/multiplexer service (out of scope for this PRD). +- Introduce new UI surfaces or complex instance selection UX. +- Change internal CodeNomad CLI per-instance MCP routing (already isolated). + +## Constraints +- The external client behavior around multiple MCP server entries is unknown in this repo. It may: + - require a single key (`ask-user`) only, + - allow selecting among server keys, or + - auto-load all configured servers and merge tools (potential collision risk). + +Because of that, this PRD includes a **compatibility-first harness**. + +## Proposed Design (Option 2) +### High-level approach +1. Introduce a **process-unique `instanceId`** for each Electron app process. +2. Write a **namespaced MCP server entry per instance**: + - Example key formats (choose one): + - `ask-user-codenomad-pid--port-` + - `ask-user-codenomad-` + - Keys should prefer conservative characters: `[a-z0-9-]`. +3. Preserve (optionally) the canonical alias `mcpServers['ask-user']` for compatibility. +4. Fix unsafe unregister and concurrent write behavior. + +### Canonical alias policy +Because external clients may hardcode `ask-user`, we keep a canonical alias by default. + +Supported modes: +- **lock** (default): first instance to register keeps canonical `ask-user` until it exits. +- **last**: last started instance overwrites canonical (legacy behavior, discouraged). +- **off**: never write canonical `ask-user` (only namespaced entries; only safe if the external client supports selection). + +Configuration (no UI): environment variables read in Electron main process. +- `CODENOMAD_MCP_CANONICAL_MODE=lock|last|off` (default `lock`) +- `CODENOMAD_MCP_WRITE_NAMESPACED=0|1` (default `0` until external client behavior is confirmed) + +## Detailed Requirements +### R1: Namespaced registration +- When enabled, each instance writes exactly one namespaced key mapping to its own port/token. +- The key must be deterministic for the running process and loggable. + +### R2: Ownership-aware unregister +- On quit, an instance must remove only: + - its own namespaced key (if written) + - the canonical `ask-user` key **only if it still owns it**. + +Ownership checks: +- The easiest check is: only delete canonical if the current `mcpServers['ask-user']` entry’s args match this process’s `--port` and `--token`. +- If a lock file is used, also confirm the lock belongs to the instance. + +### R3: Safe concurrent writes +- Config writes must not use a shared temp file path across processes. +- Use unique temp paths, e.g. `mcp_config.json.tmp..`. + +### R4: Crash tolerance / stale cleanup +- If namespaced entries are enabled, stale keys may accumulate after crashes. +- On startup, do best-effort pruning: + - parse the configured `--port` from each CodeNomad namespaced entry + - probe `http://127.0.0.1:/health` + - delete entries whose health check fails +- Pruning must be conservative and only affect keys matching CodeNomad’s chosen prefix. + +### R5: macOS + cross-platform +- Use only Node filesystem primitives and avoid OS-specific APIs. +- Prefer lock acquisition via `fs.openSync(path, 'wx')` for broad support. + +## Implementation Plan (repo touchpoints) +### 1) Add instanceId generation and pass-through +File: `packages/electron-app/electron/main/main.ts` +- Generate `instanceId` once per process (e.g., `crypto.randomUUID()` where available). +- Pass `instanceId`, `port`, and `token` into the registration API. + +### 2) Evolve registration API +File: `packages/mcp-server/src/config/registration.ts` +Add/replace APIs: +- `writeMcpConfig({ instanceId, port, token, serverPath, canonicalMode, writeNamespaced })` +- `unregisterFromMcpConfig({ instanceId, port, token, canonicalMode, wroteNamespaced })` + +Behavior: +- If `writeNamespaced` is enabled, write `mcpServers[ask-user-codenomad-...]`. +- If `canonicalMode` is `lock`: + - acquire lock (e.g., `~/.gemini/antigravity/codenomad-ask-user.lock`) + - only lock owner writes canonical `mcpServers['ask-user']` +- If `canonicalMode` is `last`: write canonical without lock (legacy) +- If `canonicalMode` is `off`: do not touch canonical + +Unregister: +- Remove the namespaced entry for this instance. +- Remove canonical only if: + - canonicalMode != `off`, and + - current config matches this instance (args contain the same `--port` and `--token`), and + - lock is owned by this instance (if lock mode). + +### 3) Unique temp files for atomic writes +File: `packages/mcp-server/src/config/registration.ts` +- Replace `const tempPath = configPath + '.tmp'` with a unique filename. + +## Compatibility Notes +- If the external client auto-loads all servers and merges tools, writing multiple servers that all expose `ask_user` may create tool name collisions. +- Therefore, default `CODENOMAD_MCP_WRITE_NAMESPACED=0` until client behavior is confirmed. + +## Security Notes +- Current MCP server token generation exists, but the HTTP request handler does not obviously enforce Authorization in `packages/mcp-server/src/server.ts`. +- Regardless of multi-instance registration, if local security matters, enforce token checks as a follow-up. + +## Test Plan +1. **Single instance**: + - start CodeNomad + - verify config contains canonical key (and optionally namespaced key) + - quit CodeNomad + - verify it only removes keys it owns +2. **Two instances**: + - start instance A + - start instance B + - verify canonical key is stable under `lock` mode + - quit instance B first → canonical should remain (owned by A) + - quit instance A → canonical removed +3. **Crash simulation**: + - start CodeNomad + - force kill process (SIGKILL) + - verify stale namespaced entries are pruned on next start (if pruning enabled) +4. **Concurrent write simulation**: + - start two instances quickly + - verify config file remains valid JSON and retains unrelated entries + +## Open Questions +1. Does Antigravity support selecting among `mcpServers` keys, or does it only use `ask-user`? +2. If it loads all servers, how does it handle duplicate tool names (`ask_user`) across multiple servers? +3. Do we want to log the chosen namespaced key prominently in Electron logs to aid manual targeting? diff --git a/dev-docs/mcp-ask-user-multi-instance/02_PRD.md b/dev-docs/mcp-ask-user-multi-instance/02_PRD.md new file mode 100644 index 00000000..71e4b7c6 --- /dev/null +++ b/dev-docs/mcp-ask-user-multi-instance/02_PRD.md @@ -0,0 +1,378 @@ +# PRD: Multi-instance MCP `ask_user` with CodeNomad-local config + +**Status:** Proposed + +**Owner:** CodeNomad + +**Last updated:** 2026-02-07 + +## Summary + +CodeNomad currently writes its MCP `ask_user` server registration to Antigravity's global config file (`~/.gemini/antigravity/mcp_config.json`). This causes multi-instance conflicts when multiple Electron app processes run concurrently. This PRD proposes a simpler solution: write to a CodeNomad-specific location instead, eliminating external Antigravity integration and the associated multi-instance complexity. + +## Background / Context + +- Each CodeNomad Electron process starts an MCP server with a random port and token. +- Electron calls `writeMcpConfig(port, token, mcpServerPath)` to register the server. +- **Internal CodeNomad tool calls are already per-instance isolated** via `OPENCODE_CONFIG_CONTENT` and the per-instance `mcpPort`. +- The config file is only consumed by external Antigravity clients (not CodeNomad's own agents). +- Multi-instance conflicts only affect the external integration use case. + +### Verified current behavior (repo sources) + +- Global config path: `packages/mcp-server/src/config/registration.ts` → `~/.gemini/antigravity/mcp_config.json` +- Electron calls registration on startup and unregister on quit: `packages/electron-app/electron/main/main.ts` +- Current writer uses a fixed temp file (`mcp_config.json.tmp`), which is unsafe under concurrent writers. +- Current `unregisterFromMcpConfig()` deletes the entry unconditionally. + +## Problem Statement + +When two CodeNomad instances run concurrently: + +1. **Last writer wins:** Both instances write to the same global `mcpServers['ask-user']` key. +2. **Unsafe deregistration:** Any instance exiting can delete the key, breaking the still-running instance. +3. **Concurrent write hazards:** Both processes use the same `*.tmp` file, risking config corruption. + +## Root Cause Analysis + +These problems exist because we're registering in a **shared global namespace** (Antigravity's config) for a feature (external integration) that is not core to CodeNomad's functionality. + +CodeNomad's own agents use `OPENCODE_CONFIG_CONTENT` environment variables and are already per-instance isolated. + +## Decision: Drop External Antigravity Integration + +After analysis, external Antigravity integration: + +- Is not a core requirement for CodeNomad's primary use case (internal agents) +- Introduces significant complexity (lock files, instance tracking, canonical aliases) +- Has unknown value (no documented external consumers) + +**Solution:** Write MCP server config to a CodeNomad-specific location instead of Antigravity's global config. + +## Goals + +- Allow multiple Electron app processes to coexist safely. +- Eliminate multi-instance file contention. +- Simplify the codebase by removing external integration complexity. +- Maintain per-instance isolation for internal agents. +- Ensure graceful cleanup on exit. + +## Non-goals + +- Enable external Antigravity clients to discover CodeNomad's MCP server. +- Support selecting among multiple CodeNomad instances from external tools. +- Implement lock file management or canonical alias tracking. + +## Proposed Design + +### High-level approach + +1. **Relocate config path:** Write to `~/.codenomad/mcp_config.json` instead of `~/.gemini/antigravity/mcp_config.json`. + +2. **Per-instance config files (optional):** Each instance writes to its own file: + ``` + ~/.codenomad/instances//config.json + ``` + +3. **Simple cleanup:** On exit, each instance removes its own config file. + +4. **No external integration:** External Antigravity clients will not discover CodeNomad's MCP server (this is intentional). + +### Architecture + +``` +~/.codenomad/ +├── instances/ +│ ├── abc-123/ +│ │ └── config.json ← Instance 1's MCP server config +│ └── def-456/ +│ └── config.json ← Instance 2's MCP server config +└── active (optional) Symlink to active instance +``` + +### Config file format (per-instance) + +```json +{ + "instanceId": "abc-123", + "pid": 12345, + "port": 3000, + "token": "random-token", + "serverPath": "/path/to/server.js", + "startedAt": "2026-02-07T10:30:00.000Z" +} +``` + +## Detailed Requirements + +### R1: CodeNomad-local config path + +- Change `getMcpConfigPath()` to return `~/.codenomad/mcp_config.json`. +- Or: Return `~/.codenomad/instances//config.json` for per-instance files. + +### R2: Instance identification + +- Generate `instanceId` once per Electron process using `crypto.randomUUID()`. +- Store `instanceId` in the config file for identification. +- Log `instanceId` on startup for debugging. + +### R3: Safe file writes + +- Use unique temp file paths: `config.json.tmp..`. +- Atomic write: write to temp, then rename. + +### R4: Instance-specific config files (recommended) + +- Each instance writes to its own subdirectory: `~/.codenomad/instances//config.json`. +- No contention between instances. +- Simple cleanup: delete own directory on exit. + +### R5: Crash cleanup (best-effort) + +- On startup, scan `~/.codenomad/instances/` for stale configs. +- Probe `http://127.0.0.1:/health` for each instance. +- Delete configs where health check fails. +- Optionally: Check PID liveness (if stored in config). + +### R6: Backward compatibility + +- Existing `OPENCODE_CONFIG_CONTENT` mechanism continues to work. +- No changes needed for CodeNomad's internal agents. + +## Implementation Plan + +### 1) Update config path + +File: `packages/mcp-server/src/config/registration.ts` + +```typescript +export function getMcpConfigPath(instanceId?: string): string { + const baseDir = path.join(os.homedir(), '.codenomad'); + + if (instanceId) { + // Per-instance config + return path.join(baseDir, 'instances', instanceId, 'config.json'); + } + + // Shared config (fallback) + return path.join(baseDir, 'mcp_config.json'); +} +``` + +### 2) Add instanceId to registration + +File: `packages/electron-app/electron/main/main.ts` + +```typescript +import { randomUUID } from 'crypto'; + +// In app.whenReady() +const instanceId = randomUUID(); + +// Pass to registration +writeMcpConfig({ + instanceId, + port, + token, + serverPath: mcpServerPath +}); +``` + +### 3) Update registration API + +File: `packages/mcp-server/src/config/registration.ts` + +```typescript +export interface McpRegistrationConfig { + instanceId: string; + port: number; + token: string; + serverPath?: string; +} + +export function writeMcpConfig(config: McpRegistrationConfig): void { + const configPath = getMcpConfigPath(config.instanceId); + + // Write instance-specific config + const instanceConfig = { + instanceId: config.instanceId, + pid: process.pid, + port: config.port, + token: config.token, + serverPath: config.serverPath, + startedAt: new Date().toISOString() + }; + + // Ensure directory exists + const configDir = path.dirname(configPath); + fs.mkdirSync(configDir, { recursive: true }); + + // Atomic write + const tempPath = `${configPath}.tmp.${process.pid}.${crypto.randomBytes(8).toString('hex')}`; + fs.writeFileSync(tempPath, JSON.stringify(instanceConfig, null, 2)); + fs.renameSync(tempPath, configPath); + + console.log(`[MCP Config] Registered instance ${config.instanceId} on port ${config.port}`); +} +``` + +### 4) Update unregister + +File: `packages/mcp-server/src/config/registration.ts` + +```typescript +export function unregisterFromMcpConfig(instanceId: string): void { + const configPath = getMcpConfigPath(instanceId); + + try { + if (fs.existsSync(configPath)) { + fs.unlinkSync(configPath); + + // Try to remove empty parent directories + const instancesDir = path.dirname(configPath); + const remaining = fs.readdirSync(instancesDir); + if (remaining.length === 0) { + fs.rmSync(instancesDir, { recursive: true }); + } + + console.log(`[MCP Config] Unregistered instance ${instanceId}`); + } + } catch (error) { + console.error('[MCP Config] Failed to unregister:', error); + } +} +``` + +### 5) Add startup cleanup + +File: `packages/mcp-server/src/config/registration.ts` + +```typescript +export async function cleanupStaleInstances(): Promise { + const instancesDir = path.join(os.homedir(), '.codenomad', 'instances'); + + if (!fs.existsSync(instancesDir)) { + return; + } + + const instanceDirs = fs.readdirSync(instancesDir); + + for (const instanceId of instanceDirs) { + const configPath = path.join(instancesDir, instanceId, 'config.json'); + + try { + const content = fs.readFileSync(configPath, 'utf8'); + const config = JSON.parse(content); + + // Check if process is still alive + try { + process.kill(config.pid, 0); // Signal 0 checks if process exists + continue; // Process alive, skip + } catch { + // Process dead, check health endpoint + } + + // Probe health endpoint + const response = await fetch(`http://127.0.0.1:${config.port}/health`); + if (response.ok) { + continue; // Server responding, keep + } + + // Stale: remove + fs.rmSync(path.join(instancesDir, instanceId), { recursive: true }); + console.log(`[MCP Config] Cleaned up stale instance ${instanceId}`); + } catch (error) { + // Invalid config or other error, remove + fs.rmSync(path.join(instancesDir, instanceId), { recursive: true }); + } + } +} +``` + +### 6) Update Electron main + +File: `packages/electron-app/electron/main/main.ts` + +```typescript +import { cleanupStaleInstances } from "@codenomad/mcp-server/src/config/registration"; + +// In app.whenReady(), before starting MCP server +await cleanupStaleInstances(); + +// Store instanceId for later use +let mcpInstanceId: string; + +// When starting MCP server +mcpInstanceId = randomUUID(); +writeMcpConfig({ + instanceId: mcpInstanceId, + port, + token, + serverPath: mcpServerPath +}); + +// In app.on("before-quit") +unregisterFromMcpConfig(mcpInstanceId); +``` + +## Compatibility Notes + +- **External Antigravity clients:** Will no longer discover CodeNomad's MCP server. This is intentional. +- **CodeNomad internal agents:** No changes needed; they use `OPENCODE_CONFIG_CONTENT`. +- **Existing functionality:** Fully preserved for CodeNomad's primary use case. + +## Security Notes + +- Config files contain auth tokens and are written to user home directory. +- Consider file permissions: restrict to owner-only (`0o600`). +- Tokens are already randomly generated per instance. + +## Test Plan + +1. **Single instance:** + - Start CodeNomad + - Verify config exists at `~/.codenomad/instances//config.json` + - Verify content includes instanceId, port, token + - Quit CodeNomad + - Verify config file is removed + +2. **Two instances:** + - Start instance A + - Start instance B + - Verify each has its own config file (different instanceIds) + - Quit instance B + - Verify instance A's config still exists + - Quit instance A + - Verify both config files removed + +3. **Crash simulation:** + - Start CodeNomad + - Force kill process (SIGKILL) + - Start CodeNomad again + - Verify stale config from crashed instance is cleaned up + +4. **Concurrent startup:** + - Start two instances simultaneously + - Verify both configs are written correctly + - Verify no temp files remain + - Verify configs are valid JSON + +## Migration Path + +For existing users: + +1. Old config at `~/.gemini/antigravity/mcp_config.json` will be ignored. +2. No automatic migration needed (external integration is being dropped). +3. Optional: Add one-time cleanup of old config on first run. + +## Open Questions + +None identified. This approach is simpler than the original PRD and eliminates the multi-instance problem by design. + +## Alternatives Considered + +1. **Original PRD (01_PRD.md):** Complex namespaced registrations with lock files and canonical alias management. Rejected due to unnecessary complexity for a non-core feature. + +2. **Symlink approach:** Use symlinks to manage active instance. Rejected as still requiring external integration. + +3. **Status quo:** Continue writing to Antigravity config. Rejected due to multi-instance conflicts. diff --git a/dev-docs/subagent-premium-bypass-prd.md b/dev-docs/subagent-premium-bypass-prd.md new file mode 100644 index 00000000..1bc3348a --- /dev/null +++ b/dev-docs/subagent-premium-bypass-prd.md @@ -0,0 +1,964 @@ +# Product Requirements Document: Subagent Premium Usage Bypass + +**Document Version:** 1.0 +**Date:** January 26, 2026 +**Status:** Draft +**Author:** CodeNomad Development Team + +--- + +## Executive Summary + +This PRD outlines the implementation required to exempt subagent tasks from consuming premium API quota in CodeNomad, aligning with user expectations similar to VSCode Copilot Chat where internal tool operations don't count against user limits. + +**Current State:** Subagent tasks triggered via the `task` tool consume 1 premium request per invocation. +**Desired State:** Subagent tasks should execute without consuming premium quota, similar to the existing `ask_user` tool behavior. +**Impact:** Improves user experience by allowing unlimited subagent usage for exploratory tasks without quota concerns. + +--- + +## Problem Statement + +### Current Behavior + +When a main agent delegates work to a subagent using the `task` tool: + +1. User sends a prompt to main agent → **Premium request consumed** ✅ +2. Main agent calls `task` tool with `subagent_type` parameter +3. CodeNomad creates a new session with `parentId` set to main agent's session +4. Subagent executes its work → **Premium request consumed** ❌ (ISSUE) +5. Subagent returns result to main agent +6. Main agent continues → **No additional premium consumed** ✅ + +**Problem:** Step 4 consumes premium quota even though the subagent is an internal implementation detail of the main agent's processing, not a direct user request. + +### User Impact + +- **Quota exhaustion:** Users hit premium limits faster when using features that delegate to subagents (exploration, research, code analysis) +- **Inhibited exploration:** Users avoid using powerful subagent-based features to conserve quota +- **Unexpected billing:** Users are surprised when internal tool operations count against their limits +- **Competitive disadvantage:** VSCode Copilot Chat doesn't count internal operations, setting user expectations + +### Business Impact + +- **User satisfaction:** Misalignment with competitor behavior creates negative perception +- **Feature adoption:** Lower utilization of advanced subagent-based features +- **Support burden:** Increased user confusion about quota consumption +- **Retention risk:** Power users may seek alternatives with more predictable quota usage + +--- + +## Current Architecture Analysis + +### How Premium Usage is Tracked + +Based on codebase investigation, premium usage is tracked through: + +1. **Session-level token counting:** + - **File:** `packages/ui/src/stores/message-v2/instance-store.ts:106-133` + - **Function:** `extractUsageEntry()` extracts tokens from `MessageInfo.meta.usage` + - **Triggers:** Every completed message with `status: "complete"` adds usage entry + +2. **Usage aggregation:** + - **File:** `packages/ui/src/stores/message-v2/instance-store.ts:135-146` + - **Function:** `applyUsageState()` accumulates totals (input/output/reasoning tokens) + - **State:** `SessionUsageState` stores cumulative token counts per session + +3. **Session info updates:** + - **File:** `packages/ui/src/stores/message-v2/session-info.ts:18-139` + - **Function:** `updateSessionInfo()` calculates total context usage + - **Display:** Powers the context usage panel UI + +4. **Event-driven tracking:** + - **File:** `packages/ui/src/stores/session-events.ts:224-266` + - **Event:** `message.updated` with `status: "complete"` triggers usage extraction + - **Flow:** SSE event → message store → usage state → session info + +**Key Insight:** Premium consumption happens implicitly when an LLM request completes and returns token usage in the `MessageInfo.meta.usage` object. There's no explicit "premium counter increment" call - it's derived from message completion events. + +### How Subagents are Identified + +Subagents are distinguished from main agents through multiple identifiers: + +1. **Agent mode property:** + - **File:** `packages/ui/src/types/session.ts:64-73` + - **Property:** `agent.mode === "subagent"` + - **Usage:** Filtered out during session creation in `session-api.ts:175` + +2. **Session parent relationship:** + - **File:** `packages/ui/src/types/session.ts:32` + - **Property:** `session.parentId: string | null` + - **Detection:** `parentId !== null` indicates a subagent session + +3. **Session title pattern:** + - **File:** `packages/ui/src/stores/session-state.ts:619` + - **Pattern:** `session.title?.includes("subagent)")` + - **Usage:** Used in cleanup logic to identify subagent sessions + +4. **Task tool metadata:** + - **File:** `packages/ui/src/components/tool-call/renderers/task.tsx` + - **Properties:** `input.subagent_type`, `metadata.model`, `metadata.summary` + - **Display:** Task title formatted as `"Task[subagent_type] {description}"` + +5. **Session hierarchy:** + - **File:** `packages/ui/src/stores/session-state.ts:375-391` + - **Functions:** `getParentSessions()`, `getChildSessions()`, `getSessionFamily()` + - **Architecture:** Clear parent-child relationship for main agent → subagent sessions + +**Key Insight:** The most reliable identifier is `session.parentId !== null` which definitively marks a session as a subagent. + +### How ask_user Bypasses Premium Consumption (Reference Implementation) + +The `ask_user` tool achieves zero premium consumption through architectural design, NOT through explicit exemption logic. + +**Architecture Pattern:** + +``` +Traditional Flow (Consumes Premium): +User prompt → LLM Request #1 ✅ → Tool call → New LLM Request #2 ❌ + +ask_user Flow (Zero Premium): +User prompt → LLM Request #1 ✅ → MCP tool blocks with Promise → +User answers via IPC → Tool returns in SAME stream → No new LLM request +``` + +**Implementation Details:** + +1. **MCP Server Blocking:** + - **File:** `packages/mcp-server/src/tools/askUser.ts:12-51` + - **Line 29:** Creates a Promise that blocks execution + - **Line 49:** Sends question via Electron IPC (not HTTP) + - **Mechanism:** Promise resolves when user answers, returns in same JSON-RPC response + +2. **JSON-RPC Response:** + - **File:** `packages/mcp-server/src/server.ts:411-420` + - **Line 396:** Debug log explicitly states "ZERO-COST" + - **Line 404:** Awaits `askUser()` which blocks until user responds + - **Line 417:** Returns result in same JSON-RPC response stream + +3. **IPC Communication:** + - **File:** `packages/ui/src/lib/mcp-bridge.ts:46-60, 119-176` + - **Line 53:** Answer sent via IPC, not HTTP/web API + - **Line 175:** Questions tagged with `source: 'mcp'` for routing + +4. **No New Message Event:** + - **Key:** Because tool returns in same stream, no new `message.updated` event fires + - **Result:** `extractUsageEntry()` never called for the user's answer + - **Outcome:** Zero premium consumption + +**Critical Insight:** The bypass works because: +- No new LLM API call is made (user provides answer, not LLM) +- Tool result returns in the same message stream +- No new `message.updated` event with token usage +- Usage tracking system never sees a new chargeable event + +--- + +## Desired Behavior Specification + +### Success Criteria + +A solution is successful when: + +1. **Main agent requests consume premium as expected:** + - User prompt → main agent response = 1 premium request ✅ + +2. **Subagent requests DO NOT consume premium:** + - Main agent → subagent task execution = 0 additional premium requests ✅ + - Subagent token usage NOT added to user's premium consumption + +3. **Token accounting remains accurate:** + - Subagent token usage still tracked for cost/context calculations + - Displayed separately or marked as "internal overhead" + +4. **No impact on non-subagent sessions:** + - Direct user interactions with any agent consume premium normally + - Only parent-child subagent relationships get exemption + +5. **Backward compatibility:** + - Existing sessions continue to work + - Premium usage history remains accurate + - No migration needed for existing data + +### Expected User Experience + +**Before Fix:** +``` +User: "Analyze this codebase" +Main Agent: [Delegates to explore subagent] + → Premium consumed: 2 requests (main + subagent) ❌ +User's quota: 48/50 remaining +``` + +**After Fix:** +``` +User: "Analyze this codebase" +Main Agent: [Delegates to explore subagent] + → Premium consumed: 1 request (main only) ✅ +User's quota: 49/50 remaining +``` + +**Context Usage Panel:** +``` +┌──────────────────────────────────────┐ +│ Context Usage │ +├──────────────────────────────────────┤ +│ Input Tokens: 2,450 │ +│ Output Tokens: 1,230 │ +│ Reasoning Tokens: 0 │ +│ │ +│ Premium Requests: 1 / 50 │ +│ Internal Tasks: 1 (no cost) │ +│ │ +│ Total Cost: $0.12 │ +└──────────────────────────────────────┘ +``` + +--- + +## Proposed Solution Approaches + +### Approach 1: Session-Level Exemption Flag (Recommended) + +**Overview:** Add a `isSubagent: boolean` or `exemptFromPremium: boolean` flag to the Session type that gets checked during usage extraction. + +**Implementation Steps:** + +1. **Add session property:** + ```typescript + // packages/ui/src/types/session.ts + export interface Session { + // ... existing fields + parentId: string | null + exemptFromPremium?: boolean // NEW FIELD + } + ``` + +2. **Set flag during session creation:** + ```typescript + // packages/ui/src/stores/session-api.ts + async function createSession(instanceId: string, agent?: string, parentId?: string): Promise { + const exemptFromPremium = parentId !== null; // Subagents are exempt + + const response = await api.createSession(instanceId, { + agent, + parentID: parentId, + exemptFromPremium // Pass to backend + }); + } + ``` + +3. **Check flag during usage extraction:** + ```typescript + // packages/ui/src/stores/message-v2/instance-store.ts + function extractUsageEntry(info: MessageInfo | undefined, sessionId: string): UsageEntry | null { + if (!info || !info.meta?.usage) return null; + + // NEW: Check if session is exempt + const session = sessions().get(info.instanceId)?.get(sessionId); + if (session?.exemptFromPremium) { + console.log(`[Usage] Skipping premium tracking for subagent session ${sessionId}`); + return null; // Don't track usage for subagents + } + + // ... existing extraction logic + } + ``` + +4. **Update session state handling:** + ```typescript + // packages/ui/src/stores/session-state.ts + function getChildSessions(instanceId: string, parentId: string): Session[] { + return allSessions.filter((s) => { + return s.parentId === parentId && s.exemptFromPremium === true; + }); + } + ``` + +**Pros:** +- Clean, explicit flag indicating intent +- Easy to test (just check flag presence) +- No architectural changes required +- Can be extended for other exemption types (e.g., system operations) +- Backend and frontend can independently validate + +**Cons:** +- Requires schema change (Session type) +- Needs database migration if sessions are persisted +- Flag could be misused if not properly validated + +--- + +### Approach 2: Usage Extraction Filter by parentId + +**Overview:** Modify usage extraction logic to check `session.parentId` directly without adding new fields. + +**Implementation Steps:** + +1. **Update extractUsageEntry signature:** + ```typescript + // packages/ui/src/stores/message-v2/instance-store.ts + function extractUsageEntry( + info: MessageInfo | undefined, + session: Session | undefined // NEW: Pass full session + ): UsageEntry | null { + if (!info || !info.meta?.usage) return null; + + // NEW: Check if session has a parent (is subagent) + if (session?.parentId !== null) { + console.log(`[Usage] Skipping premium for subagent (parent: ${session.parentId})`); + return null; + } + + // ... existing extraction logic + } + ``` + +2. **Update all call sites:** + ```typescript + // packages/ui/src/stores/message-v2/instance-store.ts + function updateUsageWithInfo(info: MessageInfo) { + const session = sessions().get(info.instanceId)?.get(info.sessionId); + const entry = extractUsageEntry(info, session); // Pass session + if (entry) { + applyUsageState(getOrCreateUsageState(info.sessionId), entry); + } + } + ``` + +3. **Update session-info.ts:** + ```typescript + // packages/ui/src/stores/message-v2/session-info.ts + export function updateSessionInfo(instanceId: string, sessionId: string) { + const session = sessions().get(instanceId)?.get(sessionId); + if (!session) return; + + const usageState = usageStates.get(sessionId); + + // Calculate premium requests (exclude subagents) + const premiumRequests = session.parentId === null + ? calculatePremiumRequests(usageState) + : 0; // Subagents contribute 0 + } + ``` + +**Pros:** +- No schema changes required +- Uses existing `parentId` field (already identifies subagents) +- Simpler implementation (fewer moving parts) +- Immediate deployment (no migrations) + +**Cons:** +- Couples usage logic to session hierarchy concept +- Less flexible for future exemption types +- Harder to extend for non-subagent exemptions + +--- + +### Approach 3: Dual Accounting (Track but Don't Charge) + +**Overview:** Track subagent token usage separately for visibility but don't count toward premium quota. + +**Implementation Steps:** + +1. **Add separate usage categories:** + ```typescript + // packages/ui/src/types/session.ts + export interface SessionUsageState { + // Existing fields + totalInputTokens: number + totalOutputTokens: number + totalReasoningTokens: number + totalCost: number + + // NEW: Separate subagent tracking + subagentInputTokens: number + subagentOutputTokens: number + subagentReasoningTokens: number + subagentCost: number + subagentTaskCount: number + } + ``` + +2. **Bifurcate usage extraction:** + ```typescript + // packages/ui/src/stores/message-v2/instance-store.ts + function extractUsageEntry(info: MessageInfo, session: Session): UsageEntry | null { + if (!info?.meta?.usage) return null; + + const tokens = info.meta.usage; + const isSubagent = session?.parentId !== null; + + return { + messageId: info.id, + inputTokens: tokens.input ?? 0, + outputTokens: tokens.output ?? 0, + reasoningTokens: tokens.reasoning ?? 0, + cost: tokens.cost ?? 0, + isSubagent, // NEW: Flag for routing + // ... + }; + } + + function applyUsageState(state: SessionUsageState, entry: UsageEntry) { + if (!entry) return; + + if (entry.isSubagent) { + // Track separately + state.subagentInputTokens += entry.inputTokens; + state.subagentOutputTokens += entry.outputTokens; + state.subagentReasoningTokens += entry.reasoningTokens; + state.subagentCost += entry.cost; + state.subagentTaskCount += 1; + } else { + // Track normally (counts toward premium) + state.totalInputTokens += entry.inputTokens; + state.totalOutputTokens += entry.outputTokens; + state.totalReasoningTokens += entry.reasoningTokens; + state.totalCost += entry.cost; + } + } + ``` + +3. **Update UI to show both:** + ```typescript + // packages/ui/src/components/session/context-usage-panel.tsx +
+
+

Premium Usage

+

Input: {usage.totalInputTokens}

+

Output: {usage.totalOutputTokens}

+

Cost: ${usage.totalCost}

+
+ +
+

Internal Tasks (No Cost)

+

Input: {usage.subagentInputTokens}

+

Output: {usage.subagentOutputTokens}

+

Tasks: {usage.subagentTaskCount}

+
+
+ ``` + +**Pros:** +- Maximum transparency (users see all usage) +- Helpful for debugging/optimization +- Clear separation between charged and uncharged usage +- Better analytics for power users + +**Cons:** +- More complex implementation (dual accounting) +- UI needs redesign to show both categories +- Higher maintenance burden (two code paths) +- Schema changes required + +--- + +### Approach 4: Backend Exemption List + +**Overview:** Backend maintains a list of exempt agent modes/types and doesn't return usage tokens for them. + +**Implementation Steps:** + +1. **Backend configuration:** + ```typescript + // packages/server/src/config/schema.ts + export const EXEMPT_AGENT_MODES = ["subagent", "system", "internal"]; + ``` + +2. **Backend session creation:** + ```typescript + // packages/server/src/agents/session-manager.ts + function createSession(params: SessionCreateParams): Session { + const agent = findAgent(params.agent); + const exemptFromPremium = EXEMPT_AGENT_MODES.includes(agent.mode); + + return { + id: generateId(), + agentName: params.agent, + parentID: params.parentID || null, + exemptFromPremium, // Set by backend + // ... + }; + } + ``` + +3. **Backend usage reporting:** + ```typescript + // packages/server/src/agents/message-handler.ts + function reportMessageUsage(session: Session, tokens: TokenUsage): MessageMeta { + if (session.exemptFromPremium) { + // Don't include usage in response + return { + usage: null // Client won't track this + }; + } + + return { + usage: { + input: tokens.input, + output: tokens.output, + reasoning: tokens.reasoning, + cost: tokens.cost + } + }; + } + ``` + +4. **Frontend passive consumption:** + ```typescript + // packages/ui/src/stores/message-v2/instance-store.ts + function extractUsageEntry(info: MessageInfo): UsageEntry | null { + if (!info?.meta?.usage) return null; // Backend already filtered + + // ... existing logic (no changes needed) + } + ``` + +**Pros:** +- Single source of truth (backend controls exemptions) +- Frontend implementation unchanged +- Impossible to bypass client-side (security) +- Centralized configuration + +**Cons:** +- Requires backend changes (more complex deployment) +- Frontend loses visibility into internal token usage +- Harder to debug (usage not visible client-side) +- Less transparency for users + +--- + +## Recommended Solution: Hybrid Approach (1 + 3) + +**Rationale:** Combine the explicit flag from Approach 1 with dual accounting from Approach 3 for best user experience and maintainability. + +**Implementation:** + +1. **Add `exemptFromPremium` flag to Session type** (Approach 1) +2. **Track subagent usage separately** (Approach 3) +3. **Display both premium and internal usage in UI** (Approach 3) +4. **Backend sets flag based on `parentID !== null`** (Validation) + +**Benefits:** +- Explicit, easy-to-test flag +- Full visibility into all token usage +- Clear separation in UI +- Backend validation prevents abuse +- Extensible for future exemption types + +--- + +## Implementation Plan + +### Phase 1: Backend Schema Update + +**Files to Modify:** +- `packages/server/src/types/session.ts` - Add `exemptFromPremium?: boolean` +- `packages/server/src/agents/session-manager.ts` - Set flag during creation +- `packages/server/src/database/schema.ts` - Add column (if persisted) + +**Tasks:** +1. Add `exemptFromPremium` field to Session type +2. Set flag automatically when `parentID !== null` +3. Return flag in session creation response +4. Add migration script if sessions are persisted + +**Estimated Time:** 2-4 hours + +--- + +### Phase 2: Frontend Type Updates + +**Files to Modify:** +- `packages/ui/src/types/session.ts` - Add `exemptFromPremium?: boolean` +- `packages/ui/src/stores/session-state.ts` - Handle new field +- `packages/ui/src/stores/session-events.ts` - Parse from SSE events + +**Tasks:** +1. Add field to frontend Session type +2. Update session normalization logic +3. Update SSE event handlers +4. Add TypeScript strict checks + +**Estimated Time:** 1-2 hours + +--- + +### Phase 3: Usage Tracking Logic Update + +**Files to Modify:** +- `packages/ui/src/stores/message-v2/instance-store.ts` - Update `extractUsageEntry()` +- `packages/ui/src/stores/message-v2/session-info.ts` - Add subagent tracking +- `packages/ui/src/types/session.ts` - Add subagent usage fields + +**Tasks:** +1. Add `isSubagent` flag to `UsageEntry` +2. Update `extractUsageEntry()` to check `session.exemptFromPremium` +3. Bifurcate `applyUsageState()` for premium vs internal usage +4. Add `subagentInputTokens`, `subagentOutputTokens`, etc. to `SessionUsageState` +5. Update `updateSessionInfo()` to calculate both categories + +**Estimated Time:** 4-6 hours + +--- + +### Phase 4: UI Updates + +**Files to Modify:** +- `packages/ui/src/components/session/context-usage-panel.tsx` - Display both categories +- `packages/ui/src/styles/panels/context-usage.css` - Style internal usage section + +**Tasks:** +1. Add "Internal Tasks (No Cost)" section to usage panel +2. Display subagent token counts and task count +3. Add tooltip explaining internal vs premium usage +4. Style with muted/secondary colors for internal usage +5. Add toggle to show/hide internal usage details + +**Estimated Time:** 3-4 hours + +--- + +### Phase 5: Testing & Validation + +**Test Cases:** + +1. **Main agent only:** + - Send prompt to main agent + - Verify premium usage increments by 1 + - Verify no internal usage tracked + +2. **Main agent with subagent:** + - Send prompt that triggers subagent delegation + - Verify premium usage increments by 1 (main only) + - Verify internal usage shows subagent token count + - Verify subagent task count = 1 + +3. **Multiple subagent tasks:** + - Trigger 3 subagent tasks in one main agent response + - Verify premium usage = 1 (main only) + - Verify internal task count = 3 + +4. **Direct subagent session (edge case):** + - Manually create session with subagent agent + - Should still consume premium (no parentId) + +5. **Child session creation:** + - Verify `exemptFromPremium` flag set correctly + - Verify `parentId` and `exemptFromPremium` correlation + +6. **Usage panel UI:** + - Verify both sections display correctly + - Verify tooltip/help text accurate + - Verify numbers match expected values + +**Estimated Time:** 4-6 hours + +--- + +### Phase 6: Documentation & Rollout + +**Documentation Updates:** +- Update `dev-docs/usage-tracking.md` (create if needed) +- Add notes to `dev-docs/TOOL_CALL_IMPLEMENTATION.md` +- Update user-facing docs about premium usage +- Add FAQ entry about subagent costs + +**Rollout:** +- Feature flag: `enableSubagentExemption` (default: true) +- Monitor error rates and usage metrics +- Collect user feedback on transparency + +**Estimated Time:** 2-3 hours + +--- + +**Total Estimated Time:** 16-25 hours (2-3 days) + +--- + +## Testing Strategy + +### Unit Tests + +1. **Test `extractUsageEntry()` with exempt session:** + ```typescript + // packages/ui/src/stores/message-v2/__tests__/instance-store.test.ts + test('extractUsageEntry returns null for exempt session', () => { + const session = { id: '1', exemptFromPremium: true }; + const info = { meta: { usage: { input: 100 } } }; + expect(extractUsageEntry(info, session)).toBeNull(); + }); + ``` + +2. **Test `applyUsageState()` bifurcation:** + ```typescript + test('applyUsageState routes to subagent fields when isSubagent=true', () => { + const state = createEmptyUsageState(); + const entry = { inputTokens: 100, isSubagent: true }; + applyUsageState(state, entry); + expect(state.subagentInputTokens).toBe(100); + expect(state.totalInputTokens).toBe(0); + }); + ``` + +3. **Test session creation sets flag:** + ```typescript + // packages/server/src/agents/__tests__/session-manager.test.ts + test('createSession sets exemptFromPremium when parentID present', () => { + const session = createSession({ parentID: 'parent-123' }); + expect(session.exemptFromPremium).toBe(true); + }); + ``` + +### Integration Tests + +1. **Full subagent delegation flow:** + - Start main agent session + - Trigger task tool with subagent + - Verify child session created with `exemptFromPremium: true` + - Verify main session premium = 1, subagent premium = 0 + +2. **Multiple subagent tasks:** + - Send prompt requiring 5 subagent tasks + - Verify total premium = 1 (main only) + - Verify internal task count = 5 + +3. **Mixed usage (main + subagent):** + - Multi-turn conversation with subagent tasks + - Verify premium increments only for main agent turns + - Verify internal usage accumulates correctly + +### Manual Testing Checklist + +- [ ] Create new session, send prompt (no subagents) → Premium = 1 +- [ ] Send prompt that triggers 1 subagent → Premium = 1, Internal = 1 +- [ ] Send prompt that triggers 3 subagents → Premium = 1, Internal = 3 +- [ ] Multi-turn conversation (3 turns, 2 with subagents) → Premium = 3, Internal = 2 +- [ ] Verify usage panel displays both categories correctly +- [ ] Verify tooltip/help text displays +- [ ] Verify session hierarchy (parent-child) shows correct flags +- [ ] Test with different subagent types (explore, general, etc.) +- [ ] Verify session JSON includes `exemptFromPremium` field +- [ ] Verify session state functions correctly filter by flag + +--- + +## Risk Assessment + +### Technical Risks + +| Risk | Impact | Likelihood | Mitigation | +|------|--------|-----------|------------| +| Flag not propagated correctly from backend | High | Low | Add integration tests, validate in session creation | +| Usage extraction logic misses edge cases | Medium | Medium | Comprehensive unit tests, manual testing | +| UI performance with dual accounting | Low | Low | Usage state updates are already efficient | +| Schema migration breaks existing sessions | Medium | Low | Add backward compatibility, default flag to false | +| Backend/frontend flag mismatch | High | Low | Backend is source of truth, frontend validates | + +### Product Risks + +| Risk | Impact | Likelihood | Mitigation | +|------|--------|-----------|------------| +| Users confused by dual accounting | Medium | Medium | Clear UI labels, tooltip explanations | +| Users expect full exemption (including main agent) | Low | Low | Clear docs, consistent behavior with competitors | +| Users abuse subagents to avoid costs | Low | Very Low | Subagents only callable by main agent, not directly | + +### Rollout Risks + +| Risk | Impact | Likelihood | Mitigation | +|------|--------|-----------|------------| +| Feature flag misconfiguration | Medium | Low | Test flag in dev/staging first | +| Breaking change for third-party integrations | Low | Very Low | Session API is internal, no external consumers | +| Premium usage history becomes inaccurate | Medium | Low | Migration script to backfill flag for old sessions | + +--- + +## Success Metrics + +### Quantitative Metrics + +1. **Premium consumption rate:** + - **Target:** 30-50% reduction in premium requests per session (for sessions using subagents) + - **Measurement:** Average premium requests per session (before vs after) + +2. **Subagent usage rate:** + - **Target:** 20-30% increase in subagent task invocations + - **Measurement:** Count of task tool invocations with subagent_type + +3. **User quota exhaustion:** + - **Target:** 40% reduction in users hitting premium limits + - **Measurement:** Weekly count of users reaching 0 remaining quota + +4. **Feature adoption:** + - **Target:** 15% increase in usage of subagent-heavy features (explore, research) + - **Measurement:** Usage frequency of specific agent types + +### Qualitative Metrics + +1. **User satisfaction:** + - Collect feedback via in-app survey about quota transparency + - Monitor support tickets related to premium usage + +2. **Feature discoverability:** + - Track how many users view the "Internal Tasks" section + - Monitor tooltip/help text interactions + +3. **Competitive parity:** + - User perception: "CodeNomad's quota system is fair/predictable" + - Benchmark against VSCode Copilot Chat behavior + +--- + +## Open Questions + +1. **Should internal usage be hidden by default?** + - Pro: Simpler UI, less clutter + - Con: Less transparency, harder to optimize token usage + +2. **Should we backfill `exemptFromPremium` for existing sessions?** + - Pro: Accurate historical data + - Con: Complex migration, could affect billing history + +3. **Should we expose internal usage in API responses?** + - Pro: Third-party integrations can track full usage + - Con: More data to maintain, potential performance impact + +4. **Should we allow manual exemption (not just subagents)?** + - Pro: Flexibility for future features (system operations, health checks) + - Con: Risk of abuse, more complex validation + +5. **Should we count thinking/reasoning tokens as internal?** + - Pro: Users only pay for visible output + - Con: Misalignment with LLM provider billing + +--- + +## Appendix: Reference Code Locations + +### Key Files for Implementation + +**Backend:** +- `packages/server/src/types/session.ts` - Session type definition +- `packages/server/src/agents/session-manager.ts` - Session creation logic +- `packages/server/src/database/schema.ts` - Database schema (if applicable) + +**Frontend - Types:** +- `packages/ui/src/types/session.ts` - Session and usage types + +**Frontend - Usage Tracking:** +- `packages/ui/src/stores/message-v2/instance-store.ts` - Usage extraction and application +- `packages/ui/src/stores/message-v2/session-info.ts` - Session-level aggregation +- `packages/ui/src/stores/session-events.ts` - SSE event handling + +**Frontend - Session Management:** +- `packages/ui/src/stores/session-state.ts` - Session hierarchy functions +- `packages/ui/src/stores/session-api.ts` - Session creation API + +**Frontend - UI:** +- `packages/ui/src/components/session/context-usage-panel.tsx` - Usage display +- `packages/ui/src/components/tool-call/renderers/task.tsx` - Task tool renderer + +**Reference Implementation:** +- `packages/mcp-server/src/tools/askUser.ts` - Zero-cost tool pattern +- `packages/mcp-server/src/server.ts` - JSON-RPC handling +- `packages/ui/src/lib/mcp-bridge.ts` - IPC communication + +### Subagent Identification + +**Agent Mode:** +- `packages/ui/src/types/session.ts:64-73` - Agent type with mode property +- `packages/ui/src/stores/session-api.ts:175` - Filtering non-subagents + +**Parent-Child Relationship:** +- `packages/ui/src/types/session.ts:32` - Session.parentId property +- `packages/ui/src/stores/session-state.ts:375-391` - Hierarchy functions +- `packages/ui/src/stores/session-state.ts:619` - Cleanup logic + +**Task Tool:** +- `packages/ui/src/components/tool-call/renderers/task.tsx` - Full task renderer + +### Premium Usage Tracking + +**Token Extraction:** +- `packages/ui/src/stores/message-v2/instance-store.ts:106-133` - extractUsageEntry() +- `packages/ui/src/stores/message-v2/instance-store.ts:135-146` - applyUsageState() + +**Session Info:** +- `packages/ui/src/stores/message-v2/session-info.ts:18-139` - updateSessionInfo() + +**Event Handling:** +- `packages/ui/src/stores/session-events.ts:224-266` - message.updated events + +--- + +## Approval & Sign-off + +**Product Owner:** _________________________ +**Engineering Lead:** _________________________ +**QA Lead:** _________________________ + +**Approved:** ☐ Yes ☐ No ☐ Needs Revision +**Date:** _________________________ + +--- + +## Implementation Summary (January 27, 2026) + +### Chosen Approach: **Server-side event ordering guard (no UI changes)** + +To mirror OpenCode CLI semantics (subagent sessions identified by `parentID`) while keeping the UI unchanged, we implemented a server-side ordering guard in the CodeNomad event bridge. The bridge now ensures the UI always receives a `session.updated` event (with `parentID`) before any `message.updated` event for that session. + +### Decision Rationale + +**Why this approach fits the constraints:** + +- ✅ **No UI changes** (explicit requirement) +- ✅ **Preserves OpenCode CLI behavior** (`Session.create({ parentID: ctx.sessionID })` remains the single source of truth) +- ✅ **Race-proof** even if SSE events arrive out of order +- ✅ **No schema changes** and no database migration + +### Implementation Details + +#### Backend Change (CodeNomad server) +**File:** `packages/server/src/workspaces/instance-events.ts` + +**Key logic added:** +1. **Session cache** keyed by `workspaceId + sessionId` to store `parentID` once known. +2. **Event serialization queue** to preserve ordering when async fetches are required. +3. **Synthetic `session.updated` emission** for uncached sessions when a `message.updated` arrives: + - Fetch `/session/:sessionID` from the OpenCode instance. + - Publish `session.updated` before the original `message.updated`. + +**Behavioral Flow:** +1. Subagent created via `task` tool → OpenCode assigns `parentID`. +2. If a `message.updated` arrives before `session.updated`, the bridge fetches the session and emits `session.updated` first. +3. UI receives `parentID` in time, so usage extraction correctly exempts subagents (premium not consumed). + +### Pros of Implemented Solution + +✅ **UI unchanged** — meets explicit constraint +✅ **Fool-proof ordering** — handles out-of-order SSE delivery +✅ **Preserves parent/child linkage** — still uses `parentID` as the authoritative marker +✅ **Low regression risk** — localized to event bridge + +### Cons / Trade-offs + +⚠️ **First-message fetch** — one extra HTTP call per uncached session +⚠️ **Async event queue** — slightly more complexity in event handling + +### Testing Results + +- ✅ `npm run typecheck` +- ✅ `npm run build` +- ✅ `npm run build:ui` +- ✅ `npm run build:tauri` + +**Warnings observed (non-blocking):** +- Vite chunking warnings about large chunks and mixed dynamic/static imports. + +--- + +**End of Document** + diff --git a/docs/failed-notifications-plan.md b/docs/failed-notifications-plan.md new file mode 100644 index 00000000..8caac092 --- /dev/null +++ b/docs/failed-notifications-plan.md @@ -0,0 +1,603 @@ +# Failed Notification Banner Enhancement + +## Overview + +Implement a persistent failed notification banner that captures `ask_user` and permission request failures (timeouts, session stops) and allows users to review and dismiss them individually or in bulk. + +## Current Architecture + +### Current UI State (Toolbar Section) + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ Session Toolbar │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ [Files] [🛡️ 2] [❓ 1] [Command Palette] Status [≡] │ +│ ▲ ▲ │ +│ │ │ │ +│ Permission Question │ +│ Banner Banner │ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +**Current Behavior:** +- **Permission Banner**: Shows active permission requests with badge count +- **Question Banner**: Shows active questions from `ask_user` tool with badge count +- **🐛 CURRENT BUG**: When timeout or session stop occurs: + - Notifications **remain in active queue** (not auto-dismissed) + - User loses context about what failed + - No way to see failure history + - **This is the primary issue we're fixing** + +### Current Data Flow + +``` +┌─────────────────┐ +│ MCP ask_user │ +│ Tool Call │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ ┌──────────────────┐ +│ PendingRequest │─────▶│ Question Queue │ +│ Manager │ │ (in-memory) │ +└────────┬────────┘ └──────────────────┘ + │ + │ Timeout/Cancel + ▼ +┌─────────────────┐ ┌──────────────────┐ +│ Returns: │ │ Question Queue │ +│ timedOut: true │──▶ │ STILL HAS IT! ❌ │ ← BUG! +│ answered: false│ │ Not removed │ +└─────────────────┘ └──────────────────┘ + │ + └──▶ ❌ No persistence, no history, no cleanup + +┌─────────────────┐ +│ Permission │ +│ Request │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ Permission Queue│ +│ (in-memory) │ +└────────┬────────┘ + │ + │ Timeout/Session Stop + ▼ +┌─────────────────┐ +│ Permission Queue│ +│ STILL HAS IT! ❌│ ← BUG! +│ Not removed │ +└─────────────────┘ + │ + └──▶ ❌ No persistence, no cleanup, stays in queue forever +``` + +## Proposed Enhancement + +### New UI State (Toolbar Section) + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ Session Toolbar │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ [Files] [🛡️ 2] [❓ 1] [❌ 3] [Command Palette] Status [≡] │ +│ ▲ ▲ ▲ │ +│ │ │ └─── NEW: Failed Notification Badge │ +│ Permission Question (red badge with count) │ +│ Banner Banner │ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### Failed Notification Panel (Expanded View) + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ Failed Notifications [Dismiss All] [✕] │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ 🛡️ Permission: read_file [✕] │ │ +│ │ Pattern: /src/**/*.ts │ │ +│ │ Reason: Session timeout │ │ +│ │ Time: 2026-01-20 18:15:30 │ │ +│ └─────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ ❓ Question: Select deployment target [✕] │ │ +│ │ Reason: Request timeout │ │ +│ │ Time: 2026-01-20 18:10:15 │ │ +│ └─────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ 🛡️ Permission: write_file [✕] │ │ +│ │ Pattern: /config/*.json │ │ +│ │ Reason: Session stopped │ │ +│ │ Time: 2026-01-20 17:55:42 │ │ +│ └─────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### New Data Flow + +``` +┌─────────────────┐ +│ MCP ask_user │ +│ Tool Call │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ ┌──────────────────┐ +│ PendingRequest │─────▶│ Question Queue │ +│ Manager │ │ (active) │ +└────────┬────────┘ └─────────┬────────┘ + │ │ + │ Timeout/Cancel │ + ▼ │ +┌─────────────────┐ │ +│ Returns: │ │ +│ timedOut: true │ │ +│ answered: false│ │ +└────────┬────────┘ │ + │ │ + │ ┌─────────────────────┐ │ + └▶│ 1. REMOVE from │◀┘ ✅ KEY FIX! + │ Question Queue │ + │ 2. ADD to Failed │ + │ Notifications │ + └─────────┬───────────┘ + │ + ▼ + ┌──────────────────────┐ + │ Failed Notifications │ + │ Store (persistent) │──▶ ✅ Persisted + │ - localStorage │ + │ - Auto-cleanup 5d │ + └──────────┬───────────┘ + │ + ▼ + ┌──────────────────────┐ + │ Failed Banner Badge │ + │ (shows count) │ + └──────────────────────┘ + +┌─────────────────┐ +│ Permission │ +│ Request │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ Permission Queue│ +│ (active) │ +└────────┬────────┘ + │ + │ Timeout/Session Stop + │ + │ ┌─────────────────────┐ + └▶│ 1. REMOVE from │ ✅ KEY FIX! + │ Permission Queue │ + │ 2. ADD to Failed │ + │ Notifications │ + └─────────┬───────────┘ + │ + ▼ + ┌──────────────────────┐ + │ Failed Notifications │ + │ Store (persistent) │──▶ ✅ Persisted + Cleaned + └──────────────────────┘ +``` + +## Proposed Changes + +### Storage Layer + +#### [NEW] [failed-notifications-store.ts](file:///Users/muhammadfaiz/Custom%20APP/CodeNomad/packages/ui/src/stores/failed-notifications-store.ts) + +**Purpose**: Manage failed notification state with localStorage persistence + +**Key Features**: +- Store failed `ask_user` and permission request notifications +- Persist to localStorage for cross-session survival +- Auto-cleanup notifications older than 5 days +- Individual and bulk dismiss operations +- Expose count for badge display + +**Schema**: +```typescript +interface FailedNotification { + id: string // Unique ID + type: 'question' | 'permission' // Notification type + title: string // Display title + reason: 'timeout' | 'session-stop' | 'cancelled' // Failure reason + timestamp: number // When it failed + instanceId: string // Which instance + + // Type-specific data + questionData?: { + questions: QuestionInfo[] + requestId: string + } + permissionData?: { + permission: PermissionRequestLike + } +} +``` + +**API**: +- `addFailedNotification(notification: FailedNotification): void` +- `removeFailedNotification(id: string): void` +- `dismissAllFailedNotifications(instanceId: string): void` +- `getFailedNotifications(instanceId: string): FailedNotification[]` +- `getFailedNotificationCount(instanceId: string): number` +- `cleanupOldNotifications(): void` // Run on init and periodically + +--- + +### UI Components + +#### [NEW] [failed-notification-banner.tsx](file:///Users/muhammadfaiz/Custom%20APP/CodeNomad/packages/ui/src/components/failed-notification-banner.tsx) + +**Purpose**: Badge button in toolbar showing count of failed notifications + +**Features**: +- Red badge style (distinct from active notification badges) +- Shows count (e.g., "3") or "9+" if > 9 +- Click opens the failed notification panel +- Hidden when count is 0 + +**Visual Style**: +- Uses `X` icon or `AlertCircle` icon +- Red accent color to indicate failure state +- Similar positioning to existing permission/question banners + +--- + +#### [NEW] [failed-notification-panel.tsx](file:///Users/muhammadfaiz/Custom%20APP/CodeNomad/packages/ui/src/components/failed-notification-panel.tsx) + +**Purpose**: Modal/drawer showing list of failed notifications + +**Features**: +- **Header**: Title + "Dismiss All" button + Close button +- **List**: Scrollable list of failed notification cards +- **Card Structure**: + - Icon (🛡️ for permission, ❓ for question) + - Title/summary + - Reason (timeout, session-stop, cancelled) + - Timestamp (formatted, e.g., "2 hours ago") + - Individual dismiss [X] button +- **Empty State**: "No failed notifications" message + +**Interactions**: +- Click [X] on card → dismiss that notification +- Click "Dismiss All" → dismiss all for this instance +- Click backdrop/close → close panel + +--- + +#### [MODIFY] [instance-shell2.tsx](file:///Users/muhammadfaiz/Custom%20APP/CodeNomad/packages/ui/src/components/instance/instance-shell2.tsx) + +**Changes**: +1. Import `FailedNotificationBanner` component +2. Add state for failed notification panel: `const [failedPanelOpen, setFailedPanelOpen] = createSignal(false)` +3. Add banner to toolbar (lines ~1458 and ~1548, next to existing banners): + ```tsx + setFailedPanelOpen(true)} + /> + ``` +4. Add panel component at bottom (around line ~1710, next to other modals): + ```tsx + setFailedPanelOpen(false)} + /> + ``` + +--- + +### Integration Points + +#### [MODIFY] [questions.ts](file:///Users/muhammadfaiz/Custom%20APP/CodeNomad/packages/ui/src/stores/questions.ts) + +**Changes**: Add failure detection and logging + +When a question request is cancelled/times out, capture it: +```typescript +export function handleQuestionFailure( + instanceId: string, + questionId: string, + reason: 'timeout' | 'session-stop' | 'cancelled' +): void { + const question = getPendingQuestion(instanceId) + if (question) { + // Step 1: Add to failed notifications (persistent storage) + addFailedNotification({ + id: `failed-q-${Date.now()}`, + type: 'question', + title: question.questions[0]?.question || 'Question', + reason, + timestamp: Date.now(), + instanceId, + questionData: { + questions: question.questions, + requestId: question.id + } + }) + + // Step 2: CRITICAL - Remove from active queue + // This ensures the notification badge disappears and it's not shown as "active" anymore + removeQuestionFromQueue(instanceId, questionId) + } +} +``` + +**CRITICAL**: The `removeQuestionFromQueue` call is essential. Without it, the question will: +- Stay in the active queue forever +- Show in the active question banner badge +- User sees duplicate state (active + failed) + +Add calls to `handleQuestionFailure` in: +- Cancel handler (when user/session cancels) +- Timeout handler (when MCP request times out) +- Session stop events (when session is forcibly terminated) + +--- + +#### [MODIFY] [instances.ts](file:///Users/muhammadfaiz/Custom%20APP/CodeNomad/packages/ui/src/stores/instances.ts) + +**Changes**: Add permission failure detection + +When a permission request fails, capture it: +```typescript +export function handlePermissionFailure( + instanceId: string, + permissionId: string, + reason: 'timeout' | 'session-stop' +): void { + const permission = getPermissionById(instanceId, permissionId) + if (permission) { + // Step 1: Add to failed notifications (persistent storage) + addFailedNotification({ + id: `failed-p-${Date.now()}`, + type: 'permission', + title: getPermissionDisplayTitle(permission), + reason, + timestamp: Date.now(), + instanceId, + permissionData: { permission } + }) + + // Step 2: CRITICAL - Remove from active permission queue + // This ensures the permission badge disappears and it's not shown as "active" anymore + removePermission(instanceId, permissionId) + } +} +``` + +**CRITICAL**: The `removePermission` call is essential. Without it, the permission will: +- Stay in the active queue forever +- Show in the active permission banner badge +- User sees duplicate state (active + failed) +- **This is the primary bug we're fixing!** + +Add calls in session event handlers: +- Session timeout events +- Session stop events (when forcibly terminated) +- Manual cancellation events + +--- + +#### [MODIFY] [pending.ts](file:///Users/muhammadfaiz/Custom%20APP/CodeNomad/packages/mcp-server/src/pending.ts) + +**Changes**: Emit failure events that UI can listen to + +When rejecting a request with timeout/cancelled: +```typescript +reject(id: string, error: Error): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + + // Clear timeout if set + if (request.timeout) { + clearTimeout(request.timeout); + } + + const reason = error.message === 'Question timeout' ? 'timeout' : + error.message === 'cancelled' ? 'cancelled' : 'session-stop'; + + // Emit failure event for UI to capture + this.emitFailure(id, reason); + + // ... rest of existing code +} +``` + +--- + +### Styling + +#### [NEW] [failed-notification.css](file:///Users/muhammadfaiz/Custom%20APP/CodeNomad/packages/ui/src/styles/components/failed-notification.css) + +**Purpose**: Styles for failed notification banner and panel + +**Key Styles**: +- `.failed-notification-trigger`: Red-accented badge button +- `.failed-notification-badge`: Red badge styling +- `.failed-notification-panel`: Modal/drawer styles +- `.failed-notification-card`: Individual notification card +- `.failed-notification-card-dismiss`: Dismiss button styles +- Hover/focus states +- Responsive layout for mobile + +--- + +## Verification Plan + +### Automated Tests + +No existing automated tests found for notification system. Manual verification will be primary approach. + +### Manual Verification + +#### Test 1: Question Timeout Scenario + +1. Start the CodeNomad app in dev mode: `npm run dev` +2. Create a new session and trigger an `ask_user` tool call (via agent interaction or test script) +3. **Do not answer** the question - wait for timeout (check MCP server timeout config) +4. **Verify**: + - ✅ Question disappears from active question banner + - ✅ Failed notification badge appears with count "1" + - ✅ Badge has red accent color + - ✅ Click badge → panel opens showing the failed question + - ✅ Panel shows reason: "Request timeout" + - ✅ Timestamp is accurate +5. Click individual [X] dismiss button +6. **Verify**: + - ✅ Card disappears + - ✅ Badge count decrements + - ✅ Panel closes when count reaches 0 + +#### Test 2: Permission Timeout Scenario + +1. Trigger a permission request (e.g., file read/write) +2. **Do not respond** - wait for timeout +3. **Verify**: + - ✅ Permission disappears from active permission banner + - ✅ Failed notification badge appears/increments + - ✅ Panel shows the failed permission with correct details + - ✅ Reason shows "Session timeout" or appropriate message + +#### Test 3: Session Stop Scenario + +1. Start a session with pending questions/permissions +2. **Stop the session** (force close or session termination) +3. **Verify**: + - ✅ Pending notifications move to failed state + - ✅ Failed banner shows all failed items + - ✅ Reason shows "Session stopped" + +#### Test 4: Persistence Across App Restarts + +1. Trigger multiple failed notifications (mix of questions and permissions) +2. **Close CodeNomad completely** +3. **Restart CodeNomad** +4. **Verify**: + - ✅ Failed notification badge still shows correct count + - ✅ Open panel → all failed notifications are still there + - ✅ Timestamps and details are preserved + +#### Test 5: Bulk Dismiss + +1. Accumulate 3+ failed notifications +2. Open failed notification panel +3. Click "Dismiss All" button +4. **Verify**: + - ✅ All cards disappear + - ✅ Panel closes + - ✅ Badge count goes to 0 + - ✅ localStorage is cleared + +#### Test 6: Auto-Cleanup (5 Day Rule) + +**Note**: This requires mocking the date or waiting 5 days. Suggest implementing a dev-only "Fast Forward Time" button for testing. + +1. Create failed notifications in localStorage with old timestamps +2. Manually set timestamps to > 5 days ago in localStorage +3. Restart the app or trigger cleanup manually +4. **Verify**: + - ✅ Old notifications are removed + - ✅ Recent notifications (< 5 days) remain + - ✅ Badge count is accurate + +#### Test 7: Multi-Instance Isolation + +1. Create 2 workspace instances +2. Generate failed notifications in both +3. **Verify**: + - ✅ Each instance shows only its own failed notifications + - ✅ Badge counts are independent + - ✅ Dismiss in one instance doesn't affect the other + +#### Test 8: UI Responsiveness (Mobile/Phone Layout) + +1. Resize browser to phone width or test on mobile device +2. Trigger failed notifications +3. **Verify**: + - ✅ Failed banner fits in toolbar without overflow + - ✅ Panel is full-width and readable + - ✅ Dismiss buttons are touch-friendly + +--- + +## Implementation Notes + +### Storage Format (localStorage) + +```typescript +// Key: `codenomad:failed-notifications:${instanceId}` +// Value: JSON array of FailedNotification objects +[ + { + "id": "failed-q-1737371730000", + "type": "question", + "title": "Select deployment target", + "reason": "timeout", + "timestamp": 1737371730000, + "instanceId": "workspace-1", + "questionData": { + "questions": [...], + "requestId": "req_123" + } + }, + // ... more notifications +] +``` + +### Auto-Cleanup Logic + +- Run `cleanupOldNotifications()` on app boot +- Run periodically (e.g., every hour) via interval +- Filter out notifications where `Date.now() - timestamp > 5 * 24 * 60 * 60 * 1000` (5 days) + +### Icon Choices + +- **Failed Badge Icon**: `AlertCircle` from lucide-solid (red accent) +- **Question Failed Card**: `MessageCircleQuestion` icon +- **Permission Failed Card**: `ShieldAlert` icon + +### Edge Cases + +1. **What if the same notification fails multiple times?** + - Use unique IDs with timestamp to allow duplicates + - User can see history of multiple failures + +2. **What if user clears localStorage manually?** + - Failed notifications are lost (acceptable tradeoff) + - No crash or errors + +3. **What if instanceId changes?** + - Old failed notifications remain under old key + - Could add a global cleanup button in settings (future enhancement) + +--- + +## Dependencies + +- No new external dependencies required +- Uses existing: + - SolidJS reactive primitives + - lucide-solid icons + - Existing CSS/theming system + - localStorage Web API diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..02c035b1 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,84 @@ +import js from "@eslint/js"; +import globals from "globals"; +import solid from "eslint-plugin-solid"; +import tseslint from "typescript-eslint"; + +const TS_FILES = [ + "packages/ui/src/**/*.{ts,tsx}", + "packages/electron-app/electron/**/*.{ts,tsx}", +]; + +export default tseslint.config( + { + ignores: [ + "**/node_modules/**", + "**/dist/**", + "**/release/**", + "packages/tauri-app/target/**", + "packages/**/public/**", + ], + }, + { + files: TS_FILES, + extends: [js.configs.recommended, ...tseslint.configs.recommended], + languageOptions: { + ecmaVersion: "latest", + sourceType: "module", + }, + rules: { + "no-console": "off", + + // Low-churn defaults: avoid forcing refactors across existing code. + "prefer-const": "off", + "no-extra-boolean-cast": "off", + "no-useless-escape": "off", + "no-control-regex": "off", + "no-case-declarations": "off", + + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "warn", + { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }, + ], + + "@typescript-eslint/no-unused-expressions": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-non-null-asserted-optional-chain": "off", + "@typescript-eslint/no-require-imports": "off", + "@typescript-eslint/no-unsafe-declaration-merging": "off", + }, + }, + { + files: ["packages/ui/src/**/*.{ts,tsx}"], + extends: [solid.configs["flat/recommended"]], + languageOptions: { + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + globals: { + ...globals.browser, + ...globals.es2021, + }, + }, + rules: { + // Low-churn: Solid's strictness is great, but too noisy for a first pass. + "solid/reactivity": "off", + "solid/style-prop": "off", + "solid/components-return-once": "off", + "solid/prefer-for": "off", + "solid/no-destructure": "off", + "solid/no-innerhtml": "warn", + }, + }, + { + files: ["packages/electron-app/electron/**/*.{ts,tsx}"], + languageOptions: { + globals: { + ...globals.node, + ...globals.es2021, + }, + }, + }, +); diff --git a/package-lock.json b/package-lock.json index cd9e08a9..4982ecb5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,22 +1,28 @@ { "name": "codenomad-workspace", - "version": "0.9.5", + "version": "0.9.2-patch.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codenomad-workspace", - "version": "0.9.5", - "license": "MIT", + "version": "0.9.2-patch.5", "dependencies": { "7zip-bin": "^5.2.0", "google-auth-library": "^10.5.0" }, "devDependencies": { - "baseline-browser-mapping": "^2.9.11" + "@eslint/js": "^9.39.2", + "baseline-browser-mapping": "^2.9.11", + "eslint": "^9.39.2", + "eslint-plugin-solid": "^0.14.5", + "globals": "^17.3.0", + "typescript": "^5.9.3", + "typescript-eslint": "^8.54.0" }, "workspaces": { "packages": [ + "packages/mcp-server", "packages/server", "packages/ui", "packages/electron-app", @@ -35,10 +41,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, "node_modules/@babel/code-frame": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -52,8 +68,6 @@ }, "node_modules/@babel/compat-data": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", "engines": { @@ -61,20 +75,19 @@ } }, "node_modules/@babel/core": { - "version": "7.28.5", + "version": "7.29.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -90,10 +103,16 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/generator": { "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { @@ -109,7 +128,7 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "dev": true, "license": "MIT", @@ -122,8 +141,6 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", "dependencies": { @@ -137,9 +154,30 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", "dev": true, "license": "MIT", @@ -159,9 +197,19 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", "dev": true, "license": "MIT", @@ -177,9 +225,19 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz", "integrity": "sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==", "dev": true, "license": "MIT", @@ -204,7 +262,7 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", "dev": true, "license": "MIT", @@ -218,8 +276,6 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { @@ -232,8 +288,6 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { @@ -250,7 +304,7 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "dev": true, "license": "MIT", @@ -263,8 +317,6 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, "license": "MIT", "engines": { @@ -273,7 +325,7 @@ }, "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", "dev": true, "license": "MIT", @@ -291,7 +343,7 @@ }, "node_modules/@babel/helper-replace-supers": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", "dev": true, "license": "MIT", @@ -309,7 +361,7 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "dev": true, "license": "MIT", @@ -347,7 +399,7 @@ }, "node_modules/@babel/helper-wrap-function": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", "dev": true, "license": "MIT", @@ -361,12 +413,12 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.4", + "version": "7.28.6", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -374,8 +426,6 @@ }, "node_modules/@babel/parser": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", - "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { @@ -390,7 +440,7 @@ }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", "dev": true, "license": "MIT", @@ -407,7 +457,7 @@ }, "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", "dev": true, "license": "MIT", @@ -423,7 +473,7 @@ }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", "dev": true, "license": "MIT", @@ -439,7 +489,7 @@ }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", "dev": true, "license": "MIT", @@ -457,7 +507,7 @@ }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", "dev": true, "license": "MIT", @@ -474,7 +524,7 @@ }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, "license": "MIT", @@ -487,7 +537,7 @@ }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", "dev": true, "license": "MIT", @@ -503,7 +553,7 @@ }, "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, "license": "MIT", @@ -518,11 +568,11 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", + "version": "7.28.6", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -533,7 +583,7 @@ }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, "license": "MIT", @@ -564,7 +614,7 @@ }, "node_modules/@babel/plugin-transform-async-generator-functions": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", "dev": true, "license": "MIT", @@ -582,7 +632,7 @@ }, "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", "dev": true, "license": "MIT", @@ -600,7 +650,7 @@ }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", "dev": true, "license": "MIT", @@ -616,7 +666,7 @@ }, "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", "dev": true, "license": "MIT", @@ -632,7 +682,7 @@ }, "node_modules/@babel/plugin-transform-class-properties": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", "dev": true, "license": "MIT", @@ -649,7 +699,7 @@ }, "node_modules/@babel/plugin-transform-class-static-block": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", "dev": true, "license": "MIT", @@ -666,7 +716,7 @@ }, "node_modules/@babel/plugin-transform-classes": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", "dev": true, "license": "MIT", @@ -687,7 +737,7 @@ }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", "dev": true, "license": "MIT", @@ -704,7 +754,7 @@ }, "node_modules/@babel/plugin-transform-destructuring": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", "dev": true, "license": "MIT", @@ -721,7 +771,7 @@ }, "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", "dev": true, "license": "MIT", @@ -738,7 +788,7 @@ }, "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", "dev": true, "license": "MIT", @@ -754,7 +804,7 @@ }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", "dev": true, "license": "MIT", @@ -771,7 +821,7 @@ }, "node_modules/@babel/plugin-transform-dynamic-import": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", "dev": true, "license": "MIT", @@ -787,7 +837,7 @@ }, "node_modules/@babel/plugin-transform-explicit-resource-management": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", "dev": true, "license": "MIT", @@ -804,7 +854,7 @@ }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", "dev": true, "license": "MIT", @@ -820,7 +870,7 @@ }, "node_modules/@babel/plugin-transform-export-namespace-from": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", "dev": true, "license": "MIT", @@ -836,7 +886,7 @@ }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", "dev": true, "license": "MIT", @@ -853,7 +903,7 @@ }, "node_modules/@babel/plugin-transform-function-name": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", "dev": true, "license": "MIT", @@ -871,7 +921,7 @@ }, "node_modules/@babel/plugin-transform-json-strings": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", "dev": true, "license": "MIT", @@ -887,7 +937,7 @@ }, "node_modules/@babel/plugin-transform-literals": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", "dev": true, "license": "MIT", @@ -903,7 +953,7 @@ }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", "dev": true, "license": "MIT", @@ -919,7 +969,7 @@ }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", "dev": true, "license": "MIT", @@ -935,7 +985,7 @@ }, "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", "dev": true, "license": "MIT", @@ -952,7 +1002,7 @@ }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", "dev": true, "license": "MIT", @@ -969,7 +1019,7 @@ }, "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", "dev": true, "license": "MIT", @@ -988,7 +1038,7 @@ }, "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", "dev": true, "license": "MIT", @@ -1005,7 +1055,7 @@ }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", "dev": true, "license": "MIT", @@ -1022,7 +1072,7 @@ }, "node_modules/@babel/plugin-transform-new-target": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", "dev": true, "license": "MIT", @@ -1038,7 +1088,7 @@ }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", "dev": true, "license": "MIT", @@ -1054,7 +1104,7 @@ }, "node_modules/@babel/plugin-transform-numeric-separator": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", "dev": true, "license": "MIT", @@ -1070,7 +1120,7 @@ }, "node_modules/@babel/plugin-transform-object-rest-spread": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", "dev": true, "license": "MIT", @@ -1090,7 +1140,7 @@ }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", "dev": true, "license": "MIT", @@ -1107,7 +1157,7 @@ }, "node_modules/@babel/plugin-transform-optional-catch-binding": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", "dev": true, "license": "MIT", @@ -1123,7 +1173,7 @@ }, "node_modules/@babel/plugin-transform-optional-chaining": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", "dev": true, "license": "MIT", @@ -1140,7 +1190,7 @@ }, "node_modules/@babel/plugin-transform-parameters": { "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "dev": true, "license": "MIT", @@ -1156,7 +1206,7 @@ }, "node_modules/@babel/plugin-transform-private-methods": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", "dev": true, "license": "MIT", @@ -1173,7 +1223,7 @@ }, "node_modules/@babel/plugin-transform-private-property-in-object": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", "dev": true, "license": "MIT", @@ -1191,7 +1241,7 @@ }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", "dev": true, "license": "MIT", @@ -1207,7 +1257,7 @@ }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", "dev": true, "license": "MIT", @@ -1223,7 +1273,7 @@ }, "node_modules/@babel/plugin-transform-regexp-modifiers": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", "dev": true, "license": "MIT", @@ -1240,7 +1290,7 @@ }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", "dev": true, "license": "MIT", @@ -1256,7 +1306,7 @@ }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", "dev": true, "license": "MIT", @@ -1272,7 +1322,7 @@ }, "node_modules/@babel/plugin-transform-spread": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", "dev": true, "license": "MIT", @@ -1289,7 +1339,7 @@ }, "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", "dev": true, "license": "MIT", @@ -1305,7 +1355,7 @@ }, "node_modules/@babel/plugin-transform-template-literals": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", "dev": true, "license": "MIT", @@ -1321,7 +1371,7 @@ }, "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", "dev": true, "license": "MIT", @@ -1337,7 +1387,7 @@ }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", "dev": true, "license": "MIT", @@ -1353,7 +1403,7 @@ }, "node_modules/@babel/plugin-transform-unicode-property-regex": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", "dev": true, "license": "MIT", @@ -1370,7 +1420,7 @@ }, "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", "dev": true, "license": "MIT", @@ -1387,7 +1437,7 @@ }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", "dev": true, "license": "MIT", @@ -1404,7 +1454,7 @@ }, "node_modules/@babel/preset-env": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.0.tgz", + "resolved": "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.29.0.tgz", "integrity": "sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==", "dev": true, "license": "MIT", @@ -1487,9 +1537,19 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "resolved": "https://registry.npmmirror.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "license": "MIT", @@ -1504,7 +1564,7 @@ }, "node_modules/@babel/runtime": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.28.6.tgz", "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", "dev": true, "license": "MIT", @@ -1514,8 +1574,6 @@ }, "node_modules/@babel/template": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1529,8 +1587,6 @@ }, "node_modules/@babel/traverse": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { @@ -1548,8 +1604,6 @@ }, "node_modules/@babel/types": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { @@ -1562,11 +1616,15 @@ }, "node_modules/@canvas/image-data": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@canvas/image-data/-/image-data-1.1.0.tgz", + "resolved": "https://registry.npmmirror.com/@canvas/image-data/-/image-data-1.1.0.tgz", "integrity": "sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==", "dev": true, "license": "MIT" }, + "node_modules/@codenomad/mcp-server": { + "resolved": "packages/mcp-server", + "link": true + }, "node_modules/@codenomad/tauri-app": { "resolved": "packages/tauri-app", "link": true @@ -1585,29 +1643,113 @@ "solid-js": "^1.8" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" }, "engines": { - "node": ">=12" + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" } }, "node_modules/@develar/schema-utils": { "version": "2.6.5", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.0", @@ -1646,6 +1788,33 @@ "concat-map": "0.0.1" } }, + "node_modules/@electron/asar/node_modules/commander": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@electron/asar/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@electron/asar/node_modules/minimatch": { "version": "3.1.2", "dev": true, @@ -1657,6 +1826,52 @@ "node": "*" } }, + "node_modules/@electron/fuses": { + "version": "1.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.1", + "fs-extra": "^9.0.1", + "minimist": "^1.2.5" + }, + "bin": { + "electron-fuses": "dist/bin.js" + } + }, + "node_modules/@electron/fuses/node_modules/fs-extra": { + "version": "9.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/fuses/node_modules/jsonfile": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/fuses/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@electron/get": { "version": "2.0.3", "dev": true, @@ -1677,8 +1892,45 @@ "global-agent": "^3.0.0" } }, + "node_modules/@electron/get/node_modules/fs-extra": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@electron/get/node_modules/fs-extra/node_modules/jsonfile": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/get/node_modules/fs-extra/node_modules/universalify": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@electron/notarize": { - "version": "2.2.1", + "version": "2.5.0", "dev": true, "license": "MIT", "dependencies": { @@ -1724,7 +1976,7 @@ } }, "node_modules/@electron/osx-sign": { - "version": "1.0.5", + "version": "1.3.3", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -1786,44 +2038,141 @@ "node": ">= 10.0.0" } }, - "node_modules/@electron/universal": { - "version": "1.5.1", + "node_modules/@electron/rebuild": { + "version": "4.0.3", "dev": true, "license": "MIT", "dependencies": { - "@electron/asar": "^3.2.1", - "@malept/cross-spawn-promise": "^1.1.0", - "debug": "^4.3.1", - "dir-compare": "^3.0.0", - "fs-extra": "^9.0.1", - "minimatch": "^3.0.4", - "plist": "^3.0.4" + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "got": "^11.7.0", + "graceful-fs": "^4.2.11", + "node-abi": "^4.2.0", + "node-api-version": "^0.2.1", + "node-gyp": "^11.2.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^7.5.6", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" }, "engines": { - "node": ">=8.6" + "node": ">=22.12.0" } }, - "node_modules/@electron/universal/node_modules/brace-expansion": { - "version": "1.1.12", + "node_modules/@electron/rebuild/node_modules/yargs": { + "version": "17.7.2", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/rebuild/node_modules/yargs/node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/rebuild/node_modules/yargs/node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@electron/rebuild/node_modules/yargs/node_modules/cliui/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@electron/rebuild/node_modules/yargs/node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@electron/rebuild/node_modules/yargs/node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/rebuild/node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/universal": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/asar": "^3.3.1", + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.3.1", + "dir-compare": "^4.2.0", + "fs-extra": "^11.1.1", + "minimatch": "^9.0.3", + "plist": "^3.1.0" + }, + "engines": { + "node": ">=16.4" } }, "node_modules/@electron/universal/node_modules/fs-extra": { - "version": "9.1.0", + "version": "11.3.3", "dev": true, "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=14.14" } }, "node_modules/@electron/universal/node_modules/jsonfile": { @@ -1838,14 +2187,25 @@ } }, "node_modules/@electron/universal/node_modules/minimatch": { - "version": "3.1.2", + "version": "9.0.5", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@electron/universal/node_modules/minimatch/node_modules/brace-expansion": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" } }, "node_modules/@electron/universal/node_modules/universalify": { @@ -1856,9 +2216,67 @@ "node": ">= 10.0.0" } }, + "node_modules/@electron/windows-sign": { + "version": "1.2.2", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "cross-dirname": "^0.1.0", + "debug": "^4.3.4", + "fs-extra": "^11.1.1", + "minimist": "^1.2.8", + "postject": "^1.0.0-alpha.6" + }, + "bin": { + "electron-windows-sign": "bin/electron-windows-sign.js" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/windows-sign/node_modules/fs-extra": { + "version": "11.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/windows-sign/node_modules/jsonfile": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/windows-sign/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@emnapi/runtime": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "resolved": "https://registry.npmmirror.com/@emnapi/runtime/-/runtime-1.8.1.tgz", "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", "dev": true, "license": "MIT", @@ -1867,10 +2285,10 @@ "tslib": "^2.4.0" } }, - "node_modules/@esbuild/darwin-x64": { + "node_modules/@esbuild/darwin-arm64": { "version": "0.25.12", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", @@ -1882,193 +2300,320 @@ "node": ">=18" } }, - "node_modules/@fastify/accept-negotiator": { - "version": "1.1.0", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/@fastify/ajv-compiler": { - "version": "3.6.0", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "dev": true, "license": "MIT", "dependencies": { - "ajv": "^8.11.0", - "ajv-formats": "^2.1.1", - "fast-uri": "^2.0.0" + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@fastify/ajv-compiler/node_modules/ajv": { - "version": "8.17.1", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://opencollective.com/eslint" } }, - "node_modules/@fastify/ajv-compiler/node_modules/ajv/node_modules/fast-uri": { - "version": "3.1.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/@fastify/ajv-compiler/node_modules/json-schema-traverse": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "dev": true, "license": "MIT", "engines": { - "node": ">=14" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@fastify/cors": { - "version": "8.5.0", - "license": "MIT", + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "fastify-plugin": "^4.0.0", - "mnemonist": "0.39.6" + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@fastify/error": { - "version": "3.4.1", - "license": "MIT" - }, - "node_modules/@fastify/fast-json-stringify-compiler": { - "version": "4.3.0", + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, "license": "MIT", "dependencies": { - "fast-json-stringify": "^5.7.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@fastify/merge-json-schemas": { - "version": "0.1.1", - "license": "MIT", + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", "dependencies": { - "fast-deep-equal": "^3.1.3" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/@fastify/reply-from": { - "version": "9.8.0", - "license": "MIT", + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@fastify/error": "^3.0.0", - "end-of-stream": "^1.4.4", - "fast-content-type-parse": "^1.1.0", - "fast-querystring": "^1.0.0", - "fastify-plugin": "^4.0.0", - "toad-cache": "^3.7.0", - "undici": "^5.19.1" + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@fastify/reply-from/node_modules/undici": { - "version": "5.29.0", - "license": "MIT", + "node_modules/@eslint/core": { + "version": "0.17.0", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@fastify/busboy": "^2.0.0" + "@types/json-schema": "^7.0.15" }, "engines": { - "node": ">=14.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@fastify/send": { - "version": "2.1.0", + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "dev": true, "license": "MIT", "dependencies": { - "@lukeed/ms": "^2.0.1", - "escape-html": "~1.0.3", - "fast-decode-uri-component": "^1.0.1", - "http-errors": "2.0.0", - "mime": "^3.0.0" - } - }, - "node_modules/@fastify/send/node_modules/mime": { - "version": "3.0.0", - "license": "MIT", - "bin": { - "mime": "cli.js" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=10.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@fastify/static": { - "version": "7.0.4", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, "license": "MIT", "dependencies": { - "@fastify/accept-negotiator": "^1.0.0", - "@fastify/send": "^2.0.0", - "content-disposition": "^0.5.3", - "fastify-plugin": "^4.0.0", - "fastq": "^1.17.0", - "glob": "^10.3.4" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@fastify/static/node_modules/glob": { - "version": "10.5.0", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "brace-expansion": "^1.1.7" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://eslint.org/donate" } }, - "node_modules/@fastify/static/node_modules/minimatch": { - "version": "9.0.5", - "license": "ISC", + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "brace-expansion": "^2.0.1" + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@fastify/accept-negotiator": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@fastify/ajv-compiler": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "ajv": "^8.11.0", + "ajv-formats": "^2.1.1", + "fast-uri": "^2.0.0" + } + }, + "node_modules/@fastify/ajv-compiler/node_modules/ajv": { + "version": "8.17.1", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@fastify/static/node_modules/minipass": { - "version": "7.1.2", - "license": "ISC", + "node_modules/@fastify/ajv-compiler/node_modules/ajv-formats": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@fastify/ajv-compiler/node_modules/ajv/node_modules/fast-uri": { + "version": "3.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/@fastify/ajv-compiler/node_modules/ajv/node_modules/json-schema-traverse": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/@fastify/ajv-compiler/node_modules/fast-uri": { + "version": "2.4.0", + "license": "MIT" + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=14" + } + }, + "node_modules/@fastify/cors": { + "version": "8.5.0", + "license": "MIT", + "dependencies": { + "fastify-plugin": "^4.0.0", + "mnemonist": "0.39.6" + } + }, + "node_modules/@fastify/cors/node_modules/fastify-plugin": { + "version": "4.5.1", + "license": "MIT" + }, + "node_modules/@fastify/fast-json-stringify-compiler": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "fast-json-stringify": "^5.7.0" } }, + "node_modules/@fastify/merge-json-schemas": { + "version": "0.1.1", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + } + }, + "node_modules/@fastify/send": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "@lukeed/ms": "^2.0.1", + "escape-html": "~1.0.3", + "fast-decode-uri-component": "^1.0.1", + "http-errors": "2.0.0", + "mime": "^3.0.0" + } + }, + "node_modules/@fastify/static": { + "version": "7.0.4", + "license": "MIT", + "dependencies": { + "@fastify/accept-negotiator": "^1.0.0", + "@fastify/send": "^2.0.0", + "content-disposition": "^0.5.3", + "fastify-plugin": "^4.0.0", + "fastq": "^1.17.0", + "glob": "^10.3.4" + } + }, + "node_modules/@fastify/static/node_modules/fastify-plugin": { + "version": "4.5.1", + "license": "MIT" + }, "node_modules/@floating-ui/core": { - "version": "1.7.3", + "version": "1.7.4", "license": "MIT", "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "node_modules/@floating-ui/dom": { - "version": "1.7.4", + "version": "1.7.5", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.7.3", + "@floating-ui/core": "^1.7.4", "@floating-ui/utils": "^0.2.10" } }, @@ -2110,9 +2655,63 @@ "solid-js": "^1.9.0" } }, + "node_modules/@hono/node-server": { + "version": "1.19.9", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", "cpu": [ "arm64" @@ -2135,7 +2734,7 @@ }, "node_modules/@img/sharp-darwin-x64": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", "cpu": [ "x64" @@ -2158,7 +2757,7 @@ }, "node_modules/@img/sharp-libvips-darwin-arm64": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", "cpu": [ "arm64" @@ -2175,7 +2774,7 @@ }, "node_modules/@img/sharp-libvips-darwin-x64": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", "cpu": [ "x64" @@ -2192,7 +2791,7 @@ }, "node_modules/@img/sharp-libvips-linux-arm": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", "cpu": [ "arm" @@ -2209,7 +2808,7 @@ }, "node_modules/@img/sharp-libvips-linux-arm64": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", "cpu": [ "arm64" @@ -2226,7 +2825,7 @@ }, "node_modules/@img/sharp-libvips-linux-s390x": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", "cpu": [ "s390x" @@ -2243,7 +2842,7 @@ }, "node_modules/@img/sharp-libvips-linux-x64": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", "cpu": [ "x64" @@ -2260,7 +2859,7 @@ }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", "cpu": [ "arm64" @@ -2277,7 +2876,7 @@ }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", "cpu": [ "x64" @@ -2294,7 +2893,7 @@ }, "node_modules/@img/sharp-linux-arm": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", "cpu": [ "arm" @@ -2317,7 +2916,7 @@ }, "node_modules/@img/sharp-linux-arm64": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", "cpu": [ "arm64" @@ -2340,7 +2939,7 @@ }, "node_modules/@img/sharp-linux-s390x": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", "cpu": [ "s390x" @@ -2363,7 +2962,7 @@ }, "node_modules/@img/sharp-linux-x64": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", "cpu": [ "x64" @@ -2386,7 +2985,7 @@ }, "node_modules/@img/sharp-linuxmusl-arm64": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", "cpu": [ "arm64" @@ -2409,7 +3008,7 @@ }, "node_modules/@img/sharp-linuxmusl-x64": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", "cpu": [ "x64" @@ -2432,7 +3031,7 @@ }, "node_modules/@img/sharp-wasm32": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", "cpu": [ "wasm32" @@ -2452,7 +3051,7 @@ }, "node_modules/@img/sharp-win32-ia32": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", "cpu": [ "ia32" @@ -2472,7 +3071,7 @@ }, "node_modules/@img/sharp-win32-x64": { "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "resolved": "https://registry.npmmirror.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", "cpu": [ "x64" @@ -2491,7 +3090,7 @@ } }, "node_modules/@internationalized/date": { - "version": "3.10.0", + "version": "3.11.0", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" @@ -2504,29 +3103,6 @@ "@swc/helpers": "^0.5.0" } }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", - "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "license": "ISC", @@ -2542,32 +3118,8 @@ "node": ">=12" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.2.2", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -2581,6 +3133,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@isaacs/cliui/node_modules/string-width/node_modules/emoji-regex": { + "version": "9.2.2", + "license": "MIT" + }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.2", "license": "MIT", @@ -2594,6 +3150,16 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", "license": "MIT", @@ -2609,6 +3175,27 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "dev": true, @@ -2637,7 +3224,7 @@ }, "node_modules/@jridgewell/source-map": { "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.11.tgz", "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dev": true, "license": "MIT", @@ -2701,7 +3288,7 @@ } }, "node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", + "version": "2.0.0", "dev": true, "funding": [ { @@ -2718,7 +3305,7 @@ "cross-spawn": "^7.0.1" }, "engines": { - "node": ">= 10" + "node": ">= 12.13.0" } }, "node_modules/@malept/flatpak-bundler": { @@ -2768,6 +3355,62 @@ "node": ">= 10.0.0" } }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.26.0", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { + "version": "8.17.1", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/ajv/node_modules/json-schema-traverse": { + "version": "1.0.0", + "license": "MIT" + }, "node_modules/@neuralnomads/codenomad": { "resolved": "packages/server", "link": true @@ -2808,10 +3451,45 @@ "node": ">= 8" } }, + "node_modules/@npmcli/agent": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/fs/node_modules/semver": { + "version": "7.7.3", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@opencode-ai/sdk": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.1.11.tgz", - "integrity": "sha512-vqdNDz8Q+4bygmDdQem6oxhU31ci4JVdoND4ZJNeCs9x6OIU6MM3ybgemGpzNkgtJDlfb4xCdrPaZZ6Sr3V1IQ==", "license": "MIT" }, "node_modules/@pinojs/redact": { @@ -2836,7 +3514,7 @@ }, "node_modules/@quansync/fs": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz", + "resolved": "https://registry.npmmirror.com/@quansync/fs/-/fs-1.0.0.tgz", "integrity": "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==", "dev": true, "license": "MIT", @@ -2849,7 +3527,7 @@ }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.3.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", + "resolved": "https://registry.npmmirror.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==", "dev": true, "license": "MIT", @@ -2874,7 +3552,7 @@ }, "node_modules/@rollup/plugin-terser": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "resolved": "https://registry.npmmirror.com/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", "dev": true, "license": "MIT", @@ -2897,7 +3575,7 @@ }, "node_modules/@rollup/pluginutils": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", "dev": true, "license": "MIT", @@ -2918,23 +3596,17 @@ } } }, - "node_modules/@rollup/pluginutils/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } + "license": "MIT" }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.52.5", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.57.1", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", @@ -2944,48 +3616,48 @@ ] }, "node_modules/@shikijs/core": { - "version": "3.15.0", + "version": "3.22.0", "license": "MIT", "dependencies": { - "@shikijs/types": "3.15.0", + "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "node_modules/@shikijs/engine-javascript": { - "version": "3.15.0", + "version": "3.22.0", "license": "MIT", "dependencies": { - "@shikijs/types": "3.15.0", + "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^4.3.3" + "oniguruma-to-es": "^4.3.4" } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "3.15.0", + "version": "3.22.0", "license": "MIT", "dependencies": { - "@shikijs/types": "3.15.0", + "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "node_modules/@shikijs/langs": { - "version": "3.15.0", + "version": "3.22.0", "license": "MIT", "dependencies": { - "@shikijs/types": "3.15.0" + "@shikijs/types": "3.22.0" } }, "node_modules/@shikijs/themes": { - "version": "3.15.0", + "version": "3.22.0", "license": "MIT", "dependencies": { - "@shikijs/types": "3.15.0" + "@shikijs/types": "3.22.0" } }, "node_modules/@shikijs/types": { - "version": "3.15.0", + "version": "3.22.0", "license": "MIT", "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", @@ -3018,7 +3690,7 @@ } }, "node_modules/@solid-primitives/keyed": { - "version": "1.5.2", + "version": "1.5.3", "license": "MIT", "peerDependencies": { "solid-js": "^1.6.12" @@ -3213,7 +3885,7 @@ }, "node_modules/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "resolved": "https://registry.npmmirror.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", "dev": true, "license": "Apache-2.0", @@ -3226,7 +3898,7 @@ }, "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string": { "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz", "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", "dev": true, "license": "MIT", @@ -3235,7 +3907,7 @@ } }, "node_modules/@swc/helpers": { - "version": "0.5.17", + "version": "0.5.18", "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" @@ -3253,9 +3925,9 @@ } }, "node_modules/@tauri-apps/api": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.9.1.tgz", - "integrity": "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw==", + "version": "2.10.1", + "resolved": "https://registry.npmmirror.com/@tauri-apps/api/-/api-2.10.1.tgz", + "integrity": "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==", "license": "Apache-2.0 OR MIT", "funding": { "type": "opencollective", @@ -3263,7 +3935,7 @@ } }, "node_modules/@tauri-apps/cli": { - "version": "2.9.4", + "version": "2.10.0", "dev": true, "license": "Apache-2.0 OR MIT", "bin": { @@ -3277,23 +3949,23 @@ "url": "https://opencollective.com/tauri" }, "optionalDependencies": { - "@tauri-apps/cli-darwin-arm64": "2.9.4", - "@tauri-apps/cli-darwin-x64": "2.9.4", - "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.4", - "@tauri-apps/cli-linux-arm64-gnu": "2.9.4", - "@tauri-apps/cli-linux-arm64-musl": "2.9.4", - "@tauri-apps/cli-linux-riscv64-gnu": "2.9.4", - "@tauri-apps/cli-linux-x64-gnu": "2.9.4", - "@tauri-apps/cli-linux-x64-musl": "2.9.4", - "@tauri-apps/cli-win32-arm64-msvc": "2.9.4", - "@tauri-apps/cli-win32-ia32-msvc": "2.9.4", - "@tauri-apps/cli-win32-x64-msvc": "2.9.4" - } - }, - "node_modules/@tauri-apps/cli-darwin-x64": { - "version": "2.9.4", + "@tauri-apps/cli-darwin-arm64": "2.10.0", + "@tauri-apps/cli-darwin-x64": "2.10.0", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.10.0", + "@tauri-apps/cli-linux-arm64-gnu": "2.10.0", + "@tauri-apps/cli-linux-arm64-musl": "2.10.0", + "@tauri-apps/cli-linux-riscv64-gnu": "2.10.0", + "@tauri-apps/cli-linux-x64-gnu": "2.10.0", + "@tauri-apps/cli-linux-x64-musl": "2.10.0", + "@tauri-apps/cli-win32-arm64-msvc": "2.10.0", + "@tauri-apps/cli-win32-ia32-msvc": "2.10.0", + "@tauri-apps/cli-win32-x64-msvc": "2.10.0" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "2.10.0", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "Apache-2.0 OR MIT", @@ -3305,48 +3977,28 @@ "node": ">= 10" } }, + "node_modules/@tauri-apps/plugin-notification": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/@tauri-apps/plugin-notification/-/plugin-notification-2.3.3.tgz", + "integrity": "sha512-Zw+ZH18RJb41G4NrfHgIuofJiymusqN+q8fGUIIV7vyCH+5sSn5coqRv/MWB9qETsUs97vmU045q7OyseCV3Qg==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, "node_modules/@tauri-apps/plugin-opener": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.5.3.tgz", + "resolved": "https://registry.npmmirror.com/@tauri-apps/plugin-opener/-/plugin-opener-2.5.3.tgz", "integrity": "sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ==", "license": "MIT OR Apache-2.0", "dependencies": { "@tauri-apps/api": "^2.8.0" } }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.12", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "dev": true, - "license": "MIT" - }, "node_modules/@types/babel__core": { "version": "7.20.5", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -3399,6 +4051,14 @@ "@types/ms": "*" } }, + "node_modules/@types/dompurify": { + "version": "3.2.0", + "deprecated": "This is a stub types definition. dompurify provides its own type definitions, so you do not need this installed.", + "license": "MIT", + "dependencies": { + "dompurify": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.8", "dev": true, @@ -3420,7 +4080,12 @@ } }, "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", "dev": true, "license": "MIT" }, @@ -3445,12 +4110,11 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.19.0", + "version": "25.2.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/plist": { @@ -3465,7 +4129,7 @@ }, "node_modules/@types/resolve": { "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "resolved": "https://registry.npmmirror.com/@types/resolve/-/resolve-1.20.2.tgz", "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true, "license": "MIT" @@ -3480,9 +4144,7 @@ }, "node_modules/@types/trusted-types": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/unist": { @@ -3503,939 +4165,885 @@ "@types/node": "*" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "license": "ISC" - }, - "node_modules/@vite-pwa/assets-generator": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vite-pwa/assets-generator/-/assets-generator-1.0.2.tgz", - "integrity": "sha512-MCbrb508JZHqe7bUibmZj/lyojdhLRnfkmyXnkrCM2zVrjTgL89U8UEfInpKTvPeTnxsw2hmyZxnhsdNR6yhwg==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.54.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "cac": "^6.7.14", - "colorette": "^2.0.20", - "consola": "^3.4.2", - "sharp": "^0.33.5", - "sharp-ico": "^0.1.5", - "unconfig": "^7.3.1" - }, - "bin": { - "pwa-assets-generator": "bin/pwa-assets-generator.mjs" + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/type-utils": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": ">=16.14.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vue/reactivity": { - "version": "3.5.24", - "license": "MIT", - "dependencies": { - "@vue/shared": "3.5.24" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.54.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@vue/shared": { - "version": "3.5.24", - "license": "MIT" - }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.11", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", "dev": true, "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">= 4" } }, - "node_modules/7zip-bin": { - "version": "5.2.0", - "license": "MIT" - }, - "node_modules/abstract-logging": { - "version": "2.0.1", - "license": "MIT" - }, - "node_modules/acorn": { - "version": "8.15.0", + "node_modules/@typescript-eslint/parser": { + "version": "8.54.0", "dev": true, "license": "MIT", - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "debug": "^4.4.3" }, "engines": { - "node": ">=0.4.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", + "node_modules/@typescript-eslint/project-service": { + "version": "8.54.0", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.11.0" + "@typescript-eslint/tsconfig-utils": "^8.54.0", + "@typescript-eslint/types": "^8.54.0", + "debug": "^4.4.3" }, "engines": { - "node": ">=0.4.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.54.0", "dev": true, "license": "MIT", "dependencies": { - "debug": "4" + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0" }, "engines": { - "node": ">= 6.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/ajv": { - "version": "6.12.6", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.54.0", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/ajv-formats": { - "version": "2.1.1", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.54.0", + "dev": true, "license": "MIT", "dependencies": { - "ajv": "^8.0.0" + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" }, - "peerDependencies": { - "ajv": "^8.0.0" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", + "node_modules/@typescript-eslint/types": { + "version": "8.54.0", + "dev": true, "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/ajv-formats/node_modules/fast-uri": { - "version": "3.1.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.54.0", "dev": true, "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.54.0", + "@typescript-eslint/tsconfig-utils": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/ansi-sequence-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.3.tgz", - "integrity": "sha512-+fksAx9eG3Ab6LDnLs3ZqZa8KVJ/jYnX+D4Qe1azX+LFGFAXqynCQLOdLpNYN/l9e7l6hMWwZbrnctqr6eSQSw==", - "license": "MIT" - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", "dependencies": { - "color-convert": "^2.0.1" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/any-promise": { - "version": "1.3.0", + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch/node_modules/brace-expansion": { + "version": "2.0.2", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } }, - "node_modules/anymatch": { - "version": "3.1.3", + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.4", "dev": true, "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 8" + "node": ">=10" } }, - "node_modules/app-builder-bin": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/app-builder-lib": { - "version": "24.13.3", + "node_modules/@typescript-eslint/utils": { + "version": "8.54.0", "dev": true, "license": "MIT", "dependencies": { - "@develar/schema-utils": "~2.6.5", - "@electron/notarize": "2.2.1", - "@electron/osx-sign": "1.0.5", - "@electron/universal": "1.5.1", - "@malept/flatpak-bundler": "^0.4.0", - "@types/fs-extra": "9.0.13", - "async-exit-hook": "^2.0.1", - "bluebird-lst": "^1.0.9", - "builder-util": "24.13.1", - "builder-util-runtime": "9.2.4", - "chromium-pickle-js": "^0.2.0", - "debug": "^4.3.4", - "ejs": "^3.1.8", - "electron-publish": "24.13.1", - "form-data": "^4.0.0", - "fs-extra": "^10.1.0", - "hosted-git-info": "^4.1.0", - "is-ci": "^3.0.0", - "isbinaryfile": "^5.0.0", - "js-yaml": "^4.1.0", - "lazy-val": "^1.0.5", - "minimatch": "^5.1.1", - "read-config-file": "6.3.2", - "sanitize-filename": "^1.6.3", - "semver": "^7.3.8", - "tar": "^6.1.12", - "temp-file": "^3.4.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0" }, "engines": { - "node": ">=14.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "dmg-builder": "24.13.3", - "electron-builder-squirrel-windows": "24.13.3" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/app-builder-lib/node_modules/fs-extra": { - "version": "10.1.0", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.54.0", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "@typescript-eslint/types": "8.54.0", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/app-builder-lib/node_modules/jsonfile": { - "version": "6.2.0", + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "license": "ISC" + }, + "node_modules/@vite-pwa/assets-generator": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/@vite-pwa/assets-generator/-/assets-generator-1.0.2.tgz", + "integrity": "sha512-MCbrb508JZHqe7bUibmZj/lyojdhLRnfkmyXnkrCM2zVrjTgL89U8UEfInpKTvPeTnxsw2hmyZxnhsdNR6yhwg==", "dev": true, "license": "MIT", "dependencies": { - "universalify": "^2.0.0" + "cac": "^6.7.14", + "colorette": "^2.0.20", + "consola": "^3.4.2", + "sharp": "^0.33.5", + "sharp-ico": "^0.1.5", + "unconfig": "^7.3.1" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/app-builder-lib/node_modules/semver": { - "version": "7.7.3", - "dev": true, - "license": "ISC", "bin": { - "semver": "bin/semver.js" + "pwa-assets-generator": "bin/pwa-assets-generator.mjs" }, "engines": { - "node": ">=10" + "node": ">=16.14.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/app-builder-lib/node_modules/universalify": { - "version": "2.0.1", + "node_modules/@vitest/expect": { + "version": "2.1.9", "dev": true, "license": "MIT", - "engines": { - "node": ">= 10.0.0" + "dependencies": { + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/archiver": { - "version": "5.3.2", + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", "dev": true, "license": "MIT", "dependencies": { - "archiver-utils": "^2.1.0", - "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", - "readdir-glob": "^1.1.2", - "tar-stream": "^2.2.0", - "zip-stream": "^4.1.0" + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": ">= 10" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/archiver-utils": { - "version": "2.1.0", + "node_modules/@vitest/runner": { + "version": "2.1.9", "dev": true, "license": "MIT", "dependencies": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" }, - "engines": { - "node": ">= 6" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/archiver-utils/node_modules/readable-stream": { - "version": "2.3.8", + "node_modules/@vitest/snapshot": { + "version": "2.1.9", "dev": true, "license": "MIT", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/archiver-utils/node_modules/safe-buffer": { - "version": "5.1.2", + "node_modules/@vitest/spy": { + "version": "2.1.9", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } }, - "node_modules/archiver-utils/node_modules/string_decoder": { - "version": "1.1.1", + "node_modules/@vitest/utils": { + "version": "2.1.9", "dev": true, "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.0" + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/arg": { - "version": "5.0.2", - "dev": true, + "node_modules/@vue/reactivity": { + "version": "3.5.27", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.27" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.27", "license": "MIT" }, - "node_modules/argparse": { - "version": "2.0.1", + "node_modules/@xmldom/xmldom": { + "version": "0.8.11", "dev": true, - "license": "Python-2.0" + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "node_modules/7zip-bin": { + "version": "5.2.0", + "license": "MIT" + }, + "node_modules/abbrev": { + "version": "3.0.1", "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/accepts": { + "version": "2.0.0", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", - "dev": true, + "node_modules/accepts/node_modules/mime-types": { + "version": "3.0.2", "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" + "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/assert-plus": { - "version": "1.0.0", - "dev": true, + "node_modules/accepts/node_modules/mime-types/node_modules/mime-db": { + "version": "1.54.0", "license": "MIT", - "optional": true, "engines": { - "node": ">=0.8" + "node": ">= 0.6" } }, - "node_modules/astral-regex": { - "version": "2.0.0", + "node_modules/acorn": { + "version": "8.15.0", "dev": true, "license": "MIT", - "optional": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/async": { - "version": "3.2.6", - "dev": true, - "license": "MIT" - }, - "node_modules/async-exit-hook": { - "version": "2.0.1", + "node_modules/acorn-jsx": { + "version": "5.3.2", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.12.0" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "dev": true, + "node_modules/agent-base": { + "version": "7.1.4", "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">= 14" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "dev": true, - "license": "MIT" + "node_modules/ajv": { + "version": "6.12.6", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } }, - "node_modules/at-least-node": { - "version": "1.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" + "node_modules/ajv-formats": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/atomic-sleep": { - "version": "1.0.0", + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", "license": "MIT", - "engines": { - "node": ">=8.0.0" + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/autoprefixer": { - "version": "10.4.21", - "dev": true, + "node_modules/ajv-formats/node_modules/ajv/node_modules/json-schema-traverse": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/ajv-formats/node_modules/fast-uri": { + "version": "3.1.0", "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" + "type": "github", + "url": "https://github.com/sponsors/fastify" }, { - "type": "github", - "url": "https://github.com/sponsors/ai" + "type": "opencollective", + "url": "https://opencollective.com/fastify" } ], + "license": "BSD-3-Clause" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", "license": "MIT", - "dependencies": { - "browserslist": "^4.24.4", - "caniuse-lite": "^1.0.30001702", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, "peerDependencies": { - "postcss": "^8.1.0" + "ajv": "^6.9.1" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "node_modules/ansi-regex": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-sequence-parser": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, "license": "MIT", "dependencies": { - "possible-typed-array-names": "^1.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/avvio": { - "version": "8.4.0", - "license": "MIT", + "node_modules/any-promise": { + "version": "1.3.0", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", "dependencies": { - "@fastify/error": "^3.3.0", - "fastq": "^1.17.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/babel-plugin-jsx-dom-expressions": { - "version": "0.40.3", + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", "dev": true, "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "7.18.6", - "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.20.7", - "html-entities": "2.3.3", - "parse5": "^7.1.2" + "engines": { + "node": ">=8.6" }, - "peerDependencies": { - "@babel/core": "^7.20.12" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/babel-plugin-jsx-dom-expressions/node_modules/@babel/helper-module-imports": { - "version": "7.18.6", + "node_modules/app-builder-lib": { + "version": "26.7.0", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@develar/schema-utils": "~2.6.5", + "@electron/asar": "3.4.1", + "@electron/fuses": "^1.8.0", + "@electron/get": "^3.0.0", + "@electron/notarize": "2.5.0", + "@electron/osx-sign": "1.3.3", + "@electron/rebuild": "^4.0.3", + "@electron/universal": "2.0.3", + "@malept/flatpak-bundler": "^0.4.0", + "@types/fs-extra": "9.0.13", + "async-exit-hook": "^2.0.1", + "builder-util": "26.4.1", + "builder-util-runtime": "9.5.1", + "chromium-pickle-js": "^0.2.0", + "ci-info": "4.3.1", + "debug": "^4.3.4", + "dotenv": "^16.4.5", + "dotenv-expand": "^11.0.6", + "ejs": "^3.1.8", + "electron-publish": "26.6.0", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", + "isbinaryfile": "^5.0.0", + "jiti": "^2.4.2", + "js-yaml": "^4.1.0", + "json5": "^2.2.3", + "lazy-val": "^1.0.5", + "minimatch": "^10.0.3", + "plist": "3.1.0", + "proper-lockfile": "^4.1.2", + "resedit": "^1.7.0", + "semver": "~7.7.3", + "tar": "^7.5.7", + "temp-file": "^3.4.0", + "tiny-async-pool": "1.3.0", + "which": "^5.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=14.0.0" + }, + "peerDependencies": { + "dmg-builder": "26.7.0", + "electron-builder-squirrel-windows": "26.7.0" } }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz", - "integrity": "sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==", + "node_modules/app-builder-lib/node_modules/@electron/get": { + "version": "3.1.0", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-define-polyfill-provider": "^0.6.6", - "semver": "^6.3.1" + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" } }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.0.tgz", - "integrity": "sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==", + "node_modules/app-builder-lib/node_modules/@electron/get/node_modules/fs-extra": { + "version": "8.1.0", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.6", - "core-js-compat": "^3.48.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + "engines": { + "node": ">=6 <7 || >=8" } }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.6.tgz", - "integrity": "sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==", + "node_modules/app-builder-lib/node_modules/@electron/get/node_modules/fs-extra/node_modules/jsonfile": { + "version": "4.0.0", "dev": true, "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.6" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/babel-preset-solid": { - "version": "1.9.10", + "node_modules/app-builder-lib/node_modules/@electron/get/node_modules/fs-extra/node_modules/universalify": { + "version": "0.1.2", "dev": true, "license": "MIT", - "dependencies": { - "babel-plugin-jsx-dom-expressions": "^0.40.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "solid-js": "^1.9.10" - }, - "peerDependenciesMeta": { - "solid-js": { - "optional": true - } + "engines": { + "node": ">= 4.0.0" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "license": "MIT" + "node_modules/app-builder-lib/node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/base64-js": { - "version": "1.5.1", - "funding": [ + "node_modules/app-builder-lib/node_modules/ci-info": { + "version": "4.3.1", + "dev": true, + "funding": [ { "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "url": "https://github.com/sponsors/sibiraj-s" } ], - "license": "MIT" - }, - "node_modules/baseline-browser-mapping": { - "version": "2.9.11", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", - "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, - "node_modules/bignumber.js": { - "version": "9.3.1", "license": "MIT", "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", + "node_modules/app-builder-lib/node_modules/dotenv": { + "version": "16.6.1", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://dotenvx.com" } }, - "node_modules/bl": { - "version": "4.1.0", + "node_modules/app-builder-lib/node_modules/which": { + "version": "5.0.0", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "dev": true, - "license": "MIT" - }, - "node_modules/bluebird-lst": { - "version": "1.0.9", + "node_modules/app-builder-lib/node_modules/which/node_modules/isexe": { + "version": "3.1.2", "dev": true, - "license": "MIT", - "dependencies": { - "bluebird": "^3.5.5" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" } }, - "node_modules/boolean": { - "version": "3.2.0", + "node_modules/arg": { + "version": "5.0.2", "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/brace-expansion": { - "version": "2.0.2", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } + "license": "MIT" }, - "node_modules/braces": { - "version": "3.0.3", + "node_modules/argparse": { + "version": "2.0.1", "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } + "license": "Python-2.0" }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", - "peer": true, "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/buffer": { - "version": "5.7.1", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "license": "MIT", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-equal": { - "version": "1.0.1", - "dev": true, - "license": "MIT", + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, "engines": { - "node": ">=0.4" + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/buffer-equal-constant-time": { + "node_modules/arrify": { "version": "1.0.1", - "license": "BSD-3-Clause" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/builder-util": { - "version": "24.13.1", - "dev": true, "license": "MIT", - "dependencies": { - "@types/debug": "^4.1.6", - "7zip-bin": "~5.2.0", - "app-builder-bin": "4.0.0", - "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.2.4", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "debug": "^4.3.4", - "fs-extra": "^10.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-ci": "^3.0.0", - "js-yaml": "^4.1.0", - "source-map-support": "^0.5.19", - "stat-mode": "^1.0.0", - "temp-file": "^3.4.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/builder-util-runtime": { - "version": "9.2.4", + "node_modules/assert-plus": { + "version": "1.0.0", "dev": true, "license": "MIT", - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, + "optional": true, "engines": { - "node": ">=12.0.0" + "node": ">=0.8" } }, - "node_modules/builder-util/node_modules/fs-extra": { - "version": "10.1.0", + "node_modules/assertion-error": { + "version": "2.0.1", "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, "engines": { "node": ">=12" } }, - "node_modules/builder-util/node_modules/jsonfile": { - "version": "6.2.0", + "node_modules/astral-regex": { + "version": "2.0.0", "dev": true, "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "optional": true, + "engines": { + "node": ">=8" } }, - "node_modules/builder-util/node_modules/universalify": { + "node_modules/async": { + "version": "3.2.6", + "dev": true, + "license": "MIT" + }, + "node_modules/async-exit-hook": { "version": "2.0.1", "dev": true, "license": "MIT", "engines": { - "node": ">= 10.0.0" + "node": ">=0.12.0" } }, - "node_modules/cac": { - "version": "6.7.14", + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", + "node_modules/asynckit": { + "version": "0.4.0", "dev": true, - "license": "MIT", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "dev": true, + "license": "ISC", "engines": { - "node": ">=10.6.0" + "node": ">= 4.0.0" } }, - "node_modules/cacheable-request": { - "version": "7.0.4", - "dev": true, + "node_modules/atomic-sleep": { + "version": "1.0.0", "license": "MIT", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "node_modules/autoprefixer": { + "version": "10.4.21", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" + "bin": { + "autoprefixer": "bin/autoprefixer" }, "engines": { - "node": ">= 0.4" + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" + "possible-typed-array-names": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -4444,151 +5052,154 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/camelcase": { - "version": "5.3.1", + "node_modules/avvio": { + "version": "8.4.0", "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "@fastify/error": "^3.3.0", + "fastq": "^1.17.1" } }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } + "node_modules/avvio/node_modules/@fastify/error": { + "version": "3.4.1", + "license": "MIT" }, - "node_modules/caniuse-lite": { - "version": "1.0.30001769", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", - "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", + "node_modules/babel-plugin-jsx-dom-expressions": { + "version": "0.40.3", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/ccount": { - "version": "2.0.1", "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "dependencies": { + "@babel/helper-module-imports": "7.18.6", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.20.7", + "html-entities": "2.3.3", + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.20.12" } }, - "node_modules/chalk": { - "version": "4.1.2", + "node_modules/babel-plugin-jsx-dom-expressions/node_modules/@babel/helper-module-imports": { + "version": "7.18.6", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/types": "^7.18.6" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=6.9.0" } }, - "node_modules/character-entities-html4": { - "version": "2.1.0", + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.15", + "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz", + "integrity": "sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==", + "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.6", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/chokidar": { - "version": "3.6.0", + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.14.0", + "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.0.tgz", + "integrity": "sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==", "dev": true, "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "@babel/helper-define-polyfill-provider": "^0.6.6", + "core-js-compat": "^3.48.0" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.6", + "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.6.tgz", + "integrity": "sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" + "@babel/helper-define-polyfill-provider": "^0.6.6" }, - "engines": { - "node": ">= 6" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/chownr": { - "version": "2.0.0", + "node_modules/babel-preset-solid": { + "version": "1.9.10", "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" + "license": "MIT", + "dependencies": { + "babel-plugin-jsx-dom-expressions": "^0.40.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "solid-js": "^1.9.10" + }, + "peerDependenciesMeta": { + "solid-js": { + "optional": true + } } }, - "node_modules/chromium-pickle-js": { - "version": "0.2.0", - "dev": true, + "node_modules/balanced-match": { + "version": "1.0.2", "license": "MIT" }, - "node_modules/ci-info": { - "version": "3.9.0", - "dev": true, + "node_modules/base64-js": { + "version": "1.5.1", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.19", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/bignumber.js": { + "version": "9.3.1", "license": "MIT", "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/cli-truncate": { - "version": "2.1.0", + "node_modules/binary-extensions": { + "version": "2.3.0", "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, "engines": { "node": ">=8" }, @@ -4596,1111 +5207,1162 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cliui": { - "version": "8.0.1", + "node_modules/bl": { + "version": "4.1.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "dev": true, + "node_modules/body-parser": { + "version": "2.2.2", "license": "MIT", "dependencies": { - "mimic-response": "^1.0.0" + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/clsx": { - "version": "2.1.1", + "node_modules/body-parser/node_modules/http-errors": { + "version": "2.0.1", "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, "engines": { - "node": ">=6" + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "dev": true, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.7.2", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">=12.5.0" + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/color-convert": { - "version": "2.0.1", + "node_modules/boolean": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=7.0.0" + "node": "20 || >=22" } }, - "node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" + "node_modules/brace-expansion/node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "node_modules/brace-expansion/node_modules/balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", "dev": true, "license": "MIT", "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "jackspeak": "^4.2.3" + }, + "engines": { + "node": "20 || >=22" } }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "node_modules/brace-expansion/node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "dev": true, - "license": "MIT" + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/combined-stream": { - "version": "1.0.8", + "node_modules/braces": { + "version": "3.0.3", "dev": true, "license": "MIT", "dependencies": { - "delayed-stream": "~1.0.0" + "fill-range": "^7.1.1" }, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", + "node_modules/browserslist": { + "version": "4.28.1", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/commander": { - "version": "5.1.0", + "node_modules/buffer": { + "version": "5.7.1", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT", - "engines": { - "node": ">= 6" + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true, + "node_modules/buffer-crc32": { + "version": "0.2.13", "license": "MIT", "engines": { - "node": ">=4.0.0" + "node": "*" } }, - "node_modules/compare-version": { - "version": "0.1.2", + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/builder-util": { + "version": "26.4.1", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@types/debug": "^4.1.6", + "7zip-bin": "~5.2.0", + "app-builder-bin": "5.0.0-alpha.12", + "builder-util-runtime": "9.5.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.6", + "debug": "^4.3.4", + "fs-extra": "^10.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "js-yaml": "^4.1.0", + "sanitize-filename": "^1.6.3", + "source-map-support": "^0.5.19", + "stat-mode": "^1.0.0", + "temp-file": "^3.4.0", + "tiny-async-pool": "1.3.0" } }, - "node_modules/compress-commons": { - "version": "4.1.2", + "node_modules/builder-util-runtime": { + "version": "9.5.1", "dev": true, "license": "MIT", "dependencies": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.2", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "debug": "^4.3.4", + "sax": "^1.2.4" }, "engines": { - "node": ">= 10" + "node": ">=12.0.0" } }, - "node_modules/concat-map": { - "version": "0.0.1", + "node_modules/builder-util/node_modules/app-builder-bin": { + "version": "5.0.0-alpha.12", "dev": true, "license": "MIT" }, - "node_modules/config-file-ts": { - "version": "0.2.6", + "node_modules/bytes": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", "dev": true, "license": "MIT", - "dependencies": { - "glob": "^10.3.10", - "typescript": "^5.3.3" + "engines": { + "node": ">=8" } }, - "node_modules/config-file-ts/node_modules/glob": { - "version": "10.4.5", + "node_modules/cacache": { + "version": "19.0.1", "dev": true, "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/config-file-ts/node_modules/minimatch": { - "version": "9.0.5", + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.5.6", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=18" } }, - "node_modules/config-file-ts/node_modules/minipass": { - "version": "7.1.2", + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=18" } }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "node_modules/cacheable-lookup": { + "version": "5.0.4", "dev": true, "license": "MIT", "engines": { - "node": "^14.18.0 || >=16.10.0" + "node": ">=10.6.0" } }, - "node_modules/content-disposition": { - "version": "0.5.4", + "node_modules/cacheable-request": { + "version": "7.0.4", + "dev": true, "license": "MIT", "dependencies": { - "safe-buffer": "5.2.1" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.7.2", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/core-js-compat": { - "version": "3.48.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.48.0.tgz", - "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==", + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.28.1" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/core-util-is": { + "node_modules/call-bind-apply-helpers": { "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/crc": { - "version": "3.8.0", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "buffer": "^5.1.0" - } - }, - "node_modules/crc-32": { - "version": "1.2.2", - "dev": true, - "license": "Apache-2.0", - "bin": { - "crc32": "bin/crc32.njs" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, "engines": { - "node": ">=0.8" + "node": ">= 0.4" } }, - "node_modules/crc32-stream": { - "version": "4.0.3", - "dev": true, + "node_modules/call-bound": { + "version": "1.0.4", "license": "MIT", "dependencies": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { - "node": ">= 10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/create-require": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-env": { - "version": "7.0.3", + "node_modules/callsites": { + "version": "3.1.0", "dev": true, "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" + "node": ">=6" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", + "node_modules/camelcase": { + "version": "5.3.1", "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, "engines": { - "node": ">= 8" + "node": ">=6" } }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "node_modules/camelcase-css": { + "version": "2.0.1", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/cssesc": { - "version": "3.0.0", + "node_modules/caniuse-lite": { + "version": "1.0.30001769", "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "license": "MIT" + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", + "node_modules/ccount": { + "version": "2.0.1", "license": "MIT", - "engines": { - "node": ">= 12" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/data-view-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "node_modules/chai": { + "version": "5.3.3", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18" } }, - "node_modules/data-view-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "node_modules/chalk": { + "version": "4.1.2", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/inspect-js" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/data-view-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/debug": { - "version": "4.4.3", + "node_modules/character-entities-html4": { + "version": "2.1.0", "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/decamelize": { - "version": "1.2.0", + "node_modules/character-entities-legacy": { + "version": "3.0.0", "license": "MIT", - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/decode-bmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/decode-bmp/-/decode-bmp-0.2.1.tgz", - "integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==", + "node_modules/check-error": { + "version": "2.1.3", "dev": true, "license": "MIT", - "dependencies": { - "@canvas/image-data": "^1.0.0", - "to-data-view": "^1.1.0" - }, "engines": { - "node": ">=8.6.0" + "node": ">= 16" } }, - "node_modules/decode-ico": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/decode-ico/-/decode-ico-0.4.1.tgz", - "integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==", + "node_modules/chokidar": { + "version": "3.6.0", "dev": true, "license": "MIT", "dependencies": { - "@canvas/image-data": "^1.0.0", - "decode-bmp": "^0.2.0", - "to-data-view": "^1.1.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=8.6" + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/decompress-response": { - "version": "6.0.0", + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "mimic-response": "^3.1.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 6" } }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", + "node_modules/chownr": { + "version": "3.0.0", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "node_modules/chromium-pickle-js": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ci-info": { + "version": "4.4.0", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/defer-to-connect": { - "version": "2.0.1", + "node_modules/cli-cursor": { + "version": "3.1.0", "dev": true, "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/define-data-property": { - "version": "1.1.4", + "node_modules/cli-spinners": { + "version": "2.9.2", "dev": true, "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/define-properties": { - "version": "1.2.1", + "node_modules/cli-truncate": { + "version": "2.1.0", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/defu": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "dev": true, - "license": "MIT" - }, - "node_modules/delayed-stream": { - "version": "1.0.0", + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, "engines": { - "node": ">=0.4.0" + "node": ">=8" } }, - "node_modules/depd": { - "version": "2.0.0", + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.8" - } + "optional": true }, - "node_modules/dequal": { - "version": "2.0.3", + "node_modules/cli-truncate/node_modules/string-width": { + "version": "4.2.3", + "dev": true, "license": "MIT", + "optional": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "6.0.1", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { "node": ">=8" } }, - "node_modules/detect-node": { - "version": "2.1.0", + "node_modules/clone": { + "version": "1.0.4", "dev": true, "license": "MIT", - "optional": true + "engines": { + "node": ">=0.8" + } }, - "node_modules/devlop": { - "version": "1.1.0", + "node_modules/clone-response": { + "version": "1.0.3", + "dev": true, "license": "MIT", "dependencies": { - "dequal": "^2.0.0" + "mimic-response": "^1.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/didyoumean": { - "version": "1.2.2", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/diff": { - "version": "4.0.2", + "node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "engines": { - "node": ">=0.3.1" + "node": ">=4" } }, - "node_modules/dijkstrajs": { - "version": "1.0.3", - "license": "MIT" - }, - "node_modules/dir-compare": { - "version": "3.3.0", - "dev": true, + "node_modules/clsx": { + "version": "2.1.1", "license": "MIT", - "dependencies": { - "buffer-equal": "^1.0.0", - "minimatch": "^3.0.4" + "engines": { + "node": ">=6" } }, - "node_modules/dir-compare/node_modules/brace-expansion": { - "version": "1.1.12", + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" } }, - "node_modules/dir-compare/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "color-name": "~1.1.4" }, "engines": { - "node": "*" + "node": ">=7.0.0" } }, - "node_modules/dlv": { - "version": "1.1.3", - "dev": true, + "node_modules/color-name": { + "version": "1.1.4", "license": "MIT" }, - "node_modules/dmg-builder": { - "version": "24.13.3", + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "app-builder-lib": "24.13.3", - "builder-util": "24.13.1", - "builder-util-runtime": "9.2.4", - "fs-extra": "^10.1.0", - "iconv-lite": "^0.6.2", - "js-yaml": "^4.1.0" - }, - "optionalDependencies": { - "dmg-license": "^1.0.11" + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" } }, - "node_modules/dmg-builder/node_modules/fs-extra": { - "version": "10.1.0", + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=12" + "node": ">= 0.8" } }, - "node_modules/dmg-builder/node_modules/jsonfile": { - "version": "6.2.0", - "dev": true, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/dmg-builder/node_modules/universalify": { - "version": "2.0.1", + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } + "license": "MIT" }, - "node_modules/dmg-license": { - "version": "1.0.11", + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmmirror.com/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "@types/plist": "^3.0.1", - "@types/verror": "^1.10.3", - "ajv": "^6.10.0", - "crc": "^3.8.0", - "iconv-corefoundation": "^1.1.7", - "plist": "^3.0.4", - "smart-buffer": "^4.0.2", - "verror": "^1.10.0" - }, - "bin": { - "dmg-license": "bin/dmg-license.js" - }, "engines": { - "node": ">=8" + "node": ">=4.0.0" } }, - "node_modules/dotenv": { - "version": "9.0.2", + "node_modules/compare-version": { + "version": "0.1.2", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/dotenv-expand": { - "version": "5.1.0", + "node_modules/concat-map": { + "version": "0.0.1", "dev": true, - "license": "BSD-2-Clause" + "license": "MIT" }, - "node_modules/dunder-proto": { - "version": "1.0.1", + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmmirror.com/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", "dev": true, "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, "engines": { - "node": ">= 0.4" + "node": "^14.18.0 || >=16.10.0" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "license": "MIT" - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "license": "Apache-2.0", + "node_modules/content-disposition": { + "version": "0.5.4", + "license": "MIT", "dependencies": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/ejs": { - "version": "3.1.10", + "node_modules/content-type": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/electron": { - "version": "39.0.0", + "node_modules/cookie-signature": { + "version": "1.2.2", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.48.0", + "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.48.0.tgz", + "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==", "dev": true, - "hasInstallScript": true, "license": "MIT", "dependencies": { - "@electron/get": "^2.0.0", - "@types/node": "^22.7.7", - "extract-zip": "^2.0.1" - }, - "bin": { - "electron": "cli.js" + "browserslist": "^4.28.1" }, - "engines": { - "node": ">= 12.20.55" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "node_modules/electron-builder": { - "version": "24.13.3", + "node_modules/core-util-is": { + "version": "1.0.2", "dev": true, "license": "MIT", + "optional": true + }, + "node_modules/cors": { + "version": "2.8.6", + "license": "MIT", "dependencies": { - "app-builder-lib": "24.13.3", - "builder-util": "24.13.1", - "builder-util-runtime": "9.2.4", - "chalk": "^4.1.2", - "dmg-builder": "24.13.3", - "fs-extra": "^10.1.0", - "is-ci": "^3.0.0", - "lazy-val": "^1.0.5", - "read-config-file": "6.3.2", - "simple-update-notifier": "2.0.0", - "yargs": "^17.6.2" - }, - "bin": { - "electron-builder": "cli.js", - "install-app-deps": "install-app-deps.js" + "object-assign": "^4", + "vary": "^1" }, "engines": { - "node": ">=14.0.0" + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/electron-builder-squirrel-windows": { - "version": "24.13.3", + "node_modules/crc": { + "version": "3.8.0", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "app-builder-lib": "24.13.3", - "archiver": "^5.3.1", - "builder-util": "24.13.1", - "fs-extra": "^10.1.0" + "buffer": "^5.1.0" } }, - "node_modules/electron-builder-squirrel-windows/node_modules/fs-extra": { - "version": "10.1.0", + "node_modules/cross-dirname": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/cross-env": { + "version": "7.0.3", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" }, "engines": { - "node": ">=12" + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" } }, - "node_modules/electron-builder-squirrel-windows/node_modules/jsonfile": { - "version": "6.2.0", - "dev": true, + "node_modules/cross-spawn": { + "version": "7.0.6", "license": "MIT", "dependencies": { - "universalify": "^2.0.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">= 8" } }, - "node_modules/electron-builder-squirrel-windows/node_modules/universalify": { - "version": "2.0.1", + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true, "license": "MIT", "engines": { - "node": ">= 10.0.0" + "node": ">=8" } }, - "node_modules/electron-builder/node_modules/fs-extra": { - "version": "10.1.0", + "node_modules/cssesc": { + "version": "3.0.0", "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "bin": { + "cssesc": "bin/cssesc" }, "engines": { - "node": ">=12" + "node": ">=4" } }, - "node_modules/electron-builder/node_modules/jsonfile": { - "version": "6.2.0", + "node_modules/cssstyle": { + "version": "4.6.0", "dev": true, "license": "MIT", "dependencies": { - "universalify": "^2.0.0" + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">=18" } }, - "node_modules/electron-builder/node_modules/universalify": { - "version": "2.0.1", + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.8.0", "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "license": "MIT" + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", "license": "MIT", "engines": { - "node": ">= 10.0.0" + "node": ">= 12" } }, - "node_modules/electron-publish": { - "version": "24.13.1", + "node_modules/data-urls": { + "version": "5.0.0", "dev": true, "license": "MIT", "dependencies": { - "@types/fs-extra": "^9.0.11", - "builder-util": "24.13.1", - "builder-util-runtime": "9.2.4", - "chalk": "^4.1.2", - "fs-extra": "^10.1.0", - "lazy-val": "^1.0.5", - "mime": "^2.5.2" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/electron-publish/node_modules/fs-extra": { - "version": "10.1.0", + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/electron-publish/node_modules/jsonfile": { - "version": "6.2.0", + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", "dependencies": { - "universalify": "^2.0.0" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" } }, - "node_modules/electron-publish/node_modules/universalify": { - "version": "2.0.1", + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.286", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", - "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", - "dev": true, - "license": "ISC" - }, - "node_modules/electron-vite": { - "version": "4.0.1", - "dev": true, + "node_modules/debug": { + "version": "4.4.3", "license": "MIT", "dependencies": { - "@babel/core": "^7.27.7", - "@babel/plugin-transform-arrow-functions": "^7.27.1", - "cac": "^6.7.14", - "esbuild": "^0.25.5", - "magic-string": "^0.30.17", - "picocolors": "^1.1.1" - }, - "bin": { - "electron-vite": "bin/electron-vite.js" + "ms": "^2.1.3" }, "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "@swc/core": "^1.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + "node": ">=6.0" }, "peerDependenciesMeta": { - "@swc/core": { + "supports-color": { "optional": true } } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.5", + "node_modules/decamelize": { + "version": "1.2.0", "license": "MIT", - "dependencies": { - "once": "^1.4.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/entities": { - "version": "6.0.1", + "node_modules/decimal.js": { + "version": "10.6.0", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } + "license": "MIT" }, - "node_modules/env-paths": { - "version": "2.2.1", + "node_modules/decode-bmp": { + "version": "0.2.1", + "resolved": "https://registry.npmmirror.com/decode-bmp/-/decode-bmp-0.2.1.tgz", + "integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==", "dev": true, "license": "MIT", + "dependencies": { + "@canvas/image-data": "^1.0.0", + "to-data-view": "^1.1.0" + }, "engines": { - "node": ">=6" + "node": ">=8.6.0" } }, - "node_modules/err-code": { - "version": "2.0.3", + "node_modules/decode-ico": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/decode-ico/-/decode-ico-0.4.1.tgz", + "integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@canvas/image-data": "^1.0.0", + "decode-bmp": "^0.2.0", + "to-data-view": "^1.1.0" + }, + "engines": { + "node": ">=8.6" + } }, - "node_modules/es-abstract": { - "version": "1.24.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", - "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "node_modules/decompress-response": { + "version": "6.0.0", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.2", - "arraybuffer.prototype.slice": "^1.0.4", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.3.0", - "get-proto": "^1.0.1", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.2.1", - "is-set": "^2.0.3", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.1", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.4", - "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.4", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "stop-iteration-iterator": "^1.1.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.19" + "mimic-response": "^3.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/es-define-property": { - "version": "1.0.1", + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/es-errors": { - "version": "1.3.0", + "node_modules/deep-eql": { + "version": "5.0.2", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=6" } }, - "node_modules/es-object-atoms": { - "version": "1.1.1", + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0" + "clone": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", + "node_modules/define-data-property": { + "version": "1.1.4", "dev": true, "license": "MIT", "dependencies": { + "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "node_modules/define-properties": { + "version": "1.2.1", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -5709,624 +6371,600 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es6-error": { - "version": "4.1.1", + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", "dev": true, - "license": "MIT", - "optional": true + "license": "MIT" }, - "node_modules/esbuild": { - "version": "0.25.12", + "node_modules/delayed-stream": { + "version": "1.0.0", "dev": true, - "hasInstallScript": true, "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" + "node": ">=0.4.0" } }, - "node_modules/escalade": { - "version": "3.2.0", - "dev": true, + "node_modules/depd": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "license": "MIT" + "node_modules/detect-libc": { + "version": "2.1.2", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", + "node_modules/detect-node": { + "version": "2.1.0", "dev": true, "license": "MIT", - "optional": true, - "engines": { - "node": ">=10" + "optional": true + }, + "node_modules/devlop": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "node_modules/didyoumean": { + "version": "1.2.2", "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dijkstrajs": { + "version": "1.0.3", "license": "MIT" }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/dir-compare": { + "version": "4.2.0", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5", + "p-limit": "^3.1.0 " } }, - "node_modules/extend": { - "version": "3.0.2", - "license": "MIT" + "node_modules/dir-compare/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "node_modules/extract-zip": { - "version": "2.0.1", + "node_modules/dir-compare/node_modules/minimatch": { + "version": "3.1.2", "dev": true, - "license": "BSD-2-Clause", + "license": "ISC", "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" + "node": "*" } }, - "node_modules/extsprintf": { - "version": "1.4.1", + "node_modules/dlv": { + "version": "1.1.3", "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "optional": true - }, - "node_modules/fast-content-type-parse": { - "version": "1.1.0", - "license": "MIT" - }, - "node_modules/fast-decode-uri-component": { - "version": "1.0.1", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", "license": "MIT" }, - "node_modules/fast-diff": { - "version": "1.3.0", - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.3", + "node_modules/dmg-builder": { + "version": "26.7.0", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" + "app-builder-lib": "26.7.0", + "builder-util": "26.4.1", + "fs-extra": "^10.1.0", + "iconv-lite": "^0.6.2", + "js-yaml": "^4.1.0" }, - "engines": { - "node": ">=8.6.0" + "optionalDependencies": { + "dmg-license": "^1.0.11" } }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", + "node_modules/dmg-license": { + "version": "1.0.11", "dev": true, - "license": "ISC", + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "dependencies": { - "is-glob": "^4.0.1" + "@types/plist": "^3.0.1", + "@types/verror": "^1.10.3", + "ajv": "^6.10.0", + "crc": "^3.8.0", + "iconv-corefoundation": "^1.1.7", + "plist": "^3.0.4", + "smart-buffer": "^4.0.2", + "verror": "^1.10.0" + }, + "bin": { + "dmg-license": "bin/dmg-license.js" }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true, - "license": "MIT" + "node_modules/dompurify": { + "version": "3.3.1", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } }, - "node_modules/fast-json-stringify": { - "version": "5.16.1", - "license": "MIT", - "dependencies": { - "@fastify/merge-json-schemas": "^0.1.0", - "ajv": "^8.10.0", - "ajv-formats": "^3.0.1", - "fast-deep-equal": "^3.1.3", - "fast-uri": "^2.1.0", - "json-schema-ref-resolver": "^1.0.1", - "rfdc": "^1.2.0" + "node_modules/dotenv": { + "version": "9.0.2", + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" } }, - "node_modules/fast-json-stringify/node_modules/ajv": { - "version": "8.17.1", - "license": "MIT", + "node_modules/dotenv-expand": { + "version": "11.0.7", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://dotenvx.com" } }, - "node_modules/fast-json-stringify/node_modules/ajv-formats": { - "version": "3.0.1", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" + "node_modules/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "funding": { + "url": "https://dotenvx.com" } }, - "node_modules/fast-json-stringify/node_modules/ajv/node_modules/fast-uri": { - "version": "3.1.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/fast-querystring": { - "version": "1.1.2", + "node_modules/dunder-proto": { + "version": "1.0.1", "license": "MIT", "dependencies": { - "fast-decode-uri-component": "^1.0.1" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/fast-uri": { - "version": "2.4.0", + "node_modules/eastasianwidth": { + "version": "0.2.0", "license": "MIT" }, - "node_modules/fastify": { - "version": "4.29.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "MIT", + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "license": "Apache-2.0", "dependencies": { - "@fastify/ajv-compiler": "^3.5.0", - "@fastify/error": "^3.4.0", - "@fastify/fast-json-stringify-compiler": "^4.3.0", - "abstract-logging": "^2.0.1", - "avvio": "^8.3.0", - "fast-content-type-parse": "^1.1.0", - "fast-json-stringify": "^5.8.0", - "find-my-way": "^8.0.0", - "light-my-request": "^5.11.0", - "pino": "^9.0.0", - "process-warning": "^3.0.0", - "proxy-addr": "^2.0.7", - "rfdc": "^1.3.0", - "secure-json-parse": "^2.7.0", - "semver": "^7.5.4", - "toad-cache": "^3.3.0" + "safe-buffer": "^5.0.1" } }, - "node_modules/fastify-plugin": { - "version": "4.5.1", + "node_modules/ee-first": { + "version": "1.1.1", "license": "MIT" }, - "node_modules/fastify/node_modules/semver": { - "version": "7.7.3", - "license": "ISC", + "node_modules/ejs": { + "version": "3.1.10", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, "bin": { - "semver": "bin/semver.js" + "ejs": "bin/cli.js" }, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/fastq": { - "version": "1.19.1", - "license": "ISC", + "node_modules/electron": { + "version": "39.0.0", + "dev": true, + "hasInstallScript": true, + "license": "MIT", "dependencies": { - "reusify": "^1.0.4" + "@electron/get": "^2.0.0", + "@types/node": "^22.7.7", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", + "node_modules/electron-builder": { + "version": "26.7.0", + "dev": true, "license": "MIT", "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" + "app-builder-lib": "26.7.0", + "builder-util": "26.4.1", + "builder-util-runtime": "9.5.1", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "dmg-builder": "26.7.0", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "simple-update-notifier": "2.0.0", + "yargs": "^17.6.2" + }, + "bin": { + "electron-builder": "cli.js", + "install-app-deps": "install-app-deps.js" }, "engines": { - "node": "^12.20 || >= 14.13" + "node": ">=14.0.0" } }, - "node_modules/filelist": { - "version": "1.0.4", + "node_modules/electron-builder-squirrel-windows": { + "version": "26.7.0", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "peer": true, "dependencies": { - "minimatch": "^5.0.1" + "app-builder-lib": "26.7.0", + "builder-util": "26.4.1", + "electron-winstaller": "5.4.0" } }, - "node_modules/fill-range": { - "version": "7.1.1", + "node_modules/electron-builder/node_modules/yargs": { + "version": "17.7.2", "dev": true, "license": "MIT", "dependencies": { - "to-regex-range": "^5.0.1" + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/find-my-way": { - "version": "8.2.2", - "license": "MIT", + "node_modules/electron-builder/node_modules/yargs/node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-querystring": "^1.0.0", - "safe-regex2": "^3.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=14" + "node": ">=12" } }, - "node_modules/find-up": { - "version": "4.1.0", + "node_modules/electron-builder/node_modules/yargs/node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "node_modules/electron-builder/node_modules/yargs/node_modules/cliui/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/foreground-child": { - "version": "3.3.1", - "license": "ISC", + "node_modules/electron-builder/node_modules/yargs/node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=14" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/form-data": { - "version": "4.0.4", + "node_modules/electron-builder/node_modules/yargs/node_modules/y18n": { + "version": "5.0.8", "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, + "license": "ISC", "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "license": "MIT", - "dependencies": { - "fetch-blob": "^3.1.2" - }, + "node_modules/electron-builder/node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", "engines": { - "node": ">=12.20.0" + "node": ">=12" } }, - "node_modules/forwarded": { - "version": "0.2.0", + "node_modules/electron-publish": { + "version": "26.6.0", + "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.6" + "dependencies": { + "@types/fs-extra": "^9.0.11", + "builder-util": "26.4.1", + "builder-util-runtime": "9.5.1", + "chalk": "^4.1.2", + "form-data": "^4.0.5", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "mime": "^2.5.2" } }, - "node_modules/fraction.js": { - "version": "4.3.7", + "node_modules/electron-publish/node_modules/mime": { + "version": "2.6.0", "dev": true, "license": "MIT", - "engines": { - "node": "*" + "bin": { + "mime": "cli.js" }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" + "engines": { + "node": ">=4.0.0" } }, - "node_modules/fs-constants": { - "version": "1.0.0", + "node_modules/electron-to-chromium": { + "version": "1.5.286", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/fs-extra": { - "version": "8.1.0", + "node_modules/electron-vite": { + "version": "4.0.1", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "@babel/core": "^7.27.7", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "cac": "^6.7.14", + "esbuild": "^0.25.5", + "magic-string": "^0.30.17", + "picocolors": "^1.1.1" + }, + "bin": { + "electron-vite": "bin/electron-vite.js" }, "engines": { - "node": ">=6 <7 || >=8" + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@swc/core": "^1.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + } } }, - "node_modules/fs-minipass": { - "version": "2.1.0", + "node_modules/electron-winstaller": { + "version": "5.4.0", "dev": true, - "license": "ISC", + "hasInstallScript": true, + "license": "MIT", + "peer": true, "dependencies": { - "minipass": "^3.0.0" + "@electron/asar": "^3.2.1", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "lodash": "^4.17.21", + "temp": "^0.9.0" }, "engines": { - "node": ">= 8" + "node": ">=8.0.0" + }, + "optionalDependencies": { + "@electron/windows-sign": "^1.1.2" } }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", + "node_modules/electron-winstaller/node_modules/fs-extra": { + "version": "7.0.1", "dev": true, - "license": "ISC", + "license": "MIT", + "peer": true, "dependencies": { - "yallist": "^4.0.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=8" + "node": ">=6 <7 || >=8" } }, - "node_modules/fs-minipass/node_modules/yallist": { + "node_modules/electron-winstaller/node_modules/fs-extra/node_modules/jsonfile": { "version": "4.0.0", "dev": true, - "license": "ISC" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "dev": true, - "license": "ISC" + "license": "MIT", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } }, - "node_modules/fsevents": { - "version": "2.3.3", + "node_modules/electron-winstaller/node_modules/fs-extra/node_modules/universalify": { + "version": "0.1.2", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "peer": true, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 4.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", + "node_modules/electron/node_modules/@types/node": { + "version": "22.19.9", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "undici-types": "~6.21.0" } }, - "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "node_modules/electron/node_modules/@types/node/node_modules/undici-types": { + "version": "6.21.0", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.8" } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "node_modules/encoding": { + "version": "0.1.13", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" } }, - "node_modules/gaxios": { - "version": "7.1.3", - "license": "Apache-2.0", - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2", - "rimraf": "^5.0.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/gaxios/node_modules/agent-base": { - "version": "7.1.4", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/gaxios/node_modules/https-proxy-agent": { - "version": "7.0.6", + "node_modules/end-of-stream": { + "version": "1.4.5", "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" + "once": "^1.4.0" } }, - "node_modules/gcp-metadata": { - "version": "8.1.2", - "license": "Apache-2.0", - "dependencies": { - "gaxios": "^7.0.0", - "google-logging-utils": "^1.0.0", - "json-bigint": "^1.0.0" - }, + "node_modules/entities": { + "version": "6.0.1", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=18" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/generator-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", - "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "node_modules/env-paths": { + "version": "2.2.1", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=6" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", + "node_modules/err-code": { + "version": "2.0.3", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } + "license": "MIT" }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" + "node_modules/error-ex": { + "version": "1.3.4", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", + "node_modules/es-abstract": { + "version": "1.24.1", + "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" @@ -6335,49 +6973,59 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "dev": true, - "license": "ISC" - }, - "node_modules/get-proto": { + "node_modules/es-define-property": { "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", "license": "MIT", "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" + "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" } }, - "node_modules/get-stream": { - "version": "5.2.0", + "node_modules/es-set-tostringtag": { + "version": "2.1.0", "dev": true, "license": "MIT", "dependencies": { - "pump": "^3.0.0" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -6386,19 +7034,67 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.13.0", + "node_modules/es6-error": { + "version": "4.1.1", "dev": true, "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" + "optional": true + }, + "node_modules/esbuild": { + "version": "0.25.12", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" } }, - "node_modules/github-markdown-css": { - "version": "5.8.1", + "node_modules/escalade": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -6407,642 +7103,714 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/glob": { - "version": "7.2.3", + "node_modules/eslint": { + "version": "9.39.2", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": "*" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" + "url": "https://eslint.org/donate" }, - "engines": { - "node": ">=10.13.0" + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.12", + "node_modules/eslint-plugin-solid": { + "version": "0.14.5", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@typescript-eslint/utils": "^7.13.1 || ^8.0.0", + "estraverse": "^5.3.0", + "is-html": "^2.0.0", + "kebab-case": "^1.0.2", + "known-css-properties": "^0.30.0", + "style-to-object": "^1.0.6" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "typescript": ">=4.8.4" } }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", + "node_modules/eslint-scope": { + "version": "8.4.0", "dev": true, - "license": "ISC", + "license": "BSD-2-Clause", "dependencies": { - "brace-expansion": "^1.1.7" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": "*" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/global-agent": { - "version": "3.0.0", + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">=10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/global-agent/node_modules/semver": { - "version": "7.7.3", + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", "dev": true, - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/globalthis": { - "version": "1.0.4", + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", "dev": true, "license": "MIT", "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/google-auth-library": { - "version": "10.5.0", - "license": "Apache-2.0", + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^7.0.0", - "gcp-metadata": "^8.0.0", - "google-logging-utils": "^1.0.0", - "gtoken": "^8.0.0", - "jws": "^4.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=18" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/google-logging-utils": { - "version": "1.1.3", - "license": "Apache-2.0", + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">=14" + "node": "*" } }, - "node_modules/gopd": { - "version": "1.2.0", + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", "dev": true, "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/got": { - "version": "11.8.6", + "node_modules/espree": { + "version": "10.4.0", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": ">=10.19.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" + "url": "https://opencollective.com/eslint" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", + "node_modules/esquery": { + "version": "1.7.0", "dev": true, - "license": "ISC" - }, - "node_modules/gtoken": { - "version": "8.0.0", - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "gaxios": "^7.0.0", - "jws": "^4.0.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=18" + "node": ">=0.10" } }, - "node_modules/has-bigints": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "node_modules/esrecurse": { + "version": "4.3.0", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=4.0" } }, - "node_modules/has-flag": { - "version": "4.0.0", + "node_modules/estraverse": { + "version": "5.3.0", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", + "node_modules/estree-walker": { + "version": "3.0.3", "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/estree": "^1.0.0" } }, - "node_modules/has-proto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "node_modules/esutils": { + "version": "2.0.3", "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", "license": "MIT", "dependencies": { - "dunder-proto": "^1.0.0" + "eventsource-parser": "^3.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18.0.0" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "dev": true, + "node_modules/eventsource-parser": { + "version": "3.0.6", "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18.0.0" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", + "node_modules/expect-type": { + "version": "1.3.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express": { + "version": "5.2.1", "license": "MIT", "dependencies": { - "has-symbols": "^1.0.3" + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" }, "engines": { - "node": ">= 0.4" + "node": ">= 18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/hasown": { - "version": "2.0.2", - "dev": true, + "node_modules/express-rate-limit": { + "version": "8.2.1", "license": "MIT", "dependencies": { - "function-bind": "^1.1.2" + "ip-address": "10.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" } }, - "node_modules/hast-util-to-html": { - "version": "9.0.5", + "node_modules/express/node_modules/content-disposition": { + "version": "1.0.1", "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" + "engines": { + "node": ">=18" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://opencollective.com/express" } }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", + "node_modules/express/node_modules/mime-types": { + "version": "3.0.2", "license": "MIT", "dependencies": { - "@types/hast": "^3.0.0" + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://opencollective.com/express" } }, - "node_modules/highlight.js": { - "version": "11.11.1", - "license": "BSD-3-Clause", + "node_modules/express/node_modules/mime-types/node_modules/mime-db": { + "version": "1.54.0", + "license": "MIT", "engines": { - "node": ">=12.0.0" + "node": ">= 0.6" } }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } + "node_modules/extend": { + "version": "3.0.2", + "license": "MIT" }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "6.0.0", + "node_modules/extract-zip": { + "version": "2.0.1", "dev": true, - "license": "ISC", + "license": "BSD-2-Clause", "dependencies": { - "yallist": "^4.0.0" + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" }, "engines": { - "node": ">=10" + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/hosted-git-info/node_modules/yallist": { - "version": "4.0.0", + "node_modules/extsprintf": { + "version": "1.4.1", "dev": true, - "license": "ISC" + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "optional": true }, - "node_modules/html-entities": { - "version": "2.3.3", - "dev": true, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", "license": "MIT" }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" }, - "node_modules/http-cache-semantics": { - "version": "4.2.0", - "dev": true, - "license": "BSD-2-Clause" + "node_modules/fast-diff": { + "version": "1.3.0", + "license": "Apache-2.0" }, - "node_modules/http-errors": { - "version": "2.0.0", + "node_modules/fast-glob": { + "version": "3.3.3", + "dev": true, "license": "MIT", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" }, "engines": { - "node": ">= 0.8" + "node": ">=8.6.0" } }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "dev": true, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/fast-json-stringify": { + "version": "5.16.1", "license": "MIT", "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" + "@fastify/merge-json-schemas": "^0.1.0", + "ajv": "^8.10.0", + "ajv-formats": "^3.0.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^2.1.0", + "json-schema-ref-resolver": "^1.0.1", + "rfdc": "^1.2.0" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "dev": true, + "node_modules/fast-json-stringify/node_modules/ajv": { + "version": "8.17.1", "license": "MIT", "dependencies": { - "agent-base": "6", - "debug": "4" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": ">= 6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ico-endec": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ico-endec/-/ico-endec-0.1.6.tgz", - "integrity": "sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==", - "dev": true, - "license": "MPL-2.0" - }, - "node_modules/iconv-corefoundation": { - "version": "1.1.7", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" + "node_modules/fast-json-stringify/node_modules/ajv/node_modules/fast-uri": { + "version": "3.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } ], - "dependencies": { - "cli-truncate": "^2.1.0", - "node-addon-api": "^1.6.3" - }, - "engines": { - "node": "^8.11.2 || >=10" - } + "license": "BSD-3-Clause" }, - "node_modules/iconv-lite": { - "version": "0.6.3", + "node_modules/fast-json-stringify/node_modules/ajv/node_modules/json-schema-traverse": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/fast-json-stringify/node_modules/fast-uri": { + "version": "2.4.0", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", "dev": true, + "license": "MIT" + }, + "node_modules/fast-querystring": { + "version": "1.1.2", "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" + "fast-decode-uri-component": "^1.0.1" } }, - "node_modules/idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/ieee754": { - "version": "1.2.1", - "dev": true, + "node_modules/fast-uri": { + "version": "3.1.0", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "url": "https://github.com/sponsors/fastify" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "opencollective", + "url": "https://opencollective.com/fastify" } ], "license": "BSD-3-Clause" }, - "node_modules/inflight": { - "version": "1.0.6", - "dev": true, - "license": "ISC", + "node_modules/fastify": { + "version": "4.29.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "@fastify/ajv-compiler": "^3.5.0", + "@fastify/error": "^3.4.0", + "@fastify/fast-json-stringify-compiler": "^4.3.0", + "abstract-logging": "^2.0.1", + "avvio": "^8.3.0", + "fast-content-type-parse": "^1.1.0", + "fast-json-stringify": "^5.8.0", + "find-my-way": "^8.0.0", + "light-my-request": "^5.11.0", + "pino": "^9.0.0", + "process-warning": "^3.0.0", + "proxy-addr": "^2.0.7", + "rfdc": "^1.3.0", + "secure-json-parse": "^2.7.0", + "semver": "^7.5.4", + "toad-cache": "^3.3.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "license": "ISC" + "node_modules/fastify/node_modules/@fastify/error": { + "version": "3.4.1", + "license": "MIT" }, - "node_modules/internal-slot": { + "node_modules/fastify/node_modules/fast-content-type-parse": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } + "license": "MIT" }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "license": "MIT", + "node_modules/fastify/node_modules/semver": { + "version": "7.7.3", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">= 0.10" + "node": ">=10" } }, - "node_modules/is-array-buffer": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", - "dev": true, + "node_modules/fastq": { + "version": "1.20.1", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" + "pend": "~1.2.0" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^12.20 || >= 14.13" } }, - "node_modules/is-arrayish": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", - "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-async-function": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "node_modules/file-entry-cache": { + "version": "8.0.0", "dev": true, "license": "MIT", "dependencies": { - "async-function": "^1.0.0", - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" + "flat-cache": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=16.0.0" } }, - "node_modules/is-bigint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "node_modules/filelist": { + "version": "1.0.4", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "has-bigints": "^1.0.2" + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", + "node_modules/filelist/node_modules/minimatch/node_modules/brace-expansion": { + "version": "2.0.2", "dev": true, "license": "MIT", "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" + "balanced-match": "^1.0.0" } }, - "node_modules/is-boolean-object": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "node_modules/fill-range": { + "version": "7.1.1", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, + "node_modules/finalhandler": { + "version": "2.1.1", "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, "engines": { - "node": ">= 0.4" + "node": ">= 18.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/is-ci": { - "version": "3.0.1", - "dev": true, + "node_modules/find-my-way": { + "version": "8.2.2", "license": "MIT", "dependencies": { - "ci-info": "^3.2.0" + "fast-deep-equal": "^3.1.3", + "fast-querystring": "^1.0.0", + "safe-regex2": "^3.1.0" }, - "bin": { - "is-ci": "bin.js" + "engines": { + "node": ">=14" } }, - "node_modules/is-core-module": { - "version": "2.16.1", - "dev": true, + "node_modules/find-up": { + "version": "5.0.0", "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-data-view": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "node_modules/flat-cache": { + "version": "4.0.1", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=16" } }, - "node_modules/is-date-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "node_modules/flatted": { + "version": "3.3.3", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -7051,186 +7819,151 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "dev": true, - "license": "MIT", + "node_modules/foreground-child": { + "version": "3.3.1", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "node_modules/form-data": { + "version": "4.0.5", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 6" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/is-generator-function": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", - "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.4", - "generator-function": "^2.0.0", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" + "mime-db": "1.52.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "dev": true, + "node_modules/formdata-polyfill": { + "version": "4.0.10", "license": "MIT", "dependencies": { - "is-extglob": "^2.1.1" + "fetch-blob": "^3.1.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=12.20.0" } }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, + "node_modules/forwarded": { + "version": "0.2.0", "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "node_modules/fraction.js": { + "version": "4.3.7", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "patreon", + "url": "https://github.com/sponsors/rawify" } }, - "node_modules/is-number": { - "version": "7.0.0", - "dev": true, + "node_modules/fresh": { + "version": "2.0.0", "license": "MIT", "engines": { - "node": ">=0.12.0" + "node": ">= 0.8" } }, - "node_modules/is-number-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "node_modules/fs-extra": { + "version": "10.1.0", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "node_modules/fs-minipass": { + "version": "3.0.3", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "minipass": "^7.0.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/is-regexp": { + "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", "dev": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.10.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, + "node_modules/function-bind": { + "version": "1.1.2", "license": "MIT", - "engines": { - "node": ">= 0.4" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmmirror.com/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -7239,62 +7972,80 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", - "dev": true, - "license": "MIT", + "node_modules/gaxios": { + "version": "7.1.3", + "license": "Apache-2.0", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=18" + } + }, + "node_modules/gcp-metadata": { + "version": "8.1.2", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", + "json-bigint": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=18" } }, - "node_modules/is-symbol": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", "dev": true, "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" - }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", "dev": true, "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.16" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -7303,43 +8054,47 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", "dev": true, + "license": "ISC" + }, + "node_modules/get-proto": { + "version": "1.0.1", "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-weakref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "node_modules/get-stream": { + "version": "5.2.0", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3" + "pump": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-weakset": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", + "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" }, "engines": { @@ -7349,768 +8104,856 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-what": { - "version": "4.1.16", + "node_modules/get-tsconfig": { + "version": "4.13.6", "dev": true, "license": "MIT", - "engines": { - "node": ">=12.13" + "dependencies": { + "resolve-pkg-maps": "^1.0.0" }, "funding": { - "url": "https://github.com/sponsors/mesqueeb" + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/isarray": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/isbinaryfile": { - "version": "5.0.6", - "dev": true, + "node_modules/github-markdown-css": { + "version": "5.9.0", "license": "MIT", "engines": { - "node": ">= 18.0.0" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/gjtorikian/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/isexe": { - "version": "2.0.0", - "license": "ISC" - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "license": "BlueOak-1.0.0", + "node_modules/glob": { + "version": "10.5.0", + "license": "ISC", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jake": { - "version": "10.9.4", + "node_modules/glob-parent": { + "version": "6.0.2", "dev": true, - "license": "Apache-2.0", + "license": "ISC", "dependencies": { - "async": "^3.2.6", - "filelist": "^1.0.4", - "picocolors": "^1.1.1" - }, - "bin": { - "jake": "bin/cli.js" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=10" - } - }, - "node_modules/jiti": { - "version": "1.21.7", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "jiti": "bin/jiti.js" + "node": ">=10.13.0" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "dev": true, - "license": "MIT", + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "license": "ISC", "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=6" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/json-bigint": { - "version": "1.0.0", + "node_modules/glob/node_modules/minimatch/node_modules/brace-expansion": { + "version": "2.0.2", "license": "MIT", "dependencies": { - "bignumber.js": "^9.0.0" + "balanced-match": "^1.0.0" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "node_modules/global-agent": { + "version": "3.0.0", "dev": true, - "license": "(AFL-2.1 OR BSD-3-Clause)" - }, - "node_modules/json-schema-ref-resolver": { - "version": "1.0.1", - "license": "MIT", + "license": "BSD-3-Clause", + "optional": true, "dependencies": { - "fast-deep-equal": "^3.1.3" + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" } }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", + "node_modules/global-agent/node_modules/semver": { + "version": "7.7.3", "dev": true, "license": "ISC", - "optional": true - }, - "node_modules/json5": { - "version": "2.2.3", - "dev": true, - "license": "MIT", + "optional": true, "bin": { - "json5": "lib/cli.js" + "semver": "bin/semver.js" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/jsonfile": { - "version": "4.0.0", + "node_modules/globals": { + "version": "17.3.0", "dev": true, "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "node_modules/globalthis": { + "version": "1.0.4", "dev": true, "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jwa": { - "version": "2.0.1", - "license": "MIT", + "node_modules/google-auth-library": { + "version": "10.5.0", + "license": "Apache-2.0", "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^7.0.0", + "gcp-metadata": "^8.0.0", + "google-logging-utils": "^1.0.0", + "gtoken": "^8.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/jws": { - "version": "4.0.0", + "node_modules/google-logging-utils": { + "version": "1.1.3", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/gopd": { + "version": "1.2.0", "license": "MIT", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/keyv": { - "version": "4.5.4", + "node_modules/got": { + "version": "11.8.6", "dev": true, "license": "MIT", "dependencies": { - "json-buffer": "3.0.1" + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" } }, - "node_modules/lazy-val": { - "version": "1.0.5", + "node_modules/graceful-fs": { + "version": "4.2.11", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/lazystream": { - "version": "1.0.1", - "dev": true, + "node_modules/gtoken": { + "version": "8.0.0", "license": "MIT", "dependencies": { - "readable-stream": "^2.0.5" + "gaxios": "^7.0.0", + "jws": "^4.0.0" }, "engines": { - "node": ">= 0.6.3" + "node": ">=18" } }, - "node_modules/lazystream/node_modules/readable-stream": { - "version": "2.3.8", - "dev": true, + "node_modules/has-ansi": { + "version": "2.0.0", "license": "MIT", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/lazystream/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/lazystream/node_modules/string_decoder": { - "version": "1.1.1", + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "node_modules/has-flag": { + "version": "4.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/light-my-request": { - "version": "5.14.0", - "license": "BSD-3-Clause", + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "dev": true, + "license": "MIT", "dependencies": { - "cookie": "^0.7.0", - "process-warning": "^3.0.0", - "set-cookie-parser": "^2.4.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lilconfig": { - "version": "3.1.3", + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "license": "MIT", "engines": { - "node": ">=14" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/antonk52" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", + "node_modules/has-tostringtag": { + "version": "1.0.2", "dev": true, - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "5.0.0", "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "has-symbols": "^1.0.3" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lodash": { - "version": "4.17.21", - "dev": true, - "license": "MIT" + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true, - "license": "MIT" + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "dev": true, - "license": "MIT" + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/highlight.js": { + "version": "11.11.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/hono": { + "version": "4.11.8", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } }, - "node_modules/lodash.difference": { - "version": "4.5.0", + "node_modules/hosted-git-info": { + "version": "4.1.0", "dev": true, - "license": "MIT" + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/lodash.flatten": { - "version": "4.4.0", + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", "dev": true, - "license": "MIT" + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", + "node_modules/hosted-git-info/node_modules/lru-cache/node_modules/yallist": { + "version": "4.0.0", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/lodash.union": { - "version": "4.6.0", + "node_modules/html-entities": { + "version": "2.3.3", "dev": true, "license": "MIT" }, - "node_modules/lowercase-keys": { - "version": "2.0.0", + "node_modules/html-tags": { + "version": "3.3.1", "dev": true, "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lowlight": { - "version": "3.3.0", + "node_modules/html-void-elements": { + "version": "3.0.0", "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "devlop": "^1.0.0", - "highlight.js": "~11.11.0" - }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/lru-cache": { - "version": "5.1.1", + "node_modules/http-cache-semantics": { + "version": "4.2.0", "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lucide-solid": { - "version": "0.300.0", - "license": "ISC", - "peerDependencies": { - "solid-js": "^1.4.7" - } + "license": "BSD-2-Clause" }, - "node_modules/magic-string": { - "version": "0.30.21", - "dev": true, + "node_modules/http-errors": { + "version": "2.0.0", "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" } }, - "node_modules/make-error": { - "version": "1.3.6", - "dev": true, - "license": "ISC" - }, - "node_modules/marked": { - "version": "12.0.2", + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, "engines": { - "node": ">= 18" + "node": ">= 0.8" } }, - "node_modules/matcher": { - "version": "3.0.0", + "node_modules/http-proxy-agent": { + "version": "7.0.2", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "escape-string-regexp": "^4.0.0" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=10" + "node": ">= 14" } }, - "node_modules/math-intrinsics": { - "version": "1.1.0", + "node_modules/http2-wrapper": { + "version": "1.0.3", "dev": true, "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=10.19.0" } }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.0", + "node_modules/https-proxy-agent": { + "version": "7.0.6", "license": "MIT", "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" + "agent-base": "^7.1.2", + "debug": "4" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">= 14" } }, - "node_modules/merge-anything": { - "version": "5.1.7", + "node_modules/ico-endec": { + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/ico-endec/-/ico-endec-0.1.6.tgz", + "integrity": "sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==", + "dev": true, + "license": "MPL-2.0" + }, + "node_modules/iconv-corefoundation": { + "version": "1.1.7", "dev": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "dependencies": { - "is-what": "^4.1.8" + "cli-truncate": "^2.1.0", + "node-addon-api": "^1.6.3" }, "engines": { - "node": ">=12.13" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" + "node": "^8.11.2 || >=10" } }, - "node_modules/merge2": { - "version": "1.4.1", + "node_modules/iconv-lite": { + "version": "0.6.3", "dev": true, "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, "engines": { - "node": ">= 8" + "node": ">=0.10.0" } }, - "node_modules/micromark-util-character": { - "version": "2.1.1", + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "dev": true, "funding": [ { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" + "type": "github", + "url": "https://github.com/sponsors/feross" }, { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "dev": true, "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "engines": { + "node": ">= 4" } }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" + "node_modules/import-fresh": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/inline-style-parser": { + "version": "0.2.7", + "dev": true, "license": "MIT" }, - "node_modules/micromatch": { - "version": "4.0.8", + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "license": "MIT", "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { - "node": ">=8.6" + "node": ">= 0.4" } }, - "node_modules/mime": { - "version": "2.6.0", - "dev": true, + "node_modules/ip-address": { + "version": "10.0.1", "license": "MIT", - "bin": { - "mime": "cli.js" - }, "engines": { - "node": ">=4.0.0" + "node": ">= 12" } }, - "node_modules/mime-db": { - "version": "1.52.0", + "node_modules/ipaddr.js": { + "version": "1.9.1", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mime-types": { - "version": "2.1.35", + "node_modules/is-arrayish": { + "version": "0.2.1", + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mimic-response": { - "version": "1.0.1", + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minimatch": { - "version": "5.1.6", + "node_modules/is-binary-path": { + "version": "2.1.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" + "binary-extensions": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/minimist": { - "version": "1.2.8", + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "5.0.0", - "license": "ISC", + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minizlib": { - "version": "2.1.2", + "node_modules/is-core-module": { + "version": "2.16.1", "dev": true, "license": "MIT", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "hasown": "^2.0.2" }, "engines": { - "node": ">= 8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "yallist": "^4.0.0" + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/mkdirp": { - "version": "1.0.4", + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">=10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mnemonist": { - "version": "0.39.6", + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, "license": "MIT", - "dependencies": { - "obliterator": "^2.0.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ms": { - "version": "2.1.3", - "license": "MIT" - }, - "node_modules/mz": { - "version": "2.7.0", + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "dev": true, "license": "MIT", "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/nanoid": { - "version": "3.3.11", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=8" } }, - "node_modules/node-addon-api": { - "version": "1.7.2", + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", "dev": true, "license": "MIT", - "optional": true - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "license": "MIT", "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/node-releases": { - "version": "2.0.27", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", + "node_modules/is-glob": { + "version": "4.0.3", "dev": true, "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/normalize-range": { - "version": "0.1.2", + "node_modules/is-html": { + "version": "2.0.0", "dev": true, "license": "MIT", + "dependencies": { + "html-tags": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/normalize-url": { - "version": "6.1.0", + "node_modules/is-interactive": { + "version": "1.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/object-assign": { - "version": "4.1.1", + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-hash": { - "version": "3.0.0", + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } + "license": "MIT" }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "license": "MIT", "engines": { @@ -8120,27 +8963,23 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-keys": { - "version": "1.1.1", + "node_modules/is-number": { + "version": "7.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=0.12.0" } }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8149,47 +8988,36 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/obliterator": { - "version": "2.0.5", - "license": "MIT" - }, - "node_modules/on-exit-leak-free": { - "version": "2.1.2", + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, "license": "MIT", "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "license": "ISC", - "dependencies": { - "wrappy": "1" + "node": ">=0.10.0" } }, - "node_modules/oniguruma-parser": { - "version": "0.12.1", + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "dev": true, "license": "MIT" }, - "node_modules/oniguruma-to-es": { - "version": "4.3.3", - "license": "MIT", - "dependencies": { - "oniguruma-parser": "^0.12.1", - "regex": "^6.0.1", - "regex-recursion": "^6.0.2" - } + "node_modules/is-promise": { + "version": "4.0.0", + "license": "MIT" }, - "node_modules/own-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.6", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -8198,1363 +9026,1249 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/p-cancelable": { - "version": "2.1.1", + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/p-limit": { - "version": "2.3.0", + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/p-locate": { - "version": "4.1.0", + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "call-bound": "^1.0.3" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/p-try": { - "version": "2.2.0", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "license": "BlueOak-1.0.0" - }, - "node_modules/parse5": { - "version": "7.3.0", + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "license": "MIT", "dependencies": { - "entities": "^6.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/path-exists": { - "version": "4.0.0", + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "license": "MIT", - "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/path-parse": { - "version": "1.0.7", + "node_modules/is-unicode-supported": { + "version": "0.1.0", "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.18" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "license": "ISC" - }, - "node_modules/pend": { - "version": "1.2.0", + "node_modules/is-utf8": { + "version": "0.2.1", "license": "MIT" }, - "node_modules/picocolors": { - "version": "1.1.1", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/pify": { - "version": "2.3.0", + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/pino": { - "version": "9.14.0", + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, "license": "MIT", "dependencies": { - "@pinojs/redact": "^0.4.0", - "atomic-sleep": "^1.0.0", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^2.0.0", - "pino-std-serializers": "^7.0.0", - "process-warning": "^5.0.0", - "quick-format-unescaped": "^4.0.3", - "real-require": "^0.2.0", - "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^4.0.1", - "thread-stream": "^3.0.0" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, - "bin": { - "pino": "bin.js" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/pino-abstract-transport": { - "version": "2.0.0", + "node_modules/is-what": { + "version": "4.1.16", + "dev": true, "license": "MIT", - "dependencies": { - "split2": "^4.0.0" + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/pino-std-serializers": { - "version": "7.0.0", - "license": "MIT" - }, - "node_modules/pino/node_modules/process-warning": { - "version": "5.0.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, "license": "MIT" }, - "node_modules/pirates": { - "version": "4.0.7", + "node_modules/isbinaryfile": { + "version": "5.0.7", "dev": true, "license": "MIT", "engines": { - "node": ">= 6" + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" } }, - "node_modules/plist": { - "version": "3.1.0", + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.4", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@xmldom/xmldom": "^0.8.8", - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" }, "engines": { - "node": ">=10.4.0" + "node": ">=10" } }, - "node_modules/png2icons": { - "version": "2.0.1", + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmmirror.com/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "dev": true, "license": "MIT", "bin": { - "png2icons": "png2icons-cli.js" + "jiti": "lib/jiti-cli.mjs" } }, - "node_modules/pngjs": { - "version": "7.0.0", - "dev": true, + "node_modules/jose": { + "version": "6.1.3", "license": "MIT", - "engines": { - "node": ">=14.19.0" + "funding": { + "url": "https://github.com/sponsors/panva" } }, - "node_modules/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "node_modules/js-tokens": { + "version": "4.0.0", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } + "license": "MIT" }, - "node_modules/postcss": { - "version": "8.5.6", + "node_modules/js-yaml": { + "version": "4.1.1", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", - "peer": true, "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "argparse": "^2.0.1" }, - "engines": { - "node": "^10 || ^12 || >=14" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/postcss-import": { - "version": "15.1.0", + "node_modules/jsdom": { + "version": "25.0.1", "dev": true, "license": "MIT", "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" + "cssstyle": "^4.1.0", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.0.0" + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/postcss-js": { - "version": "4.1.0", + "node_modules/jsesc": { + "version": "3.1.0", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" + "bin": { + "jsesc": "bin/jsesc" }, "engines": { - "node": "^12 || ^14 || >= 16" - }, - "peerDependencies": { - "postcss": "^8.4.21" + "node": ">=6" } }, - "node_modules/postcss-load-config": { - "version": "6.0.1", + "node_modules/json-bigint": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true, + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-ref-resolver": { + "version": "1.0.1", "license": "MIT", "dependencies": { - "lilconfig": "^3.1.1" + "fast-deep-equal": "^3.1.3" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "license": "BSD-2-Clause" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" }, "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "jiti": ">=1.21.0", - "postcss": ">=8.0.9", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - }, - "postcss": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } + "node": ">=6" } }, - "node_modules/postcss-nested": { + "node_modules/jsonfile": { "version": "6.2.0", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" + "universalify": "^2.0.0" }, - "peerDependencies": { - "postcss": "^8.2.14" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true, "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", + "node_modules/jwa": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kebab-case": { + "version": "1.0.2", "dev": true, "license": "MIT" }, - "node_modules/pretty-bytes": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", - "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "node_modules/keyv": { + "version": "4.5.4", "dev": true, "license": "MIT", - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "json-buffer": "3.0.1" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", + "node_modules/known-css-properties": { + "version": "0.30.0", "dev": true, "license": "MIT" }, - "node_modules/process-warning": { - "version": "3.0.0", + "node_modules/lazy-val": { + "version": "1.0.5", + "dev": true, "license": "MIT" }, - "node_modules/progress": { - "version": "2.0.3", + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.4.0" + "node": ">=6" } }, - "node_modules/promise-retry": { - "version": "2.0.1", + "node_modules/levn": { + "version": "0.4.1", "dev": true, "license": "MIT", "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=10" + "node": ">= 0.8.0" } }, - "node_modules/property-information": { - "version": "7.1.0", + "node_modules/light-my-request": { + "version": "5.14.0", + "license": "BSD-3-Clause", + "dependencies": { + "cookie": "^0.7.0", + "process-warning": "^3.0.0", + "set-cookie-parser": "^2.4.1" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "dev": true, "license": "MIT", + "engines": { + "node": ">=14" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sponsors/antonk52" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", "license": "MIT", "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "p-locate": "^5.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pump": { - "version": "3.0.3", + "node_modules/lodash": { + "version": "4.17.23", "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } + "license": "MIT" }, - "node_modules/punycode": { - "version": "2.3.1", + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } + "license": "MIT" }, - "node_modules/qrcode": { - "version": "1.5.4", + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmmirror.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { - "dijkstrajs": "^1.0.1", - "pngjs": "^5.0.0", - "yargs": "^15.3.1" - }, - "bin": { - "qrcode": "bin/qrcode" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/qrcode/node_modules/cliui": { - "version": "6.0.0", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } + "node_modules/loupe": { + "version": "3.2.1", + "dev": true, + "license": "MIT" }, - "node_modules/qrcode/node_modules/pngjs": { - "version": "5.0.0", + "node_modules/lowercase-keys": { + "version": "2.0.0", + "dev": true, "license": "MIT", "engines": { - "node": ">=10.13.0" + "node": ">=8" } }, - "node_modules/qrcode/node_modules/wrap-ansi": { - "version": "6.2.0", + "node_modules/lowlight": { + "version": "3.3.0", "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "highlight.js": "~11.11.0" }, - "engines": { - "node": ">=8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/qrcode/node_modules/y18n": { - "version": "4.0.3", + "node_modules/lru-cache": { + "version": "10.4.3", "license": "ISC" }, - "node_modules/qrcode/node_modules/yargs": { - "version": "15.4.1", - "license": "MIT", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/qrcode/node_modules/yargs-parser": { - "version": "18.1.3", + "node_modules/lucide-solid": { + "version": "0.300.0", "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/quansync": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz", - "integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/antfu" - }, - { - "type": "individual", - "url": "https://github.com/sponsors/sxzz" - } - ], - "license": "MIT" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/quick-format-unescaped": { - "version": "4.0.4", - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "solid-js": "^1.4.7" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "node_modules/magic-string": { + "version": "0.30.21", "dev": true, "license": "MIT", "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/react": { - "version": "19.2.0", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/reactivity-store": { - "version": "0.3.12", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "~3.5.22", - "@vue/shared": "~3.5.22", - "use-sync-external-store": "^1.6.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } + "node_modules/make-error": { + "version": "1.3.6", + "license": "ISC" }, - "node_modules/read-cache": { - "version": "1.0.0", + "node_modules/make-fetch-happen": { + "version": "14.0.3", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "pify": "^2.3.0" + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/read-config-file": { - "version": "6.3.2", - "dev": true, + "node_modules/marked": { + "version": "12.0.2", "license": "MIT", - "dependencies": { - "config-file-ts": "^0.2.4", - "dotenv": "^9.0.2", - "dotenv-expand": "^5.1.0", - "js-yaml": "^4.1.0", - "json5": "^2.2.0", - "lazy-val": "^1.0.4" + "bin": { + "marked": "bin/marked.js" }, "engines": { - "node": ">=12.0.0" + "node": ">= 18" } }, - "node_modules/readable-stream": { - "version": "3.6.2", + "node_modules/matcher": { + "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "escape-string-regexp": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/readdir-glob": { - "version": "1.1.3", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.1.0" + "node_modules/math-intrinsics": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "dev": true, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", "license": "MIT", "dependencies": { - "picomatch": "^2.2.1" + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" }, - "engines": { - "node": ">=8.10.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/real-require": { - "version": "0.2.0", + "node_modules/media-typer": { + "version": "1.1.0", "license": "MIT", "engines": { - "node": ">= 12.13.0" + "node": ">= 0.8" } }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "node_modules/merge-anything": { + "version": "5.1.7", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" + "is-what": "^4.1.8" }, "engines": { - "node": ">= 0.4" + "node": ">=12.13" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", - "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", - "dev": true, + "node_modules/merge-descriptors": { + "version": "2.0.0", "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2" - }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/regex": { - "version": "6.0.1", + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" + "engines": { + "node": ">= 8" } }, - "node_modules/regex-recursion": { - "version": "6.0.2", + "node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", "dependencies": { - "regex-utilities": "^2.3.0" + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "node_modules/regex-utilities": { - "version": "2.3.0", - "license": "MIT" - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" }, - "node_modules/regexpu-core": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", - "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", - "dev": true, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.2", - "regjsgen": "^0.8.0", - "regjsparser": "^0.13.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.2.1" - }, - "engines": { - "node": ">=4" + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" } }, - "node_modules/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", - "dev": true, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT" }, - "node_modules/regjsparser": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", - "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "node_modules/micromark-util-types": { + "version": "2.0.2", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "jsesc": "~3.1.0" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, - "bin": { - "regjsparser": "bin/parser" + "engines": { + "node": ">=8.6" } }, - "node_modules/require-directory": { - "version": "2.1.1", + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/require-from-string": { - "version": "2.0.2", + "node_modules/mime": { + "version": "3.0.0", "license": "MIT", + "bin": { + "mime": "cli.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "license": "ISC" - }, - "node_modules/resolve": { - "version": "1.22.11", + "node_modules/mimic-fn": { + "version": "2.1.0", "dev": true, "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "10.2.0", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-10.2.0.tgz", + "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">= 0.4" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "dev": true, + "node_modules/minimist": { + "version": "1.2.8", "license": "MIT", "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/responselike": { + "node_modules/minipass": { + "version": "7.1.2", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { "version": "2.0.1", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "lowercase-keys": "^2.0.0" + "minipass": "^7.0.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=16 || 14 >=14.17" } }, - "node_modules/ret": { - "version": "0.4.3", + "node_modules/minipass-fetch": { + "version": "4.0.1", + "dev": true, "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, "engines": { - "node": ">=10" + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" } }, - "node_modules/retry": { - "version": "0.12.0", + "node_modules/minipass-flush": { + "version": "1.0.5", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, "engines": { - "node": ">= 4" + "node": ">= 8" } }, - "node_modules/reusify": { - "version": "1.1.0", - "license": "MIT", + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/rfdc": { - "version": "1.4.1", - "license": "MIT" + "node_modules/minipass-flush/node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" }, - "node_modules/rimraf": { - "version": "5.0.10", + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, "license": "ISC", "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" + "minipass": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">=8" } }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.5.0", + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "dev": true, "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "yallist": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">=8" } }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.5", + "node_modules/minipass-pipeline/node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "minipass": "^3.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/rimraf/node_modules/minipass": { - "version": "7.1.2", + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "dev": true, "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=8" } }, - "node_modules/roarr": { - "version": "2.15.4", + "node_modules/minipass-sized/node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=8.0" - } + "license": "ISC" }, - "node_modules/rollup": { - "version": "4.52.5", + "node_modules/minizlib": { + "version": "3.1.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" + "minipass": "^7.1.2" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.52.5", - "@rollup/rollup-android-arm64": "4.52.5", - "@rollup/rollup-darwin-arm64": "4.52.5", - "@rollup/rollup-darwin-x64": "4.52.5", - "@rollup/rollup-freebsd-arm64": "4.52.5", - "@rollup/rollup-freebsd-x64": "4.52.5", - "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", - "@rollup/rollup-linux-arm-musleabihf": "4.52.5", - "@rollup/rollup-linux-arm64-gnu": "4.52.5", - "@rollup/rollup-linux-arm64-musl": "4.52.5", - "@rollup/rollup-linux-loong64-gnu": "4.52.5", - "@rollup/rollup-linux-ppc64-gnu": "4.52.5", - "@rollup/rollup-linux-riscv64-gnu": "4.52.5", - "@rollup/rollup-linux-riscv64-musl": "4.52.5", - "@rollup/rollup-linux-s390x-gnu": "4.52.5", - "@rollup/rollup-linux-x64-gnu": "4.52.5", - "@rollup/rollup-linux-x64-musl": "4.52.5", - "@rollup/rollup-openharmony-arm64": "4.52.5", - "@rollup/rollup-win32-arm64-msvc": "4.52.5", - "@rollup/rollup-win32-ia32-msvc": "4.52.5", - "@rollup/rollup-win32-x64-gnu": "4.52.5", - "@rollup/rollup-win32-x64-msvc": "4.52.5", - "fsevents": "~2.3.2" + "node": ">= 18" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/mnemonist": { + "version": "0.39.6", "license": "MIT", "dependencies": { - "queue-microtask": "^1.2.2" + "obliterator": "^2.0.1" } }, - "node_modules/safe-array-concat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "node_modules/monaco-editor": { + "version": "0.52.2", + "resolved": "https://registry.npmmirror.com/monaco-editor/-/monaco-editor-0.52.2.tgz", + "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" } }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "node_modules/nanoid": { + "version": "3.3.11", "dev": true, - "license": "MIT" - }, - "node_modules/safe-buffer": { - "version": "5.2.1", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "url": "https://github.com/sponsors/ai" } ], - "license": "MIT" - }, - "node_modules/safe-push-apply": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "dev": true, "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "isarray": "^2.0.5" + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/safe-push-apply/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "node_modules/natural-compare": { + "version": "1.4.0", "dev": true, "license": "MIT" }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "dev": true, + "node_modules/negotiator": { + "version": "1.0.0", "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/safe-regex2": { - "version": "3.1.0", + "node_modules/node-abi": { + "version": "4.26.0", + "dev": true, "license": "MIT", "dependencies": { - "ret": "~0.4.0" + "semver": "^7.6.3" + }, + "engines": { + "node": ">=22.12.0" } }, - "node_modules/safe-stable-stringify": { - "version": "2.5.0", - "license": "MIT", + "node_modules/node-abi/node_modules/semver": { + "version": "7.7.3", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { "node": ">=10" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", + "node_modules/node-addon-api": { + "version": "1.7.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, - "node_modules/sanitize-filename": { - "version": "1.6.3", + "node_modules/node-api-version": { + "version": "0.2.1", "dev": true, - "license": "WTFPL OR ISC", + "license": "MIT", "dependencies": { - "truncate-utf8-bytes": "^1.0.0" + "semver": "^7.3.5" } }, - "node_modules/sax": { - "version": "1.4.3", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/secure-json-parse": { - "version": "2.7.0", - "license": "BSD-3-Clause" - }, - "node_modules/semver": { - "version": "6.3.1", + "node_modules/node-api-version/node_modules/semver": { + "version": "7.7.3", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/semver-compare": { + "node_modules/node-domexception": { "version": "1.0.0", - "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], "license": "MIT", - "optional": true + "engines": { + "node": ">=10.5.0" + } }, - "node_modules/serialize-error": { - "version": "7.0.1", - "dev": true, + "node_modules/node-fetch": { + "version": "3.3.2", "license": "MIT", - "optional": true, "dependencies": { - "type-fest": "^0.13.1" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" } }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "node_modules/node-gyp": { + "version": "11.5.0", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "randombytes": "^2.1.0" + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "tinyglobby": "^0.2.12", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/seroval": { - "version": "1.3.2", - "license": "MIT", - "peer": true, + "node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/seroval-plugins": { - "version": "1.3.3", - "license": "MIT", + "node_modules/node-gyp/node_modules/semver": { + "version": "7.7.3", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { "node": ">=10" - }, - "peerDependencies": { - "seroval": "^1.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "license": "ISC" - }, - "node_modules/set-cookie-parser": { - "version": "2.7.2", - "license": "MIT" - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "node_modules/node-gyp/node_modules/tar": { + "version": "7.5.6", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=18" } }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "node_modules/node-gyp/node_modules/which": { + "version": "5.0.0", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" }, "engines": { - "node": ">= 0.4" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/set-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "node_modules/node-gyp/node_modules/which/node_modules/isexe": { + "version": "3.1.2", "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">= 0.4" + "node": ">=20" } }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "license": "ISC" + "node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } }, - "node_modules/sharp": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", - "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "node_modules/node-releases": { + "version": "2.0.27", "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", + "license": "MIT" + }, + "node_modules/nopt": { + "version": "8.1.0", + "dev": true, + "license": "ISC", "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.3", - "semver": "^7.6.3" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "abbrev": "^3.0.0" }, - "funding": { - "url": "https://opencollective.com/libvips" + "bin": { + "nopt": "bin/nopt.js" }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.33.5", - "@img/sharp-darwin-x64": "0.33.5", - "@img/sharp-libvips-darwin-arm64": "1.0.4", - "@img/sharp-libvips-darwin-x64": "1.0.4", - "@img/sharp-libvips-linux-arm": "1.0.5", - "@img/sharp-libvips-linux-arm64": "1.0.4", - "@img/sharp-libvips-linux-s390x": "1.0.4", - "@img/sharp-libvips-linux-x64": "1.0.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", - "@img/sharp-libvips-linuxmusl-x64": "1.0.4", - "@img/sharp-linux-arm": "0.33.5", - "@img/sharp-linux-arm64": "0.33.5", - "@img/sharp-linux-s390x": "0.33.5", - "@img/sharp-linux-x64": "0.33.5", - "@img/sharp-linuxmusl-arm64": "0.33.5", - "@img/sharp-linuxmusl-x64": "0.33.5", - "@img/sharp-wasm32": "0.33.5", - "@img/sharp-win32-ia32": "0.33.5", - "@img/sharp-win32-x64": "0.33.5" + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/sharp-ico": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/sharp-ico/-/sharp-ico-0.1.5.tgz", - "integrity": "sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==", + "node_modules/normalize-path": { + "version": "3.0.0", "dev": true, "license": "MIT", - "dependencies": { - "decode-ico": "*", - "ico-endec": "*", - "sharp": "*" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/sharp/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "node_modules/normalize-range": { + "version": "0.1.2", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/shebang-command": { - "version": "2.0.0", + "node_modules/normalize-url": { + "version": "6.1.0", + "dev": true, "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", + "node_modules/nwsapi": { + "version": "2.2.23", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/shiki": { - "version": "3.15.0", + "node_modules/object-hash": { + "version": "3.0.0", + "dev": true, "license": "MIT", - "dependencies": { - "@shikijs/core": "3.15.0", - "@shikijs/engine-javascript": "3.15.0", - "@shikijs/engine-oniguruma": "3.15.0", - "@shikijs/langs": "3.15.0", - "@shikijs/themes": "3.15.0", - "@shikijs/types": "3.15.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" + "engines": { + "node": ">= 6" } }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, + "node_modules/object-inspect": { + "version": "1.13.4", "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, "engines": { "node": ">= 0.4" }, @@ -9562,34 +10276,27 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "node_modules/object-keys": { + "version": "1.1.1", "dev": true, "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -9598,929 +10305,894 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, + "node_modules/obliterator": { + "version": "2.0.5", + "license": "MIT" + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" + "ee-first": "1.1.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.8" } }, - "node_modules/signal-exit": { - "version": "4.1.0", + "node_modules/once": { + "version": "1.4.0", "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, "engines": { - "node": ">=14" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/simple-swizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", - "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", - "dev": true, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.4", "license": "MIT", "dependencies": { - "is-arrayish": "^0.3.1" + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" } }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", + "node_modules/optionator": { + "version": "0.9.4", "dev": true, "license": "MIT", "dependencies": { - "semver": "^7.5.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { - "node": ">=10" + "node": ">= 0.8.0" } }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.7.3", + "node_modules/ora": { + "version": "5.4.1", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/slice-ansi": { - "version": "3.0.0", + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.1", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", + "node_modules/ora/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, "license": "MIT", - "optional": true, "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" + "node": ">=8" } }, - "node_modules/smob": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", - "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "dev": true, - "license": "MIT" - }, - "node_modules/solid-js": { - "version": "1.9.10", "license": "MIT", - "peer": true, "dependencies": { - "csstype": "^3.1.0", - "seroval": "~1.3.0", - "seroval-plugins": "~1.3.0" + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/solid-presence": { - "version": "0.1.8", + "node_modules/p-cancelable": { + "version": "2.1.1", + "dev": true, "license": "MIT", - "dependencies": { - "@corvu/utils": "~0.4.0" - }, - "peerDependencies": { - "solid-js": "^1.8" + "engines": { + "node": ">=8" } }, - "node_modules/solid-prevent-scroll": { - "version": "0.1.10", + "node_modules/p-limit": { + "version": "3.1.0", "license": "MIT", "dependencies": { - "@corvu/utils": "~0.4.1" + "yocto-queue": "^0.1.0" }, - "peerDependencies": { - "solid-js": "^1.8" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/solid-refresh": { - "version": "0.6.3", - "dev": true, + "node_modules/p-locate": { + "version": "5.0.0", "license": "MIT", "dependencies": { - "@babel/generator": "^7.23.6", - "@babel/helper-module-imports": "^7.22.15", - "@babel/types": "^7.23.6" + "p-limit": "^3.0.2" }, - "peerDependencies": { - "solid-js": "^1.3" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/solid-toast": { - "version": "0.5.0", + "node_modules/p-map": { + "version": "7.0.4", + "dev": true, "license": "MIT", - "peerDependencies": { - "solid-js": "^1.5.4" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/sonic-boom": { - "version": "4.2.0", - "license": "MIT", - "dependencies": { - "atomic-sleep": "^1.0.0" - } + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "license": "BlueOak-1.0.0" }, - "node_modules/source-map": { - "version": "0.6.1", + "node_modules/parent-module": { + "version": "1.0.1", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/source-map-js": { - "version": "1.2.1", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/parse-json": { + "version": "2.2.0", + "license": "MIT", + "dependencies": { + "error-ex": "^1.2.0" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", + "node_modules/parse5": { + "version": "7.3.0", "dev": true, "license": "MIT", "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead", - "dev": true, - "license": "MIT" - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", + "node_modules/parseurl": { + "version": "1.3.3", "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": ">= 0.8" } }, - "node_modules/split2": { - "version": "4.2.0", - "license": "ISC", + "node_modules/path-exists": { + "version": "4.0.0", + "license": "MIT", "engines": { - "node": ">= 10.x" + "node": ">=8" } }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "dev": true, - "license": "BSD-3-Clause", - "optional": true - }, - "node_modules/stat-mode": { - "version": "1.0.0", + "node_modules/path-is-absolute": { + "version": "1.0.1", "dev": true, "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, - "node_modules/statuses": { - "version": "2.0.1", + "node_modules/path-key": { + "version": "3.1.1", "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/stop-iteration-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "node_modules/path-parse": { + "version": "1.0.7", "dev": true, - "license": "MIT", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "license": "BlueOak-1.0.0", "dependencies": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, + "node_modules/path-to-regexp": { + "version": "8.3.0", "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/string-width": { - "version": "4.2.3", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } + "node_modules/pathe": { + "version": "1.1.2", + "dev": true, + "license": "MIT" }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", + "node_modules/pathval": { + "version": "2.0.1", + "dev": true, "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">=8" + "node": ">= 14.16" } }, - "node_modules/string.prototype.matchall": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", - "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "node_modules/pe-library": { + "version": "0.4.1", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "regexp.prototype.flags": "^1.5.3", - "set-function-name": "^2.0.2", - "side-channel": "^1.1.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=12", + "npm": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "github", + "url": "https://github.com/sponsors/jet2jet" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "node_modules/pend": { + "version": "1.2.0", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-data-property": "^1.1.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" - }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "node_modules/pify": { + "version": "2.3.0", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, + "node_modules/pinkie": { + "version": "2.0.4", "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/stringify-entities": { - "version": "4.0.4", + "node_modules/pino": { + "version": "9.14.0", "license": "MIT", "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" + "@pinojs/redact": "^0.4.0", + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "bin": { + "pino": "bin.js" } }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/pino-abstract-transport": { + "version": "2.0.0", + "license": "MIT", "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, + "split2": "^4.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.1.0", + "license": "MIT" + }, + "node_modules/pino/node_modules/process-warning": { + "version": "5.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/pirates": { + "version": "4.0.7", + "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 6" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", + "node_modules/pkce-challenge": { + "version": "5.0.1", "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=16.20.0" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", + "node_modules/plist": { + "version": "3.1.0", + "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" }, "engines": { - "node": ">=8" + "node": ">=10.4.0" } }, - "node_modules/strip-comments": { + "node_modules/png2icons": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", - "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" + "bin": { + "png2icons": "png2icons-cli.js" } }, - "node_modules/sucrase": { - "version": "3.35.0", + "node_modules/pngjs": { + "version": "7.0.0", "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=14.19.0" } }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", "engines": { - "node": ">= 6" + "node": ">= 0.4" } }, - "node_modules/sucrase/node_modules/glob": { - "version": "10.4.5", + "node_modules/postcss": { + "version": "8.5.6", "dev": true, - "license": "ISC", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": "^10 || ^12 || >=14" } }, - "node_modules/sucrase/node_modules/minimatch": { - "version": "9.0.5", + "node_modules/postcss-import": { + "version": "15.1.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=14.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "postcss": "^8.0.0" } }, - "node_modules/sucrase/node_modules/minipass": { - "version": "7.1.2", + "node_modules/postcss-js": { + "version": "4.1.0", "dev": true, - "license": "ISC", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" } }, - "node_modules/sumchecker": { - "version": "3.0.1", + "node_modules/postcss-load-config": { + "version": "6.0.1", "dev": true, - "license": "Apache-2.0", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "debug": "^4.1.0" + "lilconfig": "^3.1.1" }, "engines": { - "node": ">= 8.0" + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } } }, - "node_modules/supports-color": { - "version": "7.2.0", + "node_modules/postcss-nested": { + "version": "6.2.0", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "postcss-selector-parser": "^6.1.1" }, "engines": { - "node": ">=8" + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", + "node_modules/postcss-selector-parser": { + "version": "6.1.2", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=4" } }, - "node_modules/tailwindcss": { - "version": "3.4.18", + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/postject": { + "version": "1.0.0-alpha.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.6.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.7", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" + "commander": "^9.4.0" }, "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" + "postject": "dist/cli.js" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/tar": { - "version": "6.2.1", + "node_modules/postject/node_modules/commander": { + "version": "9.5.0", "dev": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, + "license": "MIT", + "optional": true, + "peer": true, "engines": { - "node": ">=10" + "node": "^12.20.0 || >=14" } }, - "node_modules/tar-stream": { - "version": "2.2.0", + "node_modules/prelude-ls": { + "version": "1.2.1", "dev": true, "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, "engines": { - "node": ">=6" + "node": ">= 0.8.0" } }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", + "node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmmirror.com/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", "dev": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "node_modules/proc-log": { + "version": "5.0.0", "dev": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=8" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/temp-file": { - "version": "3.4.0", + "node_modules/process-warning": { + "version": "3.0.0", + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", "dev": true, "license": "MIT", - "dependencies": { - "async-exit-hook": "^2.0.1", - "fs-extra": "^10.0.0" + "engines": { + "node": ">=0.4.0" } }, - "node_modules/temp-file/node_modules/fs-extra": { - "version": "10.1.0", + "node_modules/promise-retry": { + "version": "2.0.1", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "err-code": "^2.0.2", + "retry": "^0.12.0" }, "engines": { - "node": ">=12" + "node": ">=10" } }, - "node_modules/temp-file/node_modules/jsonfile": { - "version": "6.2.0", + "node_modules/proper-lockfile": { + "version": "4.1.2", "dev": true, "license": "MIT", "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" } }, - "node_modules/temp-file/node_modules/universalify": { - "version": "2.0.1", + "node_modules/proper-lockfile/node_modules/signal-exit": { + "version": "3.0.7", "dev": true, + "license": "ISC" + }, + "node_modules/property-information": { + "version": "7.1.0", "license": "MIT", - "engines": { - "node": ">= 10.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/tempy": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", - "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", - "dev": true, + "node_modules/proxy-addr": { + "version": "2.0.7", "license": "MIT", "dependencies": { - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.10" } }, - "node_modules/tempy/node_modules/type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "node_modules/pump": { + "version": "3.0.3", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/terser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", - "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/qrcode": { + "version": "1.5.4", + "license": "MIT", "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" + "dijkstrajs": "^1.0.1", + "pngjs": "^5.0.0", + "yargs": "^15.3.1" }, "bin": { - "terser": "bin/terser" + "qrcode": "bin/qrcode" }, "engines": { - "node": ">=10" + "node": ">=10.13.0" } }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/thenify": { - "version": "3.3.1", - "dev": true, + "node_modules/qrcode/node_modules/ansi-regex": { + "version": "5.0.1", "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/thenify-all": { - "version": "1.6.0", - "dev": true, + "node_modules/qrcode/node_modules/ansi-styles": { + "version": "4.3.0", "license": "MIT", "dependencies": { - "thenify": ">= 3.1.0 < 4" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=0.8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/thread-stream": { - "version": "3.1.0", - "license": "MIT", + "node_modules/qrcode/node_modules/cliui": { + "version": "6.0.0", + "license": "ISC", "dependencies": { - "real-require": "^0.2.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, + "node_modules/qrcode/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/qrcode/node_modules/pngjs": { + "version": "5.0.0", "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" + "node": ">=10.13.0" } }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, + "node_modules/qrcode/node_modules/string-width": { + "version": "4.2.3", "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "engines": { + "node": ">=8" } }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, + "node_modules/qrcode/node_modules/strip-ansi": { + "version": "6.0.1", "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/tmp": { - "version": "0.2.5", - "dev": true, - "license": "MIT", "engines": { - "node": ">=14.14" + "node": ">=8" } }, - "node_modules/tmp-promise": { - "version": "3.0.3", - "dev": true, + "node_modules/qrcode/node_modules/wrap-ansi": { + "version": "6.2.0", "license": "MIT", "dependencies": { - "tmp": "^0.2.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/to-data-view": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", - "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", - "dev": true, - "license": "MIT" + "node_modules/qrcode/node_modules/y18n": { + "version": "4.0.3", + "license": "ISC" }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "dev": true, + "node_modules/qrcode/node_modules/yargs": { + "version": "15.4.1", "license": "MIT", "dependencies": { - "is-number": "^7.0.0" + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" }, "engines": { - "node": ">=8.0" + "node": ">=8" } }, - "node_modules/toad-cache": { - "version": "3.7.0", - "license": "MIT", + "node_modules/qrcode/node_modules/yargs-parser": { + "version": "18.1.3", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, "engines": { - "node": ">=12" + "node": ">=6" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "license": "MIT", + "node_modules/qs": { + "version": "6.14.1", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, "engines": { "node": ">=0.6" - } - }, - "node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "license": "MIT", + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/truncate-utf8-bytes": { - "version": "1.0.2", - "dev": true, - "license": "WTFPL", - "dependencies": { - "utf8-byte-length": "^1.0.1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/ts-node": { - "version": "10.9.2", + "node_modules/quansync": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/quansync/-/quansync-1.0.0.tgz", + "integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==", "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" }, - "@swc/wasm": { - "optional": true + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" } - } + ], + "license": "MIT" }, - "node_modules/ts-node/node_modules/arg": { - "version": "4.1.3", + "node_modules/queue-microtask": { + "version": "1.2.3", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT" }, - "node_modules/tslib": { - "version": "2.8.1", - "license": "0BSD" + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "license": "MIT" }, - "node_modules/tsx": { - "version": "4.20.6", + "node_modules/quick-lru": { + "version": "5.1.1", "dev": true, "license": "MIT", - "dependencies": { - "esbuild": "~0.25.0", - "get-tsconfig": "^4.7.5" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/type-fest": { - "version": "0.13.1", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "optional": true, "engines": { "node": ">=10" }, @@ -10528,570 +11200,3036 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" - }, + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/typed-array-byte-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "dev": true, + "node_modules/raw-body": { + "version": "3.0.2", "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.14" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.10" } }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "dev": true, + "node_modules/raw-body/node_modules/http-errors": { + "version": "2.0.1", "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.15", - "reflect.getprototypeof": "^1.0.9" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/typed-array-length": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", - "dev": true, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.7.2", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=0.10.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/typescript": { - "version": "5.9.3", - "dev": true, - "license": "Apache-2.0", + "node_modules/react": { + "version": "19.2.4", + "license": "MIT", "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, "engines": { - "node": ">=14.17" + "node": ">=0.10.0" } }, - "node_modules/unbox-primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "dev": true, + "node_modules/reactivity-store": { + "version": "0.3.12", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" + "@vue/reactivity": "~3.5.22", + "@vue/shared": "~3.5.22", + "use-sync-external-store": "^1.6.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/unconfig": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-7.4.2.tgz", - "integrity": "sha512-nrMlWRQ1xdTjSnSUqvYqJzbTBFugoqHobQj58B2bc8qxHKBBHMNNsWQFP3Cd3/JZK907voM2geYPWqD4VK3MPQ==", + "node_modules/read-binary-file-arch": { + "version": "1.0.6", "dev": true, "license": "MIT", "dependencies": { - "@quansync/fs": "^1.0.0", - "defu": "^6.1.4", - "jiti": "^2.6.1", - "quansync": "^1.0.0", - "unconfig-core": "7.4.2" + "debug": "^4.3.4" }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "bin": { + "read-binary-file-arch": "cli.js" } }, - "node_modules/unconfig-core": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.4.2.tgz", - "integrity": "sha512-VgPCvLWugINbXvMQDf8Jh0mlbvNjNC6eSUziHsBCMpxR05OPrNrvDnyatdMjRgcHaaNsCqz+wjNXxNw1kRLHUg==", + "node_modules/read-cache": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "@quansync/fs": "^1.0.0", - "quansync": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "pify": "^2.3.0" } }, - "node_modules/unconfig/node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "node_modules/readable-stream": { + "version": "3.6.2", "dev": true, "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/undici": { - "version": "6.22.0", - "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, "engines": { - "node": ">=18.17" + "node": ">= 6" } }, - "node_modules/undici-types": { - "version": "6.21.0", - "dev": true, - "license": "MIT" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "node_modules/readdirp": { + "version": "3.6.0", "dev": true, "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, "engines": { - "node": ">=4" + "node": ">=8.10.0" } }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", "dev": true, "license": "MIT", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, "engines": { - "node": ">=4" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", - "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", - "dev": true, + "node_modules/real-require": { + "version": "0.2.0", "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 12.13.0" } }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", - "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmmirror.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", "dev": true, "license": "MIT", "dependencies": { - "crypto-random-string": "^2.0.0" + "regenerate": "^1.4.2" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/unist-util-is": { - "version": "6.0.1", + "node_modules/regex": { + "version": "6.1.0", "license": "MIT", "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "regex-utilities": "^2.3.0" } }, - "node_modules/unist-util-position": { - "version": "5.0.0", + "node_modules/regex-recursion": { + "version": "6.0.2", "license": "MIT", "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "regex-utilities": "^2.3.0" } }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", + "node_modules/regex-utilities": { + "version": "2.3.0", + "license": "MIT" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, "license": "MIT", "dependencies": { - "@types/unist": "^3.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unist-util-visit": { - "version": "5.0.0", + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "dev": true, "license": "MIT", "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=4" } }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "license": "MIT", + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmmirror.com/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "resolved": "https://registry.npmmirror.com/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" + "jsesc": "~3.1.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "bin": { + "regjsparser": "bin/parser" } }, - "node_modules/universalify": { - "version": "0.1.2", - "dev": true, + "node_modules/require-directory": { + "version": "2.1.1", "license": "MIT", "engines": { - "node": ">= 4.0.0" + "node": ">=0.10.0" } }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, + "node_modules/require-from-string": { + "version": "2.0.2", "license": "MIT", "engines": { - "node": ">=4", - "yarn": "*" + "node": ">=0.10.0" } }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "node_modules/require-main-filename": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/resedit": { + "version": "1.7.2", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" + "pe-library": "^0.4.1" }, - "bin": { - "update-browserslist-db": "cli.js" + "engines": { + "node": ">=12", + "npm": ">=6" }, - "peerDependencies": { - "browserslist": ">= 4.21.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" } }, - "node_modules/uri-js": { - "version": "4.4.1", + "node_modules/resolve": { + "version": "1.22.11", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/use-sync-external-store": { - "version": "1.6.0", "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/utf8-byte-length": { - "version": "1.0.5", - "dev": true, - "license": "(WTFPL OR MIT)" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", + "node_modules/resolve-alpn": { + "version": "1.2.1", "dev": true, "license": "MIT" }, - "node_modules/verror": { - "version": "1.10.1", + "node_modules/resolve-from": { + "version": "4.0.0", "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, "engines": { - "node": ">=0.6.0" + "node": ">=4" } }, - "node_modules/vfile": { - "version": "6.0.3", + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "dev": true, "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/vfile-message": { - "version": "4.0.3", + "node_modules/responselike": { + "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" + "lowercase-keys": "^2.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/vite": { - "version": "5.4.21", + "node_modules/restore-cursor": { + "version": "3.1.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } + "node": ">=8" } }, - "node_modules/vite-plugin-pwa": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.2.0.tgz", - "integrity": "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==", + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", "dev": true, + "license": "ISC" + }, + "node_modules/ret": { + "version": "0.4.3", "license": "MIT", - "dependencies": { - "debug": "^4.3.6", - "pretty-bytes": "^6.1.1", - "tinyglobby": "^0.2.10", - "workbox-build": "^7.4.0", - "workbox-window": "^7.4.0" - }, "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vite-pwa/assets-generator": "^1.0.0", - "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", - "workbox-build": "^7.4.0", - "workbox-window": "^7.4.0" - }, - "peerDependenciesMeta": { - "@vite-pwa/assets-generator": { - "optional": true - } + "node": ">=10" } }, - "node_modules/vite-plugin-solid": { - "version": "2.11.10", + "node_modules/retry": { + "version": "0.12.0", "dev": true, "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "5.0.10", + "license": "ISC", "dependencies": { - "@babel/core": "^7.23.3", - "@types/babel__core": "^7.20.4", - "babel-preset-solid": "^1.8.4", - "merge-anything": "^5.1.7", - "solid-refresh": "^0.6.3", - "vitefu": "^1.0.4" + "glob": "^10.3.7" }, - "peerDependencies": { - "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", - "solid-js": "^1.7.2", - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + "bin": { + "rimraf": "dist/esm/bin.mjs" }, - "peerDependenciesMeta": { - "@testing-library/jest-dom": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "cpu": [ - "x64" - ], + "node_modules/roarr": { + "version": "2.15.4", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, "engines": { - "node": ">=12" + "node": ">=8.0" } }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.21.5", + "node_modules/rollup": { + "version": "4.57.1", "dev": true, - "hasInstallScript": true, "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, "bin": { - "esbuild": "bin/esbuild" + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=12" + "node": ">=18.0.0", + "npm": ">=8.0.0" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@rollup/rollup-android-arm-eabi": "4.57.1", + "@rollup/rollup-android-arm64": "4.57.1", + "@rollup/rollup-darwin-arm64": "4.57.1", + "@rollup/rollup-darwin-x64": "4.57.1", + "@rollup/rollup-freebsd-arm64": "4.57.1", + "@rollup/rollup-freebsd-x64": "4.57.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", + "@rollup/rollup-linux-arm-musleabihf": "4.57.1", + "@rollup/rollup-linux-arm64-gnu": "4.57.1", + "@rollup/rollup-linux-arm64-musl": "4.57.1", + "@rollup/rollup-linux-loong64-gnu": "4.57.1", + "@rollup/rollup-linux-loong64-musl": "4.57.1", + "@rollup/rollup-linux-ppc64-gnu": "4.57.1", + "@rollup/rollup-linux-ppc64-musl": "4.57.1", + "@rollup/rollup-linux-riscv64-gnu": "4.57.1", + "@rollup/rollup-linux-riscv64-musl": "4.57.1", + "@rollup/rollup-linux-s390x-gnu": "4.57.1", + "@rollup/rollup-linux-x64-gnu": "4.57.1", + "@rollup/rollup-linux-x64-musl": "4.57.1", + "@rollup/rollup-openbsd-x64": "4.57.1", + "@rollup/rollup-openharmony-arm64": "4.57.1", + "@rollup/rollup-win32-arm64-msvc": "4.57.1", + "@rollup/rollup-win32-ia32-msvc": "4.57.1", + "@rollup/rollup-win32-x64-gnu": "4.57.1", + "@rollup/rollup-win32-x64-msvc": "4.57.1", + "fsevents": "~2.3.2" } }, - "node_modules/vitefu": { - "version": "1.1.1", - "dev": true, + "node_modules/router": { + "version": "2.2.0", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "dev": true, + "license": "MIT" + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex2": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "ret": "~0.4.0" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "dev": true, + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sax": { + "version": "1.4.4", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "license": "BSD-3-Clause" + }, + "node_modules/semver": { + "version": "7.7.4", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/send": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/send/node_modules/http-errors": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/send/node_modules/mime-types": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/send/node_modules/mime-types/node_modules/mime-db": { + "version": "1.54.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/seroval": { + "version": "1.5.0", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/seroval-plugins": { + "version": "1.5.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "seroval": "^1.0" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "license": "MIT" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/sharp-ico": { + "version": "0.1.5", + "resolved": "https://registry.npmmirror.com/sharp-ico/-/sharp-ico-0.1.5.tgz", + "integrity": "sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "decode-ico": "*", + "ico-endec": "*", + "sharp": "*" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "3.22.0", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.22.0", + "@shikijs/engine-javascript": "3.22.0", + "@shikijs/engine-oniguruma": "3.22.0", + "@shikijs/langs": "3.22.0", + "@shikijs/themes": "3.22.0", + "@shikijs/types": "3.22.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.7.3", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/smob": { + "version": "1.6.1", + "resolved": "https://registry.npmmirror.com/smob/-/smob-1.6.1.tgz", + "integrity": "sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/solid-js": { + "version": "1.9.11", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.0", + "seroval": "~1.5.0", + "seroval-plugins": "~1.5.0" + } + }, + "node_modules/solid-presence": { + "version": "0.1.8", + "license": "MIT", + "dependencies": { + "@corvu/utils": "~0.4.0" + }, + "peerDependencies": { + "solid-js": "^1.8" + } + }, + "node_modules/solid-prevent-scroll": { + "version": "0.1.10", + "license": "MIT", + "dependencies": { + "@corvu/utils": "~0.4.1" + }, + "peerDependencies": { + "solid-js": "^1.8" + } + }, + "node_modules/solid-refresh": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/generator": "^7.23.6", + "@babel/helper-module-imports": "^7.22.15", + "@babel/types": "^7.23.6" + }, + "peerDependencies": { + "solid-js": "^1.3" + } + }, + "node_modules/solid-toast": { + "version": "0.5.0", + "license": "MIT", + "peerDependencies": { + "solid-js": "^1.5.4" + } + }, + "node_modules/sonic-boom": { + "version": "4.2.0", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "deprecated": "The work that was done in this beta branch won't be included in future versions", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/source-map/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/source-map/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true, + "license": "MIT" + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/ssri": { + "version": "12.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/stat-mode": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.10.0", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmmirror.com/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "dev": true, + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/tailwindcss": { + "version": "3.4.19", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/jiti": { + "version": "1.21.7", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/tar": { + "version": "7.5.7", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tauri-plugin-keepawake-api": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/tauri-plugin-keepawake-api/-/tauri-plugin-keepawake-api-0.1.0.tgz", + "integrity": "sha512-XPUl66zUYiB7kCRxsTdmCoNjFM/++NWCJ4kdTo2NUOgBUa8UVYfayDWnnTzGIQbhT7qNAHs+jgKSjhqSKs/QHA==", + "dependencies": { + "@tauri-apps/api": ">=2.0.0-beta.6" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/temp-file": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "async-exit-hook": "^2.0.1", + "fs-extra": "^10.0.0" + } + }, + "node_modules/temp-file/node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/temp-file/node_modules/jsonfile": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/temp-file/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/temp/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/temp/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/temp/node_modules/mkdirp": { + "version": "0.5.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/temp/node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.46.0", + "resolved": "https://registry.npmmirror.com/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/tiny-async-pool": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^5.5.0" + } + }, + "node_modules/tiny-async-pool/node_modules/semver": { + "version": "5.7.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "6.1.86", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.86", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/to-data-view": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/to-data-view/-/to-data-view-1.1.0.tgz", + "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toad-cache": { + "version": "3.7.0", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "5.1.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "dev": true, + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/ts-api-utils": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tsconfig": { + "version": "5.0.3", + "license": "MIT", + "dependencies": { + "any-promise": "^1.3.0", + "parse-json": "^2.2.0", + "strip-bom": "^2.0.0", + "strip-json-comments": "^2.0.0" + } + }, + "node_modules/tsconfig/node_modules/strip-json-comments": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.27.3", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/tsx/node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.13.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/mime-types/node_modules/mime-db": { + "version": "1.54.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.54.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.54.0", + "@typescript-eslint/parser": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/utils": "8.54.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unconfig": { + "version": "7.5.0", + "resolved": "https://registry.npmmirror.com/unconfig/-/unconfig-7.5.0.tgz", + "integrity": "sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@quansync/fs": "^1.0.0", + "defu": "^6.1.4", + "jiti": "^2.6.1", + "quansync": "^1.0.0", + "unconfig-core": "7.5.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unconfig-core": { + "version": "7.5.0", + "resolved": "https://registry.npmmirror.com/unconfig-core/-/unconfig-core-7.5.0.tgz", + "integrity": "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@quansync/fs": "^1.0.0", + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/undici": { + "version": "6.23.0", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-filename": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/user-home": { + "version": "1.1.1", + "license": "MIT", + "bin": { + "user-home": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/v8flags": { + "version": "2.1.1", + "dependencies": { + "user-home": "^1.1.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "7.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/node_modules/vite": { + "version": "5.4.21", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node/node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vite-node/node_modules/vite/node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-pwa": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/vite-plugin-pwa/-/vite-plugin-pwa-1.2.0.tgz", + "integrity": "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.6", + "pretty-bytes": "^6.1.1", + "tinyglobby": "^0.2.10", + "workbox-build": "^7.4.0", + "workbox-window": "^7.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vite-pwa/assets-generator": "^1.0.0", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "workbox-build": "^7.4.0", + "workbox-window": "^7.4.0" + }, + "peerDependenciesMeta": { + "@vite-pwa/assets-generator": { + "optional": true + } + } + }, + "node_modules/vite-plugin-solid": { + "version": "2.11.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.3", + "@types/babel__core": "^7.20.4", + "babel-preset-solid": "^1.8.4", + "merge-anything": "^5.1.7", + "solid-refresh": "^0.6.3", + "vitefu": "^1.0.4" + }, + "peerDependencies": { + "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", + "solid-js": "^1.7.2", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "@testing-library/jest-dom": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.27.3", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/vite/node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.1", + "dev": true, "license": "MIT", "workspaces": [ "tests/deps/*", @@ -11099,909 +14237,1475 @@ "tests/projects/workspace/packages/*" ], "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "2.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.9", + "@vitest/mocker": "2.1.9", + "@vitest/pretty-format": "^2.1.9", + "@vitest/runner": "2.1.9", + "@vitest/snapshot": "2.1.9", + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.9", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.9", + "@vitest/ui": "2.1.9", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "2.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/vite": { + "version": "5.4.21", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vitest/node_modules/vite/node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "license": "ISC" + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-background-sync": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-background-sync/-/workbox-background-sync-7.4.0.tgz", + "integrity": "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.4.0" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-broadcast-update/-/workbox-broadcast-update-7.4.0.tgz", + "integrity": "sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0" + } + }, + "node_modules/workbox-build": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-build/-/workbox-build-7.4.0.tgz", + "integrity": "sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.24.4", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^2.4.1", + "@rollup/plugin-terser": "^0.4.3", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^11.0.1", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.79.2", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "7.4.0", + "workbox-broadcast-update": "7.4.0", + "workbox-cacheable-response": "7.4.0", + "workbox-core": "7.4.0", + "workbox-expiration": "7.4.0", + "workbox-google-analytics": "7.4.0", + "workbox-navigation-preload": "7.4.0", + "workbox-precaching": "7.4.0", + "workbox-range-requests": "7.4.0", + "workbox-recipes": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0", + "workbox-streams": "7.4.0", + "workbox-sw": "7.4.0", + "workbox-window": "7.4.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmmirror.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/workbox-build/node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/workbox-build/node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmmirror.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" }, "peerDependenciesMeta": { - "vite": { + "@types/babel__core": { "optional": true } } }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", + "node_modules/workbox-build/node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/workbox-build/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, "license": "MIT", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, "engines": { - "node": ">= 8" + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" } }, - "node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "node_modules/workbox-build/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true, - "license": "BSD-2-Clause" + "license": "MIT" }, - "node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/which": { - "version": "2.0.2", - "license": "ISC", + "node_modules/workbox-build/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true, + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/workbox-build/node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmmirror.com/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" }, "bin": { - "node-which": "bin/node-which" + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/workbox-build/node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/workbox-build/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/workbox-build/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">= 8" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/which-boxed-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "node_modules/workbox-build/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", - "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" + "engines": { + "node": ">=8.6" }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/workbox-build/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmmirror.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "node_modules/workbox-build/node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">= 0.4" + "node": ">=10.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/which-builtin-type/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "node_modules/workbox-cacheable-response": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-cacheable-response/-/workbox-cacheable-response-7.4.0.tgz", + "integrity": "sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0" + } + }, + "node_modules/workbox-core": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-core/-/workbox-core-7.4.0.tgz", + "integrity": "sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==", "dev": true, "license": "MIT" }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "node_modules/workbox-expiration": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-expiration/-/workbox-expiration-7.4.0.tgz", + "integrity": "sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==", "dev": true, "license": "MIT", "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "idb": "^7.0.1", + "workbox-core": "7.4.0" } }, - "node_modules/which-module": { - "version": "2.0.1", - "license": "ISC" - }, - "node_modules/which-typed-array": { - "version": "1.1.20", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", - "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "node_modules/workbox-google-analytics": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-google-analytics/-/workbox-google-analytics-7.4.0.tgz", + "integrity": "sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==", "dev": true, "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "workbox-background-sync": "7.4.0", + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" } }, - "node_modules/workbox-background-sync": { + "node_modules/workbox-navigation-preload": { "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.4.0.tgz", - "integrity": "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==", + "resolved": "https://registry.npmmirror.com/workbox-navigation-preload/-/workbox-navigation-preload-7.4.0.tgz", + "integrity": "sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==", "dev": true, "license": "MIT", "dependencies": { - "idb": "^7.0.1", "workbox-core": "7.4.0" } }, - "node_modules/workbox-broadcast-update": { + "node_modules/workbox-precaching": { "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.4.0.tgz", - "integrity": "sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==", + "resolved": "https://registry.npmmirror.com/workbox-precaching/-/workbox-precaching-7.4.0.tgz", + "integrity": "sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-range-requests/-/workbox-range-requests-7.4.0.tgz", + "integrity": "sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==", "dev": true, "license": "MIT", "dependencies": { "workbox-core": "7.4.0" } }, - "node_modules/workbox-build": { + "node_modules/workbox-recipes": { "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.4.0.tgz", - "integrity": "sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==", + "resolved": "https://registry.npmmirror.com/workbox-recipes/-/workbox-recipes-7.4.0.tgz", + "integrity": "sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==", "dev": true, "license": "MIT", "dependencies": { - "@apideck/better-ajv-errors": "^0.3.1", - "@babel/core": "^7.24.4", - "@babel/preset-env": "^7.11.0", - "@babel/runtime": "^7.11.2", - "@rollup/plugin-babel": "^5.2.0", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-replace": "^2.4.1", - "@rollup/plugin-terser": "^0.4.3", - "@surma/rollup-plugin-off-main-thread": "^2.2.3", - "ajv": "^8.6.0", - "common-tags": "^1.8.0", - "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^9.0.1", - "glob": "^11.0.1", - "lodash": "^4.17.20", - "pretty-bytes": "^5.3.0", - "rollup": "^2.79.2", - "source-map": "^0.8.0-beta.0", - "stringify-object": "^3.3.0", - "strip-comments": "^2.0.1", - "tempy": "^0.6.0", - "upath": "^1.2.0", - "workbox-background-sync": "7.4.0", - "workbox-broadcast-update": "7.4.0", "workbox-cacheable-response": "7.4.0", "workbox-core": "7.4.0", "workbox-expiration": "7.4.0", - "workbox-google-analytics": "7.4.0", - "workbox-navigation-preload": "7.4.0", "workbox-precaching": "7.4.0", - "workbox-range-requests": "7.4.0", - "workbox-recipes": "7.4.0", "workbox-routing": "7.4.0", - "workbox-strategies": "7.4.0", - "workbox-streams": "7.4.0", - "workbox-sw": "7.4.0", - "workbox-window": "7.4.0" - }, - "engines": { - "node": ">=20.0.0" + "workbox-strategies": "7.4.0" } }, - "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", - "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "node_modules/workbox-routing": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-routing/-/workbox-routing-7.4.0.tgz", + "integrity": "sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==", "dev": true, "license": "MIT", "dependencies": { - "json-schema": "^0.4.0", - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "ajv": ">=8" + "workbox-core": "7.4.0" } }, - "node_modules/workbox-build/node_modules/@isaacs/cliui": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", - "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "node_modules/workbox-strategies": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-strategies/-/workbox-strategies-7.4.0.tgz", + "integrity": "sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==", "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0" } }, - "node_modules/workbox-build/node_modules/@rollup/plugin-babel": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", - "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "node_modules/workbox-streams": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-streams/-/workbox-streams-7.4.0.tgz", + "integrity": "sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.10.4", - "@rollup/pluginutils": "^3.1.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "@types/babel__core": "^7.1.9", - "rollup": "^1.20.0||^2.0.0" - }, - "peerDependenciesMeta": { - "@types/babel__core": { - "optional": true - } + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0" } }, - "node_modules/workbox-build/node_modules/@rollup/plugin-replace": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", - "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "node_modules/workbox-sw": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-sw/-/workbox-sw-7.4.0.tgz", + "integrity": "sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==", + "dev": true, + "license": "MIT" + }, + "node_modules/workbox-window": { + "version": "7.4.0", + "resolved": "https://registry.npmmirror.com/workbox-window/-/workbox-window-7.4.0.tgz", + "integrity": "sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==", "dev": true, "license": "MIT", "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" + "@types/trusted-types": "^2.0.2", + "workbox-core": "7.4.0" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/workbox-build/node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", "license": "MIT", "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 8.0.0" + "node": ">=8" }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/workbox-build/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", "license": "MIT" }, - "node_modules/workbox-build/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", "license": "MIT", - "peer": true, "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">=8" } }, - "node_modules/workbox-build/node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true, - "license": "MIT" - }, - "node_modules/workbox-build/node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/workbox-build/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/workbox-build/node_modules/glob": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", - "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.19.0", "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "foreground-child": "^3.3.1", - "jackspeak": "^4.1.1", - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" + "license": "MIT", + "engines": { + "node": ">=10.0.0" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=18" } }, - "node_modules/workbox-build/node_modules/jackspeak": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", - "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "node_modules/xmlbuilder": { + "version": "15.1.1", "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^9.0.0" - }, + "license": "MIT", "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8.0" } }, - "node_modules/workbox-build/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "node_modules/xmlchars": { + "version": "2.2.0", "dev": true, "license": "MIT" }, - "node_modules/workbox-build/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", - "dev": true, + "node_modules/xtend": { + "version": "4.0.2", "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">=0.4" } }, - "node_modules/workbox-build/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "node_modules/yallist": { + "version": "5.0.0", "dev": true, "license": "BlueOak-1.0.0", "engines": { - "node": "20 || >=22" + "node": ">=18" } }, - "node_modules/workbox-build/node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", "license": "MIT", "dependencies": { - "sourcemap-codec": "^1.4.8" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" } }, - "node_modules/workbox-build/node_modules/minimatch": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", - "integrity": "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.1" - }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "license": "MIT", "engines": { - "node": "20 || >=22" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/workbox-build/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, + "node_modules/zod": { + "version": "3.25.76", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" + "peerDependencies": { + "zod": "^3.25 || ^4" } }, - "node_modules/workbox-build/node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", - "dev": true, - "license": "BlueOak-1.0.0", + "node_modules/zwitch": { + "version": "2.0.4", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "packages/electron-app": { + "name": "@neuralnomads/codenomad-electron-app", + "version": "0.9.2-patch.5", + "license": "MIT", "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" + "@codenomad/mcp-server": "file:../mcp-server", + "@codenomad/ui": "file:../ui", + "@develar/schema-utils": "^2.6.5", + "@fastify/reply-from": "12.5.0", + "@neuralnomads/codenomad": "file:../server", + "@types/dompurify": "^3.0.5", + "dompurify": "^3.3.1", + "dotenv": "^9.0.2", + "sax": "^1.4.4", + "ts-node": "1.7.1", + "yaml": "^2.4.2" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "devDependencies": { + "7zip-bin": "^5.2.0", + "app-builder-bin": "^4.2.0", + "electron": "39.0.0", + "electron-builder": "^26.4.0", + "electron-vite": "4.0.1", + "png2icons": "^2.0.1", + "pngjs": "^7.0.0", + "tsx": "^4.20.6", + "typescript": "^5.3.0", + "vite": "^7.3.1", + "vite-plugin-solid": "^2.10.0" } }, - "node_modules/workbox-build/node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, + "packages/electron-app/node_modules/@fastify/error": { + "version": "4.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "packages/electron-app/node_modules/@fastify/reply-from": { + "version": "12.5.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/error": "^4.0.0", + "end-of-stream": "^1.4.4", + "fast-content-type-parse": "^3.0.0", + "fast-querystring": "^1.1.2", + "fastify-plugin": "^5.0.1", + "toad-cache": "^3.7.0", + "undici": "^7.0.0" + } + }, + "packages/electron-app/node_modules/ansi-regex": { + "version": "2.1.1", "license": "MIT", "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/workbox-build/node_modules/rollup": { - "version": "2.79.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", - "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", - "dev": true, + "packages/electron-app/node_modules/ansi-styles": { + "version": "2.2.1", "license": "MIT", - "peer": true, - "bin": { - "rollup": "dist/bin/rollup" - }, "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "node": ">=0.10.0" } }, - "node_modules/workbox-build/node_modules/source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "deprecated": "The work that was done in this beta branch won't be included in future versions", + "packages/electron-app/node_modules/app-builder-bin": { + "version": "4.2.0", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT" + }, + "packages/electron-app/node_modules/chalk": { + "version": "1.1.3", + "license": "MIT", "dependencies": { - "whatwg-url": "^7.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" }, "engines": { - "node": ">= 8" + "node": ">=0.10.0" } }, - "node_modules/workbox-build/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, + "packages/electron-app/node_modules/escape-string-regexp": { + "version": "1.0.5", "license": "MIT", "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/workbox-cacheable-response": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.4.0.tgz", - "integrity": "sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-core": "7.4.0" + "node": ">=0.8.0" } }, - "node_modules/workbox-core": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.4.0.tgz", - "integrity": "sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==", - "dev": true, + "packages/electron-app/node_modules/fast-content-type-parse": { + "version": "3.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "license": "MIT" }, - "node_modules/workbox-expiration": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.4.0.tgz", - "integrity": "sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "idb": "^7.0.1", - "workbox-core": "7.4.0" - } + "packages/electron-app/node_modules/fastify-plugin": { + "version": "5.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" }, - "node_modules/workbox-google-analytics": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.4.0.tgz", - "integrity": "sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==", - "dev": true, + "packages/electron-app/node_modules/mkdirp": { + "version": "0.5.6", "license": "MIT", "dependencies": { - "workbox-background-sync": "7.4.0", - "workbox-core": "7.4.0", - "workbox-routing": "7.4.0", - "workbox-strategies": "7.4.0" + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, - "node_modules/workbox-navigation-preload": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.4.0.tgz", - "integrity": "sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-core": "7.4.0" + "packages/electron-app/node_modules/source-map": { + "version": "0.5.7", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/workbox-precaching": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.4.0.tgz", - "integrity": "sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==", - "dev": true, + "packages/electron-app/node_modules/source-map-support": { + "version": "0.4.18", "license": "MIT", "dependencies": { - "workbox-core": "7.4.0", - "workbox-routing": "7.4.0", - "workbox-strategies": "7.4.0" + "source-map": "^0.5.6" } }, - "node_modules/workbox-range-requests": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.4.0.tgz", - "integrity": "sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==", - "dev": true, + "packages/electron-app/node_modules/strip-ansi": { + "version": "3.0.1", "license": "MIT", "dependencies": { - "workbox-core": "7.4.0" + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/workbox-recipes": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.4.0.tgz", - "integrity": "sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==", - "dev": true, + "packages/electron-app/node_modules/supports-color": { + "version": "2.0.0", "license": "MIT", - "dependencies": { - "workbox-cacheable-response": "7.4.0", - "workbox-core": "7.4.0", - "workbox-expiration": "7.4.0", - "workbox-precaching": "7.4.0", - "workbox-routing": "7.4.0", - "workbox-strategies": "7.4.0" + "engines": { + "node": ">=0.8.0" } }, - "node_modules/workbox-routing": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.4.0.tgz", - "integrity": "sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==", - "dev": true, + "packages/electron-app/node_modules/ts-node": { + "version": "1.7.1", "license": "MIT", "dependencies": { - "workbox-core": "7.4.0" + "arrify": "^1.0.0", + "chalk": "^1.1.1", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "pinkie": "^2.0.4", + "source-map-support": "^0.4.0", + "tsconfig": "^5.0.2", + "v8flags": "^2.0.11", + "xtend": "^4.0.0", + "yn": "^1.2.0" + }, + "bin": { + "ts-node": "dist/bin.js" } }, - "node_modules/workbox-strategies": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.4.0.tgz", - "integrity": "sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==", - "dev": true, + "packages/electron-app/node_modules/undici": { + "version": "7.19.1", "license": "MIT", - "dependencies": { - "workbox-core": "7.4.0" + "engines": { + "node": ">=20.18.1" } }, - "node_modules/workbox-streams": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.4.0.tgz", - "integrity": "sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==", - "dev": true, + "packages/electron-app/node_modules/yn": { + "version": "1.3.0", "license": "MIT", "dependencies": { - "workbox-core": "7.4.0", - "workbox-routing": "7.4.0" + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/workbox-sw": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.4.0.tgz", - "integrity": "sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==", - "dev": true, - "license": "MIT" - }, - "node_modules/workbox-window": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.4.0.tgz", - "integrity": "sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==", - "dev": true, - "license": "MIT", + "packages/mcp-server": { + "name": "@codenomad/mcp-server", + "version": "0.9.2-patch.5", "dependencies": { - "@types/trusted-types": "^2.0.2", - "workbox-core": "7.4.0" + "zod": "^3.25.76" + }, + "devDependencies": { + "typescript": "^5.3.0" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "dev": true, - "license": "MIT", + "packages/server": { + "name": "@neuralnomads/codenomad", + "version": "0.9.2-patch.5", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "@fastify/cors": "^8.5.0", + "@fastify/reply-from": "^9.8.0", + "@fastify/static": "^7.0.4", + "@modelcontextprotocol/sdk": "^1.25.2", + "commander": "^12.1.0", + "fastify": "^4.28.1", + "fuzzysort": "^2.0.4", + "pino": "^9.4.0", + "undici": "^6.19.8", + "yauzl": "^2.10.0", + "zod": "^3.23.8" }, - "engines": { - "node": ">=10" + "bin": { + "codenomad": "dist/bin.js" }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "devDependencies": { + "@types/yauzl": "^2.10.0", + "cross-env": "^7.0.3", + "esbuild": "^0.25.12", + "ts-node": "^1.7.1", + "tsx": "^4.20.6", + "typescript": "^5.6.3" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", + "packages/server/node_modules/@fastify/reply-from": { + "version": "9.8.0", "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "@fastify/error": "^3.0.0", + "end-of-stream": "^1.4.4", + "fast-content-type-parse": "^1.1.0", + "fast-querystring": "^1.0.0", + "fastify-plugin": "^4.0.0", + "toad-cache": "^3.7.0", + "undici": "^5.19.1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "license": "ISC" + "packages/server/node_modules/@fastify/reply-from/node_modules/@fastify/error": { + "version": "3.4.1", + "license": "MIT" }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "dev": true, + "packages/server/node_modules/@fastify/reply-from/node_modules/fast-content-type-parse": { + "version": "1.1.0", + "license": "MIT" + }, + "packages/server/node_modules/@fastify/reply-from/node_modules/fastify-plugin": { + "version": "4.5.1", + "license": "MIT" + }, + "packages/server/node_modules/@fastify/reply-from/node_modules/undici": { + "version": "5.29.0", "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, "engines": { - "node": ">=8.0" + "node": ">=14.0" } }, - "node_modules/y18n": { - "version": "5.0.8", + "packages/server/node_modules/ansi-regex": { + "version": "2.1.1", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, - "node_modules/yargs": { - "version": "17.7.2", + "packages/server/node_modules/ansi-styles": { + "version": "2.2.1", "dev": true, "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, "engines": { - "node": ">=12" + "node": ">=0.10.0" } }, - "node_modules/yargs-parser": { - "version": "21.1.1", + "packages/server/node_modules/chalk": { + "version": "1.1.3", "dev": true, - "license": "ISC", + "license": "MIT", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, "engines": { - "node": ">=12" + "node": ">=0.10.0" } }, - "node_modules/yauzl": { - "version": "2.10.0", + "packages/server/node_modules/commander": { + "version": "12.1.0", "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "engines": { + "node": ">=18" } }, - "node_modules/yn": { - "version": "3.1.1", + "packages/server/node_modules/diff": { + "version": "3.5.0", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=0.3.1" } }, - "node_modules/zip-stream": { - "version": "4.1.1", + "packages/server/node_modules/escape-string-regexp": { + "version": "1.0.5", "dev": true, "license": "MIT", - "dependencies": { - "archiver-utils": "^3.0.4", - "compress-commons": "^4.1.2", - "readable-stream": "^3.6.0" - }, "engines": { - "node": ">= 10" + "node": ">=0.8.0" } }, - "node_modules/zip-stream/node_modules/archiver-utils": { - "version": "3.0.4", + "packages/server/node_modules/fuzzysort": { + "version": "2.0.4", + "license": "MIT" + }, + "packages/server/node_modules/mkdirp": { + "version": "0.5.6", "dev": true, "license": "MIT", "dependencies": { - "glob": "^7.2.3", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "minimist": "^1.2.6" }, - "engines": { - "node": ">= 10" + "bin": { + "mkdirp": "bin/cmd.js" } }, - "node_modules/zod": { - "version": "3.25.76", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" + "packages/server/node_modules/source-map": { + "version": "0.5.7", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/zwitch": { - "version": "2.0.4", + "packages/server/node_modules/source-map-support": { + "version": "0.4.18", + "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "dependencies": { + "source-map": "^0.5.6" } }, - "packages/electron-app": { - "name": "@neuralnomads/codenomad-electron-app", - "version": "0.9.5", + "packages/server/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, "license": "MIT", "dependencies": { - "@codenomad/ui": "file:../ui", - "@neuralnomads/codenomad": "file:../server" + "ansi-regex": "^2.0.0" }, - "devDependencies": { - "7zip-bin": "^5.2.0", - "app-builder-bin": "^4.2.0", - "electron": "39.0.0", - "electron-builder": "^24.0.0", - "electron-vite": "4.0.1", - "png2icons": "^2.0.1", - "pngjs": "^7.0.0", - "tsx": "^4.20.6", - "typescript": "^5.3.0", - "vite": "^5.0.0", - "vite-plugin-solid": "^2.10.0" + "engines": { + "node": ">=0.10.0" } }, - "packages/electron-app/node_modules/app-builder-bin": { - "version": "4.2.0", + "packages/server/node_modules/supports-color": { + "version": "2.0.0", "dev": true, - "license": "MIT" - }, - "packages/opencode-config": { - "name": "@codenomad/opencode-config", - "version": "0.5.0", - "extraneous": true, - "dependencies": { - "@opencode-ai/plugin": "1.1.1" + "license": "MIT", + "engines": { + "node": ">=0.8.0" } }, - "packages/server": { - "name": "@neuralnomads/codenomad", - "version": "0.9.5", + "packages/server/node_modules/ts-node": { + "version": "1.7.3", + "dev": true, "license": "MIT", "dependencies": { - "@fastify/cors": "^8.5.0", - "@fastify/reply-from": "^9.8.0", - "@fastify/static": "^7.0.4", - "commander": "^12.1.0", - "fastify": "^4.28.1", - "fuzzysort": "^2.0.4", - "pino": "^9.4.0", - "undici": "^6.19.8", - "yauzl": "^2.10.0", - "zod": "^3.23.8" + "arrify": "^1.0.0", + "chalk": "^1.1.1", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "pinkie": "^2.0.4", + "source-map-support": "^0.4.0", + "tsconfig": "^5.0.2", + "v8flags": "^2.0.11", + "xtend": "^4.0.0", + "yn": "^1.2.0" }, "bin": { - "codenomad": "dist/bin.js" - }, - "devDependencies": { - "@types/yauzl": "^2.10.0", - "cross-env": "^7.0.3", - "ts-node": "^10.9.2", - "tsx": "^4.20.6", - "typescript": "^5.6.3" + "ts-node": "dist/bin.js" } }, - "packages/server/node_modules/commander": { - "version": "12.1.0", + "packages/server/node_modules/yn": { + "version": "1.3.0", + "dev": true, "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1" + }, "engines": { - "node": ">=18" + "node": ">=0.10.0" } }, - "packages/server/node_modules/fuzzysort": { - "version": "2.0.4", - "license": "MIT" - }, "packages/tauri-app": { "name": "@codenomad/tauri-app", - "version": "0.9.5", + "version": "0.9.2-patch.5", "license": "MIT", "devDependencies": { "@tauri-apps/cli": "^2.9.4" @@ -12009,9 +15713,10 @@ }, "packages/ui": { "name": "@codenomad/ui", - "version": "0.9.5", + "version": "0.9.2-patch.5", "license": "MIT", "dependencies": { + "@fastify/reply-from": "12.5.0", "@git-diff-view/solid": "^0.0.8", "@kobalte/core": "0.13.11", "@opencode-ai/sdk": "1.1.11", @@ -12019,26 +15724,212 @@ "@suid/icons-material": "^0.9.0", "@suid/material": "^0.19.0", "@suid/system": "^0.14.0", + "@tauri-apps/plugin-notification": "^2.3.3", "@tauri-apps/plugin-opener": "^2.5.3", + "@types/dompurify": "^3.0.5", "ansi-sequence-parser": "^1.1.3", "debug": "^4.4.3", + "dompurify": "^3.3.1", "github-markdown-css": "^5.8.1", "lucide-solid": "^0.300.0", "marked": "^12.0.0", + "monaco-editor": "^0.52.2", "qrcode": "^1.5.3", "shiki": "^3.13.0", "solid-js": "^1.8.0", - "solid-toast": "^0.5.0" + "solid-toast": "^0.5.0", + "tauri-plugin-keepawake-api": "^0.1.0", + "ts-node": "1.7.1" }, "devDependencies": { "@vite-pwa/assets-generator": "^1.0.2", "autoprefixer": "10.4.21", + "jsdom": "^25.0.1", "postcss": "8.5.6", "tailwindcss": "3", "typescript": "^5.3.0", - "vite": "^5.0.0", + "vite": "^7.3.1", "vite-plugin-pwa": "^1.2.0", - "vite-plugin-solid": "^2.10.0" + "vite-plugin-solid": "^2.10.0", + "vitest": "^2.1.9" + } + }, + "packages/ui/node_modules/@fastify/error": { + "version": "4.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "packages/ui/node_modules/@fastify/reply-from": { + "version": "12.5.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/error": "^4.0.0", + "end-of-stream": "^1.4.4", + "fast-content-type-parse": "^3.0.0", + "fast-querystring": "^1.1.2", + "fastify-plugin": "^5.0.1", + "toad-cache": "^3.7.0", + "undici": "^7.0.0" + } + }, + "packages/ui/node_modules/ansi-regex": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "packages/ui/node_modules/ansi-styles": { + "version": "2.2.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "packages/ui/node_modules/chalk": { + "version": "1.1.3", + "license": "MIT", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "packages/ui/node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "packages/ui/node_modules/fast-content-type-parse": { + "version": "3.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "packages/ui/node_modules/fastify-plugin": { + "version": "5.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "packages/ui/node_modules/mkdirp": { + "version": "0.5.6", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "packages/ui/node_modules/source-map": { + "version": "0.5.7", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "packages/ui/node_modules/source-map-support": { + "version": "0.4.18", + "license": "MIT", + "dependencies": { + "source-map": "^0.5.6" + } + }, + "packages/ui/node_modules/strip-ansi": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "packages/ui/node_modules/supports-color": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "packages/ui/node_modules/ts-node": { + "version": "1.7.1", + "license": "MIT", + "dependencies": { + "arrify": "^1.0.0", + "chalk": "^1.1.1", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "pinkie": "^2.0.4", + "source-map-support": "^0.4.0", + "tsconfig": "^5.0.2", + "v8flags": "^2.0.11", + "xtend": "^4.0.0", + "yn": "^1.2.0" + }, + "bin": { + "ts-node": "dist/bin.js" + } + }, + "packages/ui/node_modules/undici": { + "version": "7.19.1", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "packages/ui/node_modules/yn": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" } } } diff --git a/package.json b/package.json index f6741af7..4eedb97a 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "codenomad-workspace", - "version": "0.9.5", + "version": "0.10.3", "private": true, "description": "CodeNomad monorepo workspace", - "license": "MIT", "workspaces": { "packages": [ + "packages/mcp-server", "packages/server", "packages/ui", "packages/electron-app", @@ -22,6 +22,8 @@ "build:mac-x64": "npm run build:mac-x64 --workspace @neuralnomads/codenomad-electron-app", "build:binaries": "npm run build:binaries --workspace @neuralnomads/codenomad-electron-app", "typecheck": "npm run typecheck --workspace @codenomad/ui && npm run typecheck --workspace @neuralnomads/codenomad-electron-app", + "lint": "eslint \"packages/ui/src/**/*.{ts,tsx}\" \"packages/electron-app/electron/**/*.{ts,tsx}\"", + "lint:fix": "npm run lint -- --fix", "bumpVersion": "npm version --workspaces --include-workspace-root --no-git-tag-version" }, "dependencies": { @@ -29,6 +31,12 @@ "google-auth-library": "^10.5.0" }, "devDependencies": { - "baseline-browser-mapping": "^2.9.11" + "@eslint/js": "^9.39.2", + "baseline-browser-mapping": "^2.9.11", + "eslint": "^9.39.2", + "eslint-plugin-solid": "^0.14.5", + "globals": "^17.3.0", + "typescript": "^5.9.3", + "typescript-eslint": "^8.54.0" } } diff --git a/packages/cloudflare/release-config.json b/packages/cloudflare/release-config.json index 95b1c661..5cae1b9d 100644 --- a/packages/cloudflare/release-config.json +++ b/packages/cloudflare/release-config.json @@ -1,4 +1,4 @@ { - "minServerVersion": "0.9.2", + "minServerVersion": "0.10.3", "latestServerUrl": "https://github.com/NeuralNomadsAI/CodeNomad/releases/latest" } diff --git a/packages/electron-app/.gitignore b/packages/electron-app/.gitignore index 2dfa475b..ed86b9a6 100644 --- a/packages/electron-app/.gitignore +++ b/packages/electron-app/.gitignore @@ -1,4 +1,5 @@ node_modules/ dist/ release/ +resources/ .vite/ diff --git a/packages/electron-app/electron.vite.config.ts b/packages/electron-app/electron.vite.config.ts index 1161176a..b4b49b15 100644 --- a/packages/electron-app/electron.vite.config.ts +++ b/packages/electron-app/electron.vite.config.ts @@ -1,6 +1,7 @@ import { defineConfig, externalizeDepsPlugin } from "electron-vite" import solid from "vite-plugin-solid" import { resolve } from "path" +import { copyMonacoPublicAssets } from "../ui/scripts/monaco-public-assets.js" const uiRoot = resolve(__dirname, "../ui") const uiSrc = resolve(uiRoot, "src") @@ -8,9 +9,41 @@ const uiRendererRoot = resolve(uiRoot, "src/renderer") const uiRendererEntry = resolve(uiRendererRoot, "index.html") const uiRendererLoadingEntry = resolve(uiRendererRoot, "loading.html") +function prepareMonacoPublicAssets() { + return { + name: "prepare-monaco-public-assets", + configureServer(server: any) { + copyMonacoPublicAssets({ + uiRendererRoot: uiRendererRoot, + warn: (msg: string) => server.config.logger.warn(msg), + sourceRoots: [ + resolve(__dirname, "../../node_modules/monaco-editor/min/vs"), + resolve(uiRoot, "node_modules/monaco-editor/min/vs"), + ], + }) + }, + buildStart(this: any) { + copyMonacoPublicAssets({ + uiRendererRoot: uiRendererRoot, + warn: (msg: string) => this.warn(msg), + sourceRoots: [ + resolve(__dirname, "../../node_modules/monaco-editor/min/vs"), + resolve(uiRoot, "node_modules/monaco-editor/min/vs"), + ], + }) + }, + } +} + export default defineConfig({ main: { - plugins: [externalizeDepsPlugin()], + plugins: [externalizeDepsPlugin({ exclude: ["@codenomad/mcp-server"] })], + resolve: { + alias: { + "@codenomad/mcp-server/src": resolve(__dirname, "../mcp-server/src"), + "@codenomad/mcp-server": resolve(__dirname, "../mcp-server/src/server.ts"), + }, + }, build: { outDir: "dist/main", lib: { @@ -40,7 +73,7 @@ export default defineConfig({ }, renderer: { root: uiRendererRoot, - plugins: [solid()], + plugins: [solid(), prepareMonacoPublicAssets()], css: { postcss: resolve(uiRoot, "postcss.config.js"), }, diff --git a/packages/electron-app/electron/main/ipc.ts b/packages/electron-app/electron/main/ipc.ts index 26f6499e..7c4433b1 100644 --- a/packages/electron-app/electron/main/ipc.ts +++ b/packages/electron-app/electron/main/ipc.ts @@ -1,6 +1,8 @@ -import { BrowserWindow, dialog, ipcMain, type OpenDialogOptions } from "electron" +import { BrowserWindow, dialog, ipcMain, powerSaveBlocker, type OpenDialogOptions } from "electron" import type { CliProcessManager, CliStatus } from "./process-manager" +let wakeLockId: number | null = null + interface DialogOpenRequest { mode: "directory" | "file" title?: string @@ -14,23 +16,34 @@ interface DialogOpenResult { } export function setupCliIPC(mainWindow: BrowserWindow, cliManager: CliProcessManager) { - cliManager.on("status", (status: CliStatus) => { + // Define listeners + const onStatus = (status: CliStatus) => { if (!mainWindow.isDestroyed()) { mainWindow.webContents.send("cli:status", status) } - }) + } - cliManager.on("ready", (status: CliStatus) => { + const onReady = (status: CliStatus) => { if (!mainWindow.isDestroyed()) { mainWindow.webContents.send("cli:ready", status) } - }) + } - cliManager.on("error", (error: Error) => { + const onError = (error: Error) => { if (!mainWindow.isDestroyed()) { mainWindow.webContents.send("cli:error", { message: error.message }) } - }) + } + + // Register listeners + cliManager.on("status", onStatus) + cliManager.on("ready", onReady) + cliManager.on("error", onError) + + // Clean up existing handlers if any (though usually we clean up on window close) + ipcMain.removeHandler("cli:getStatus") + ipcMain.removeHandler("cli:restart") + ipcMain.removeHandler("dialog:open") ipcMain.handle("cli:getStatus", async () => cliManager.getStatus()) @@ -62,4 +75,31 @@ export function setupCliIPC(mainWindow: BrowserWindow, cliManager: CliProcessMan return { canceled: result.canceled, paths: result.filePaths } }) + + ipcMain.handle("power:setWakeLock", async (_, enabled: boolean) => { + if (enabled) { + if (wakeLockId === null) { + wakeLockId = powerSaveBlocker.start("prevent-app-suspension") + } + } else { + if (wakeLockId !== null) { + powerSaveBlocker.stop(wakeLockId) + wakeLockId = null + } + } + return { enabled: wakeLockId !== null } + }) + + // Return cleanup function + return () => { + cliManager.removeListener("status", onStatus) + cliManager.removeListener("ready", onReady) + cliManager.removeListener("error", onError) + + ipcMain.removeHandler("cli:getStatus") + ipcMain.removeHandler("cli:restart") + ipcMain.removeHandler("dialog:open") + ipcMain.removeHandler("power:setWakeLock") + } } + diff --git a/packages/electron-app/electron/main/main.ts b/packages/electron-app/electron/main/main.ts index 071c5620..1016a920 100644 --- a/packages/electron-app/electron/main/main.ts +++ b/packages/electron-app/electron/main/main.ts @@ -1,17 +1,27 @@ -import { app, BrowserView, BrowserWindow, nativeImage, session, shell } from "electron" +import { app, BrowserWindow, WebContentsView, nativeImage, session, shell } from "electron" import http from "node:http" import https from "node:https" +import { randomUUID } from "node:crypto" import { existsSync } from "fs" import { dirname, join } from "path" import { fileURLToPath } from "url" import { createApplicationMenu } from "./menu" import { setupCliIPC } from "./ipc" import { CliProcessManager } from "./process-manager" +import { CodeNomadMcpServer } from "@codenomad/mcp-server" +import { setupMcpBridge, connectMcpBridge, shutdownBridge } from "@codenomad/mcp-server/src/bridge/ipc" +import { + cleanupLegacyAntigravityRegistration, + cleanupStaleInstances, + writeMcpConfig, + unregisterFromMcpConfig, +} from "@codenomad/mcp-server/src/config/registration" const mainFilename = fileURLToPath(import.meta.url) const mainDirname = dirname(mainFilename) const isMac = process.platform === "darwin" +const SESSION_PARTITION = "persist:codenomad" const cliManager = new CliProcessManager() let mainWindow: BrowserWindow | null = null @@ -19,7 +29,35 @@ let currentCliUrl: string | null = null let pendingCliUrl: string | null = null let pendingBootstrapToken: string | null = null let showingLoadingScreen = false -let preloadingView: BrowserView | null = null +let preloadingView: WebContentsView | null = null +let mcpServer: CodeNomadMcpServer | null = null +let mcpInstanceId: string | null = null + +type McpLogLevel = "info" | "warn" | "error" + +/** + * Safely send message to window webContents with proper destruction checks. + * Prevents "Object has been destroyed" errors during app shutdown. + */ +function safeWebContentsSend(window: BrowserWindow | null, channel: string, ...args: unknown[]) { + if (!window || window.isDestroyed()) { + return false + } + if (window.webContents.isDestroyed()) { + return false + } + try { + window.webContents.send(channel, ...args) + return true + } catch (error) { + console.warn(`[safe-send] Failed to send to ${channel}:`, error) + return false + } +} + +function emitMcpLog(level: McpLogLevel, message: string, data?: unknown) { + safeWebContentsSend(mainWindow, "mcp:log", { level, message, data }) +} if (isMac) { app.commandLine.appendSwitch("disable-spell-checking") @@ -168,15 +206,19 @@ function getPreloadPath() { return join(mainDirname, "../preload/index.js") } -function destroyPreloadingView(target?: BrowserView | null) { +function destroyPreloadingView(target?: WebContentsView | null) { const view = target ?? preloadingView if (!view) { return } try { - const contents = view.webContents as any - contents?.destroy?.() + // WebContentsView: access webContents directly + const contents = view.webContents + if (contents && !contents.isDestroyed()) { + contents.closeDevTools() + contents.stop() + } } catch (error) { console.warn("[cli] failed to destroy preloading view", error) } @@ -203,6 +245,7 @@ function createWindow() { contextIsolation: true, nodeIntegration: false, spellcheck: !isMac, + partition: SESSION_PARTITION, }, }) @@ -221,9 +264,10 @@ function createWindow() { } createApplicationMenu(mainWindow) - setupCliIPC(mainWindow, cliManager) + const cleanupIPC = setupCliIPC(mainWindow, cliManager) mainWindow.on("closed", () => { + cleanupIPC() destroyPreloadingView() mainWindow = null currentCliUrl = null @@ -287,17 +331,31 @@ function startCliPreload(url: string) { return } - const view = new BrowserView({ + if (process.env.NODE_ENV === "development") { + finalizeCliSwap(url) + return + } + + const view = new WebContentsView({ webPreferences: { contextIsolation: true, nodeIntegration: false, spellcheck: !isMac, + partition: SESSION_PARTITION, }, }) preloadingView = view - view.webContents.once("did-finish-load", () => { + // WebContentsView: access webContents directly (no deprecation) + const viewContents = view.webContents + if (!viewContents) { + console.error("[cli] failed to access WebContentsView webContents") + destroyPreloadingView(view) + return + } + + viewContents.once("did-finish-load", () => { if (preloadingView !== view) { destroyPreloadingView(view) return @@ -305,7 +363,7 @@ function startCliPreload(url: string) { finalizeCliSwap(url) }) - view.webContents.loadURL(url).catch((error) => { + viewContents.loadURL(url).catch((error: Error) => { console.error("[cli] failed to preload CLI view:", error) if (preloadingView === view) { destroyPreloadingView(view) @@ -324,6 +382,7 @@ function finalizeCliSwap(url: string) { showingLoadingScreen = false currentCliUrl = url pendingCliUrl = null + console.info("[cli] loading renderer from", url) mainWindow.loadURL(url).catch((error) => console.error("[cli] failed to load CLI view:", error)) } @@ -385,7 +444,7 @@ async function exchangeBootstrapToken(baseUrl: string, token: string): Promise { + // Don't process events if mainWindow is null (app is shutting down) + if (!mainWindow) { + return + } pendingBootstrapToken = token const status = cliManager.getStatus() @@ -453,6 +514,10 @@ cliManager.on("bootstrapToken", (token) => { }) cliManager.on("ready", (status) => { + // Don't process events if mainWindow is null (app is shutting down) + if (!mainWindow) { + return + } if (!status.url) { return } @@ -461,6 +526,10 @@ cliManager.on("ready", (status) => { }) cliManager.on("status", (status) => { + // Don't process events if mainWindow is null (app is shutting down) + if (!mainWindow) { + return + } if (status.state !== "ready") { showLoadingScreen() } @@ -472,9 +541,7 @@ if (isMac) { }) } -app.whenReady().then(() => { - startCli() - +app.whenReady().then(async () => { if (isMac) { session.defaultSession.setSpellCheckerEnabled(false) app.on("browser-window-created", (_, window) => { @@ -491,20 +558,127 @@ app.whenReady().then(() => { createWindow() + // Start MCP server FIRST if we have a main window + let mcpPort: number | undefined + if (mainWindow) { + try { + await setupMcpBridge(mainWindow) + console.log('[MCP] IPC bridge setup completed') + emitMcpLog("info", "IPC bridge setup completed") + console.log('[MCP] preload path:', getPreloadPath()) + emitMcpLog("info", "Preload path resolved", { preloadPath: getPreloadPath() }) + console.log('[MCP] app.isPackaged:', app.isPackaged) + emitMcpLog("info", "App packaging state", { isPackaged: app.isPackaged }) + console.log('[MCP] main window ids:', { + windowId: mainWindow.id, + webContentsId: mainWindow.webContents?.id, + }) + emitMcpLog("info", "Main window ids", { + windowId: mainWindow.id, + webContentsId: mainWindow.webContents?.id, + }) + } catch (err) { + console.error('[MCP] Failed to setup IPC bridge:', err) + emitMcpLog("error", "Failed to setup IPC bridge", err) + } + + const server = new CodeNomadMcpServer() + mcpServer = server + + try { + cleanupLegacyAntigravityRegistration() + await cleanupStaleInstances() + await mcpServer.start() + console.log('[MCP] Server start completed') + emitMcpLog("info", "MCP server start completed") + const port = mcpServer.getPort() + const token = mcpServer.getAuthToken() + + // Debug logging to identify why registration might fail + console.log(`[MCP] Debug - port: ${port}, token: ${token ? 'exists' : 'missing'}`) + emitMcpLog("info", "MCP server port/token", { port, token: token ? "exists" : "missing" }) + + if (port && token) { + mcpPort = port + mcpInstanceId = mcpInstanceId ?? randomUUID() + // Pass the correct path to the MCP server entry point + const mcpServerPath = join(app.getAppPath(), '../mcp-server/dist/server.js') + writeMcpConfig({ instanceId: mcpInstanceId, port, token, serverPath: mcpServerPath }) + console.log(`[MCP] Registered local instance ${mcpInstanceId} on port ${port}`) + emitMcpLog("info", "Registered local MCP instance", { instanceId: mcpInstanceId, port }) + } else { + console.error(`[MCP] Failed to register - port: ${port}, token: ${token}`) + emitMcpLog("warn", "Failed to register MCP config", { port, token: token ? "exists" : "missing" }) + } + + // Connect MCP server bridge regardless of registration outcome + if (mcpServer && mainWindow) { + try { + connectMcpBridge(mcpServer, mainWindow) + console.log('[MCP] Connected MCP server bridge to IPC') + emitMcpLog("info", "Connected MCP server bridge to IPC") + } catch (connectError) { + console.error('[MCP] Failed to connect MCP bridge:', connectError) + emitMcpLog("error", "Failed to connect MCP bridge", connectError) + } + } + } catch (error) { + console.error('[MCP] Failed to start server:', error) + emitMcpLog("error", "Failed to start MCP server", error) + } + } + + // Then start CLI with MCP port + await startCli(mcpPort) + app.on("activate", () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow() } }) -}) -app.on("before-quit", async (event) => { - event.preventDefault() - await cliManager.stop().catch(() => {}) - app.exit(0) -}) + app.on("before-quit", async (event) => { + event.preventDefault() + + // First: Signal MCP bridge to stop sending messages + // This must happen before any cleanup to prevent race conditions + shutdownBridge() + + // Second: Remove all IPC event listeners before nulling mainWindow + // This prevents any event handlers from trying to use the mainWindow reference + const windowToCleanup = mainWindow + + // Third: Clean up the IPC handlers + // The 'closed' event handler will call cleanupIPC(), but we need to ensure + // it happens before mainWindow is nulled out in case any events fire + if (windowToCleanup) { + // Remove all IPC listeners by triggering cleanup + // Note: The actual cleanupIPC function is called from the 'closed' event + } + + // Fourth: Now safe to null out mainWindow reference + mainWindow = null -app.on("window-all-closed", () => { - // CodeNomad supports a single window; closing it should quit the app on all platforms. - app.quit() + // Fifth: Unregister MCP server from CodeNomad-local per-instance config + if (mcpServer) { + if (mcpInstanceId) { + unregisterFromMcpConfig(mcpInstanceId) + } + await mcpServer.stop() + } + + await cliManager.stop().catch(() => { }) + + // Close window after cleanup to prevent webContents access during shutdown + if (windowToCleanup && !windowToCleanup.isDestroyed()) { + windowToCleanup.close() + } + + app.exit(0) + }) + + app.on("window-all-closed", () => { + // CodeNomad supports a single window; closing it should quit the app on all platforms. + app.quit() + }) }) diff --git a/packages/electron-app/electron/main/process-manager.ts b/packages/electron-app/electron/main/process-manager.ts index 76ae2271..67c3eb36 100644 --- a/packages/electron-app/electron/main/process-manager.ts +++ b/packages/electron-app/electron/main/process-manager.ts @@ -1,4 +1,4 @@ -import { spawn, spawnSync, type ChildProcess } from "child_process" +import { spawn, type ChildProcess } from "child_process" import { app } from "electron" import { createRequire } from "module" import { EventEmitter } from "events" @@ -29,6 +29,7 @@ export interface CliLogEntry { interface StartOptions { dev: boolean + mcpPort?: number } interface CliEntryResolution { @@ -82,7 +83,6 @@ export class CliProcessManager extends EventEmitter { private stdoutBuffer = "" private stderrBuffer = "" private bootstrapToken: string | null = null - private requestedStop = false async start(options: StartOptions): Promise { if (this.child) { @@ -92,7 +92,6 @@ export class CliProcessManager extends EventEmitter { this.stdoutBuffer = "" this.stderrBuffer = "" this.bootstrapToken = null - this.requestedStop = false this.updateStatus({ state: "starting", port: undefined, pid: undefined, url: undefined, error: undefined }) const cliEntry = this.resolveCliEntry(options) @@ -106,18 +105,40 @@ export class CliProcessManager extends EventEmitter { const env = supportsUserShell() ? getUserShellEnv() : { ...process.env } env.ELECTRON_RUN_AS_NODE = "1" + if (!options.dev) { + env.CODENOMAD_PACKAGED = "1" + } + + // Inject MCP configuration if port is provided + if (options.mcpPort) { + const mcpConfig = { + mcp: { + "codenomad": { + type: "remote", + url: `http://127.0.0.1:${options.mcpPort}`, + enabled: true + } + }, + permission: { + question: "deny" + }, + tools: { + question: false + } + } + env.OPENCODE_CONFIG_CONTENT = JSON.stringify(mcpConfig) + console.info(`[cli] injected MCP config for port ${options.mcpPort}`) + } const spawnDetails = supportsUserShell() ? buildUserShellCommand(`ELECTRON_RUN_AS_NODE=1 exec ${this.buildCommand(cliEntry, args)}`) : this.buildDirectSpawn(cliEntry, args) - const detached = process.platform !== "win32" const child = spawn(spawnDetails.command, spawnDetails.args, { cwd: process.cwd(), stdio: ["ignore", "pipe", "pipe"], env, shell: false, - detached, }) console.info(`[cli] spawn command: ${spawnDetails.command} ${spawnDetails.args.join(" ")}`) @@ -179,89 +200,12 @@ export class CliProcessManager extends EventEmitter { return } - this.requestedStop = true - - const pid = child.pid - if (!pid) { - this.child = undefined - this.updateStatus({ state: "stopped" }) - return - } - - const isAlreadyExited = () => child.exitCode !== null || child.signalCode !== null - - const tryKillPosixGroup = (signal: NodeJS.Signals) => { - try { - // Negative PID targets the process group (POSIX). - process.kill(-pid, signal) - return true - } catch (error) { - const err = error as NodeJS.ErrnoException - if (err?.code === "ESRCH") { - return true - } - return false - } - } - - const tryKillSinglePid = (signal: NodeJS.Signals) => { - try { - process.kill(pid, signal) - return true - } catch (error) { - const err = error as NodeJS.ErrnoException - if (err?.code === "ESRCH") { - return true - } - return false - } - } - - const tryTaskkill = (force: boolean) => { - const args = ["/PID", String(pid), "/T"] - if (force) { - args.push("/F") - } - - try { - const result = spawnSync("taskkill", args, { encoding: "utf8" }) - const exitCode = result.status - if (exitCode === 0) { - return true - } - - // If the PID is already gone, treat it as success. - const stderr = (result.stderr ?? "").toString().toLowerCase() - const stdout = (result.stdout ?? "").toString().toLowerCase() - const combined = `${stdout}\n${stderr}` - if (combined.includes("not found") || combined.includes("no running instance")) { - return true - } - return false - } catch { - return false - } - } - - const sendStopSignal = (signal: NodeJS.Signals) => { - if (process.platform === "win32") { - tryTaskkill(signal === "SIGKILL") - return - } - - // Prefer process-group signaling so wrapper launchers (shell/tsx) don't outlive Electron. - const groupOk = tryKillPosixGroup(signal) - if (!groupOk) { - tryKillSinglePid(signal) - } - } - return new Promise((resolve) => { const killTimeout = setTimeout(() => { console.warn( `[cli] stop timed out after 30000ms; sending SIGKILL (pid=${child.pid ?? "unknown"})`, ) - sendStopSignal("SIGKILL") + child.kill("SIGKILL") }, 30000) child.on("exit", () => { @@ -272,15 +216,7 @@ export class CliProcessManager extends EventEmitter { resolve() }) - if (isAlreadyExited()) { - clearTimeout(killTimeout) - this.child = undefined - this.updateStatus({ state: "stopped" }) - resolve() - return - } - - sendStopSignal("SIGTERM") + child.kill("SIGTERM") }) } @@ -294,16 +230,7 @@ export class CliProcessManager extends EventEmitter { private handleTimeout() { if (this.child) { - const pid = this.child.pid - if (pid && process.platform !== "win32") { - try { - process.kill(-pid, "SIGKILL") - } catch { - this.child.kill("SIGKILL") - } - } else { - this.child.kill("SIGKILL") - } + this.child.kill("SIGKILL") this.child = undefined } this.updateStatus({ state: "error", error: "CLI did not start in time" }) @@ -363,7 +290,17 @@ export class CliProcessManager extends EventEmitter { return parseInt(readyMatch[1], 10) } + const localUrlMatch = line.match(/Local Connection URL\s*:\s*https?:\/\/[^:]+:(\d{2,5})/i) + if (localUrlMatch) { + return parseInt(localUrlMatch[1], 10) + } + if (line.toLowerCase().includes("http server listening")) { + const keyValueMatch = line.match(/port\s*[=:]\s*(\d{2,5})/i) + if (keyValueMatch) { + return parseInt(keyValueMatch[1], 10) + } + const httpMatch = line.match(/:(\d{2,5})(?!.*:\d)/) if (httpMatch) { return parseInt(httpMatch[1], 10) @@ -387,10 +324,21 @@ export class CliProcessManager extends EventEmitter { } private buildCliArgs(options: StartOptions, host: string): string[] { - const args = ["serve", "--host", host, "--port", "0", "--generate-token"] + const args = [ + "--host", + host, + "--http", + "true", + "--https", + "false", + "--http-port", + "0", + "--generate-token", + ] if (options.dev) { - args.push("--ui-dev-server", "http://localhost:3000", "--log-level", "debug") + const devUrl = process.env.VITE_DEV_SERVER_URL || process.env.ELECTRON_RENDERER_URL || "http://localhost:3000" + args.push("--ui-dev-server", devUrl, "--log-level", "debug") } return args @@ -423,11 +371,11 @@ export class CliProcessManager extends EventEmitter { const devEntry = this.resolveDevEntry() return { entry: devEntry, runner: "tsx", runnerPath: tsxPath } } - + const distEntry = this.resolveProdEntry() return { entry: distEntry, runner: "node" } } - + private resolveTsx(): string | null { const candidates: Array string)> = [ () => nodeRequire.resolve("tsx/cli"), @@ -442,7 +390,7 @@ export class CliProcessManager extends EventEmitter { path.resolve(app.getAppPath(), "..", "node_modules", "tsx", "dist", "cli.mjs"), path.resolve(app.getAppPath(), "..", "node_modules", "tsx", "dist", "cli.cjs"), ] - + for (const candidate of candidates) { try { const resolved = typeof candidate === "function" ? candidate() : candidate @@ -453,10 +401,10 @@ export class CliProcessManager extends EventEmitter { continue } } - + return null } - + private resolveDevEntry(): string { const entry = path.resolve(process.cwd(), "..", "server", "src", "index.ts") if (!existsSync(entry)) { @@ -464,16 +412,33 @@ export class CliProcessManager extends EventEmitter { } return entry } - + private resolveProdEntry(): string { + // 1. Try node_modules resolution (development or linked) try { const entry = nodeRequire.resolve("@neuralnomads/codenomad/dist/bin.js") if (existsSync(entry)) { return entry } } catch { - // fall through to error below + // fall through + } + + // 2. Try packaged resources (production) + const resourcesPath = process.resourcesPath ?? app.getAppPath() + + // Check for boot.js (wrapper for _node_modules fix) + const bootEntry = path.join(resourcesPath, "cli", "boot.js") + if (existsSync(bootEntry)) { + return bootEntry } - throw new Error("Unable to locate CodeNomad CLI build (dist/bin.js). Run npm run build --workspace @neuralnomads/codenomad.") + + // Check for bin.js (direct) + const cliEntry = path.join(resourcesPath, "cli", "dist", "bin.js") + if (existsSync(cliEntry)) { + return cliEntry + } + + throw new Error(`Unable to locate CodeNomad CLI build. Checked: \n- node_modules\n- ${bootEntry}\n- ${cliEntry}`) } } diff --git a/packages/electron-app/electron/main/storage.ts b/packages/electron-app/electron/main/storage.ts index a93cc19e..fa353269 100644 --- a/packages/electron-app/electron/main/storage.ts +++ b/packages/electron-app/electron/main/storage.ts @@ -8,7 +8,7 @@ const CONFIG_FILE = join(CONFIG_DIR, "config.json") const INSTANCES_DIR = join(CONFIG_DIR, "instances") // File watching for config changes -let configWatchers = new Set() +let _configWatchers = new Set() let configLastModified = 0 let configCache: string | null = null @@ -57,7 +57,7 @@ export function setupStorageIPC() { ipcMain.handle("storage:readConfigFile", async () => { try { return await readConfigWithCache() - } catch (error) { + } catch { // Return empty config if file doesn't exist return JSON.stringify({ preferences: { showThinkingBlocks: false, thinkingBlocksExpansion: "expanded" }, recentFolders: [] }, null, 2) } @@ -69,15 +69,29 @@ export function setupStorageIPC() { invalidateConfigCache() // Notify other renderer processes about config change - const windows = require("electron").BrowserWindow.getAllWindows() + // Use safe access pattern to prevent "Object has been destroyed" errors during shutdown + const { BrowserWindow } = require("electron") + const windows = BrowserWindow.getAllWindows() windows.forEach((win: any) => { - if (win.webContents && !win.webContents.isDestroyed()) { - win.webContents.send("storage:configChanged") + try { + // Check if window is destroyed BEFORE accessing webContents property + if (win.isDestroyed()) { + return + } + // Access webContents after window check - this can still throw if window is being destroyed + const webContents = win.webContents + if (!webContents || webContents.isDestroyed()) { + return + } + webContents.send("storage:configChanged") + } catch (_error2) { + // Silently ignore errors during shutdown - window may be in destruction process + console.debug("[storage] Failed to send config change notification:", _error2) } }) - } catch (error) { - console.error("Failed to write config file:", error) - throw error + } catch (_error) { + console.error("Failed to write config file:", _error) + throw _error } }) @@ -85,7 +99,7 @@ export function setupStorageIPC() { const instanceFile = join(INSTANCES_DIR, `${filename}.json`) try { return await readFile(instanceFile, "utf-8") - } catch (error) { + } catch { // Return empty instance data if file doesn't exist return JSON.stringify({ messageHistory: [] }, null, 2) } @@ -95,9 +109,9 @@ export function setupStorageIPC() { const instanceFile = join(INSTANCES_DIR, `${filename}.json`) try { await writeFile(instanceFile, content, "utf-8") - } catch (error) { - console.error(`Failed to write instance file for ${filename}:`, error) - throw error + } catch (_error) { + console.error(`Failed to write instance file for ${filename}:`, _error) + throw _error } }) @@ -107,15 +121,9 @@ export function setupStorageIPC() { if (existsSync(instanceFile)) { await unlink(instanceFile) } - } catch (error) { - console.error(`Failed to delete instance file for ${filename}:`, error) - throw error + } catch (_error) { + console.error(`Failed to delete instance file for ${filename}:`, _error) + throw _error } }) } - -// Clean up on app quit -app.on("before-quit", () => { - configCache = null - configLastModified = 0 -}) diff --git a/packages/electron-app/electron/preload/index.cjs b/packages/electron-app/electron/preload/index.cjs index 8a7d6bf6..74961fd1 100644 --- a/packages/electron-app/electron/preload/index.cjs +++ b/packages/electron-app/electron/preload/index.cjs @@ -2,16 +2,26 @@ const { contextBridge, ipcRenderer } = require("electron") const electronAPI = { onCliStatus: (callback) => { - ipcRenderer.on("cli:status", (_, data) => callback(data)) - return () => ipcRenderer.removeAllListeners("cli:status") + const listener = (_, data) => callback(data) + ipcRenderer.on("cli:status", listener) + return () => ipcRenderer.removeListener("cli:status", listener) }, onCliError: (callback) => { - ipcRenderer.on("cli:error", (_, data) => callback(data)) - return () => ipcRenderer.removeAllListeners("cli:error") + const listener = (_, data) => callback(data) + ipcRenderer.on("cli:error", listener) + return () => ipcRenderer.removeListener("cli:error", listener) }, getCliStatus: () => ipcRenderer.invoke("cli:getStatus"), restartCli: () => ipcRenderer.invoke("cli:restart"), openDialog: (options) => ipcRenderer.invoke("dialog:open", options), + setWakeLock: (enabled) => ipcRenderer.invoke("power:setWakeLock", Boolean(enabled)), + // MCP bridge methods + mcpSend: (channel, data) => ipcRenderer.send(channel, data), + mcpOn: (channel, callback) => { + const listener = (_, data) => callback(data) + ipcRenderer.on(channel, listener) + return () => ipcRenderer.removeListener(channel, listener) + }, } contextBridge.exposeInMainWorld("electronAPI", electronAPI) diff --git a/packages/electron-app/package.json b/packages/electron-app/package.json index 0ecc0802..40428ad5 100644 --- a/packages/electron-app/package.json +++ b/packages/electron-app/package.json @@ -1,6 +1,6 @@ { "name": "@neuralnomads/codenomad-electron-app", - "version": "0.9.5", + "version": "0.10.3", "description": "CodeNomad - AI coding assistant", "license": "MIT", "author": { @@ -35,20 +35,29 @@ "package:linux": "electron-builder --linux" }, "dependencies": { + "@codenomad/mcp-server": "file:../mcp-server", + "@codenomad/ui": "file:../ui", + "@develar/schema-utils": "^2.6.5", + "@fastify/reply-from": "12.5.0", "@neuralnomads/codenomad": "file:../server", - "@codenomad/ui": "file:../ui" + "@types/dompurify": "^3.0.5", + "dompurify": "^3.3.1", + "dotenv": "^9.0.2", + "sax": "^1.4.4", + "ts-node": "1.7.1", + "yaml": "^2.4.2" }, "devDependencies": { "7zip-bin": "^5.2.0", "app-builder-bin": "^4.2.0", "electron": "39.0.0", - "electron-builder": "^24.0.0", + "electron-builder": "^26.4.0", "electron-vite": "4.0.1", "png2icons": "^2.0.1", "pngjs": "^7.0.0", "tsx": "^4.20.6", "typescript": "^5.3.0", - "vite": "^5.0.0", + "vite": "^7.3.1", "vite-plugin-solid": "^2.10.0" }, "build": { @@ -63,6 +72,10 @@ "package.json" ], "extraResources": [ + { + "from": "resources/cli", + "to": "cli" + }, { "from": "electron/resources", "to": "", diff --git a/packages/electron-app/scripts/build.js b/packages/electron-app/scripts/build.js index 4cc52ce7..9226d48d 100644 --- a/packages/electron-app/scripts/build.js +++ b/packages/electron-app/scripts/build.js @@ -1,7 +1,7 @@ #!/usr/bin/env node import { spawn } from "child_process" -import { existsSync } from "fs" +import { existsSync, readFileSync } from "fs" import path, { join } from "path" import { fileURLToPath } from "url" @@ -115,6 +115,82 @@ async function build(platform) { await run(npmCmd, ["run", "build"]) console.log("\n📦 Step 3/3: Packaging binaries...\n") + + // Step 2.5: Copy CLI dist and node_modules to resources + console.log("\n📦 Step 2.5/3: Preparing CLI resources...") + const { cpSync, renameSync, writeFileSync, existsSync, rmSync, readdirSync, statSync, readFileSync } = await import("fs") + const { join } = await import("path") + + const serverDir = join(process.cwd(), "../server") + const resourcesDir = join(process.cwd(), "resources") + const cliDest = join(resourcesDir, "cli") + const workspaceRootNodeModules = join(process.cwd(), "../../node_modules") + + // Ensure clean destination + if (existsSync(cliDest)) rmSync(cliDest, { recursive: true, force: true }) + + console.log(`Copying CLI from ${serverDir} to ${cliDest}`) + cpSync(serverDir, cliDest, { + recursive: true, + filter: (source, destination) => { + return !source.includes(".bin") && !source.includes("node_modules") + } + }) + + // Install production dependencies in the copied CLI to ensure all transitive deps are resolved + console.log(`\n📦 Installing production dependencies in copied CLI...`) + const installResult = await run(npmCmd, ["install", "--production", "--no-package-lock"], { + cwd: cliDest, + stdio: "pipe", + }) + console.log(`✓ Dependencies installed`) + + // Rename node_modules -> _node_modules to bypass electron-builder ignore + if (existsSync(join(cliDest, "node_modules"))) { + console.log("✓ Renaming node_modules -> _node_modules to bypass ignore rules") + renameSync(join(cliDest, "node_modules"), join(cliDest, "_node_modules")) + } else { + console.warn("⚠️ node_modules not found in CLI dir") + } + + // Create boot.js wrapper that sets up module resolution + const bootContent = ` +import { existsSync, symlinkSync, copyFileSync, mkdirSync } from 'fs'; +import { join, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const hiddenPath = join(__dirname, '_node_modules'); +const realPath = join(__dirname, 'node_modules'); + +// Create symlink from node_modules -> _node_modules (works in most cases) +if (existsSync(hiddenPath) && !existsSync(realPath)) { + try { + // Try creating a symlink first (works if we have write permissions) + symlinkSync(hiddenPath, realPath, 'dir'); + console.log('[CodeNomad] Created symlink: node_modules -> _node_modules'); + } catch (e) { + // Symlink failed, likely due to permissions + // Set NODE_PATH as fallback for child processes + process.env.NODE_PATH = hiddenPath; + console.warn('[CodeNomad] Could not create symlink, using NODE_PATH fallback'); + } +} + +// Import the CLI entry point +await import('./dist/bin.js'); +`; + writeFileSync(join(cliDest, "boot.js"), bootContent) + console.log("✓ Created boot.js wrapper") + + // Cleanup source files + const filesToRemove = ["src", "tsconfig.json", ".gitignore", "nodemon.json"] + filesToRemove.forEach(f => { + const p = join(cliDest, f) + if (existsSync(p)) rmSync(p, { recursive: true, force: true }) + }) const distPath = join(appDir, "dist") if (!existsSync(distPath)) { throw new Error("dist/ directory not found. Build failed.") diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json new file mode 100644 index 00000000..54a4e211 --- /dev/null +++ b/packages/mcp-server/package.json @@ -0,0 +1,19 @@ +{ + "name": "@codenomad/mcp-server", + "version": "0.10.3", + "description": "CodeNomad MCP Server - native ask_user tool for saving premium requests (Raw JSON-RPC implementation)", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc", + "dev": "tsc --watch", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "zod": "^3.25.76" + }, + "devDependencies": { + "typescript": "^5.3.0" + } +} diff --git a/packages/mcp-server/pnpm-lock.yaml b/packages/mcp-server/pnpm-lock.yaml new file mode 100644 index 00000000..b808eb4f --- /dev/null +++ b/packages/mcp-server/pnpm-lock.yaml @@ -0,0 +1,33 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + zod: + specifier: ^3.25.76 + version: 3.25.76 + devDependencies: + typescript: + specifier: ^5.3.0 + version: 5.9.3 + +packages: + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + +snapshots: + + typescript@5.9.3: {} + + zod@3.25.76: {} diff --git a/packages/mcp-server/scripts/simulate-tools-call.mjs b/packages/mcp-server/scripts/simulate-tools-call.mjs new file mode 100644 index 00000000..a2791035 --- /dev/null +++ b/packages/mcp-server/scripts/simulate-tools-call.mjs @@ -0,0 +1,53 @@ +import { CodeNomadMcpServer } from '../dist/index.js'; + +async function simulate() { + const server = new CodeNomadMcpServer(); + console.log('[SIM] Server instance created'); + + const payload = { + jsonrpc: '2.0', + id: 'sim-1', + method: 'tools/call', + params: { + name: 'ask_user', + arguments: { + questions: [{ question: 'Is this a test?', type: 'text', required: true }], + title: 'SimTest' + } + } + }; + + // Invoke private handler directly + const resPromise = server['handleJsonRpc'](payload); + + // Allow microtask queue to process + await new Promise((r) => setTimeout(r, 10)); + + const pending = server.getPendingManager().getAll(); + console.log('[SIM] Pending count after call:', server.getPendingManager().count()); + console.log('[SIM] Pending IDs:', pending.map(p => p.id)); + + if (pending.length === 0) { + console.error('[SIM] No pending request was created'); + const res = await resPromise; + console.log('[SIM] Response (no pending):', JSON.stringify(res, null, 2)); + return; + } + + const reqId = pending[0].id; + const q = pending[0].questions[0]; + + // Simulate UI answering + const answers = [{ questionId: q.id, values: ['yes'] }]; + const ok = server.getPendingManager().resolve(reqId, answers); + console.log('[SIM] Resolve returned:', ok); + + const res = await resPromise; + console.log('[SIM] Tool response:', JSON.stringify(res, null, 2)); + console.log('[SIM] Pending count after resolve:', server.getPendingManager().count()); +} + +simulate().catch((err) => { + console.error('[SIM] Error during simulation:', err); + process.exit(1); +}); diff --git a/packages/mcp-server/src/__tests__/askuser.test.ts b/packages/mcp-server/src/__tests__/askuser.test.ts new file mode 100644 index 00000000..bce9a01a --- /dev/null +++ b/packages/mcp-server/src/__tests__/askuser.test.ts @@ -0,0 +1,57 @@ +import { describe, it } from 'node:test' +import assert from 'node:assert' +import type { CnAskUserInput } from '../tools/schemas.js' +import { askUser } from '../tools/askUser.js' +import { PendingRequestManager } from '../pending.js' + +// Minimal fake bridge to capture sendQuestion calls +const makeBridge = () => { + let last: any = null + return { + sendQuestion: (requestId: string, questions: any[], title?: string) => { + last = { requestId, questions, title } + }, + getLast: () => last, + onAnswer: (_cb: any) => {}, + onCancel: (_cb: any) => {}, + onRenderConfirmed: (_cb: any) => {} + } +} + +describe('askUser tool', () => { + it('sends a question via bridge and resolves when pending manager is answered', async () => { + const pending = new PendingRequestManager() + const bridge = makeBridge() + + const input: CnAskUserInput = { + questions: [{ question: 'What is your name?', type: 'text', required: true }], + title: 'Test', + maxRetries: 3, + renderTimeout: 30000 + } + + const p = askUser(input, bridge as any, pending) + + // Bridge should have received a sendQuestion call + const sent = bridge.getLast() + assert.ok(sent) + assert.ok(sent.requestId) + assert.equal(sent.title, 'Test') + + // Simulate UI confirming render + const confirmed = pending.confirmRender(sent.requestId) + assert.equal(confirmed, true) + + // Simulate UI answering the question + const answers = [{ questionId: (sent.questions[0].id), values: ['copilot'] }] + + const resolved = pending.resolve(sent.requestId, answers) + assert.equal(resolved, true) + + const result = await p + assert.equal(result.answered, true) + assert.equal(result.shouldRetry, false) + assert.equal(result.renderConfirmed, true) + assert.equal(result.answers[0].values[0], 'copilot') + }) +}) diff --git a/packages/mcp-server/src/__tests__/ipc-bridge.test.ts b/packages/mcp-server/src/__tests__/ipc-bridge.test.ts new file mode 100644 index 00000000..c827cf84 --- /dev/null +++ b/packages/mcp-server/src/__tests__/ipc-bridge.test.ts @@ -0,0 +1,26 @@ +import { describe, it } from 'node:test' +import assert from 'node:assert' +import { createIpcBridge } from '../bridge/ipc.js' +import { PendingRequestManager } from '../pending.js' + +describe('IPC bridge', () => { + it('sends ask_user.asked to mainWindow.webContents', () => { + const sent: any[] = [] + const fakeWindow: any = { + webContents: { + send: (channel: string, payload: any) => sent.push({ channel, payload }) + }, + on: (_ev: string, _cb: any) => {} + } + + const pending = new PendingRequestManager() + const bridge = createIpcBridge(fakeWindow as any, pending) + + bridge.sendQuestion('req-1', [{ id: 'q-1', question: 'x', type: 'text', required: true }], 'T') + + assert.equal(sent.length, 1) + assert.equal(sent[0].channel, 'ask_user.asked') + assert.equal(sent[0].payload.requestId, 'req-1') + assert.equal(sent[0].payload.title, 'T') + }) +}) diff --git a/packages/mcp-server/src/__tests__/ipc-setup.test.ts b/packages/mcp-server/src/__tests__/ipc-setup.test.ts new file mode 100644 index 00000000..44fa6e3b --- /dev/null +++ b/packages/mcp-server/src/__tests__/ipc-setup.test.ts @@ -0,0 +1,16 @@ +import { describe, it } from 'node:test' +import assert from 'node:assert' +import { setupMcpBridge } from '../bridge/ipc.js' + +describe('setupMcpBridge', () => { + it('resolves without throwing when Electron is not present', async () => { + const fakeWindow: any = { + webContents: { send: () => {} }, + on: () => {} + } + + await setupMcpBridge(fakeWindow) + // No exceptions = pass + assert.ok(true) + }) +}) diff --git a/packages/mcp-server/src/__tests__/pending.test.ts b/packages/mcp-server/src/__tests__/pending.test.ts new file mode 100644 index 00000000..32c5f15e --- /dev/null +++ b/packages/mcp-server/src/__tests__/pending.test.ts @@ -0,0 +1,38 @@ +import { describe, it } from 'node:test' +import assert from 'node:assert' +import { PendingRequestManager } from '../pending.js' + +describe('PendingRequestManager', () => { + it('adds and resolves a pending request', async () => { + const mgr = new PendingRequestManager() + + let resolvedResult: any = null + + mgr.add({ + id: 'test-1', + questions: [], + resolve: (r) => { resolvedResult = r }, + reject: (_e) => { /* not used */ }, + createdAt: Date.now(), + timeout: null, + renderTimeout: null, + renderConfirmed: false, + maxRetries: 3, + retryCount: 0 + }) + + const ok = mgr.resolve('test-1', [{ questionId: 'q1', values: ['a'] }]) + assert.equal(ok, true) + assert.ok(resolvedResult) + assert.equal(resolvedResult.answered, true) + assert.equal(resolvedResult.shouldRetry, false) + assert.equal(resolvedResult.renderConfirmed, false) + assert.equal(mgr.count(), 0) + }) + + it('rejects a missing request gracefully', () => { + const mgr = new PendingRequestManager() + const ok = mgr.resolve('does-not-exist', []) + assert.equal(ok, false) + }) +}) diff --git a/packages/mcp-server/src/__tests__/schemas.test.ts b/packages/mcp-server/src/__tests__/schemas.test.ts new file mode 100644 index 00000000..29178b25 --- /dev/null +++ b/packages/mcp-server/src/__tests__/schemas.test.ts @@ -0,0 +1,91 @@ +import { describe, it } from 'node:test'; +import assert from 'node:assert'; +import { CnAskUserInputSchema, CnAskUserOutputSchema } from '../tools/schemas.js'; + +describe('CnAskUserInputSchema', () => { + it('should accept valid input with default maxRetries', () => { + const result = CnAskUserInputSchema.safeParse({ + questions: [{ question: 'Test?' }] + }); + assert.strictEqual(result.success, true); + if (result.success) { + assert.strictEqual(result.data.maxRetries, 3); + assert.strictEqual(result.data.renderTimeout, 30000); + } + }); + + it('should accept custom maxRetries and renderTimeout', () => { + const result = CnAskUserInputSchema.safeParse({ + questions: [{ question: 'Test?' }], + maxRetries: 5, + renderTimeout: 15000 + }); + assert.strictEqual(result.success, true); + if (result.success) { + assert.strictEqual(result.data.maxRetries, 5); + assert.strictEqual(result.data.renderTimeout, 15000); + } + }); + + it('should reject maxRetries > 5', () => { + const result = CnAskUserInputSchema.safeParse({ + questions: [{ question: 'Test?' }], + maxRetries: 10 + }); + assert.strictEqual(result.success, false); + }); + + it('should reject renderTimeout < 10000', () => { + const result = CnAskUserInputSchema.safeParse({ + questions: [{ question: 'Test?' }], + renderTimeout: 5000 + }); + assert.strictEqual(result.success, false); + }); + + it('should reject renderTimeout > 60000', () => { + const result = CnAskUserInputSchema.safeParse({ + questions: [{ question: 'Test?' }], + renderTimeout: 70000 + }); + assert.strictEqual(result.success, false); + }); +}); + +describe('CnAskUserOutputSchema', () => { + it('should validate output with retry fields', () => { + const result = CnAskUserOutputSchema.safeParse({ + answered: false, + cancelled: false, + timedOut: false, + shouldRetry: true, + retryReason: "UI render timeout", + renderConfirmed: false, + answers: [] + }); + assert.strictEqual(result.success, true); + }); + + it('should validate successful response', () => { + const result = CnAskUserOutputSchema.safeParse({ + answered: true, + cancelled: false, + timedOut: false, + shouldRetry: false, + retryReason: null, + renderConfirmed: true, + answers: [{ questionId: 'q1', values: ['answer'], customText: '' }] + }); + assert.strictEqual(result.success, true); + }); + + it('should require all retry-related fields', () => { + const result = CnAskUserOutputSchema.safeParse({ + answered: false, + cancelled: false, + timedOut: false, + answers: [] + }); + assert.strictEqual(result.success, false); + }); +}); diff --git a/packages/mcp-server/src/bridge/ipc.ts b/packages/mcp-server/src/bridge/ipc.ts new file mode 100644 index 00000000..36a1e729 --- /dev/null +++ b/packages/mcp-server/src/bridge/ipc.ts @@ -0,0 +1,351 @@ +import type { BrowserWindow } from 'electron'; +import type { QuestionInfo, QuestionAnswer } from '../tools/schemas.js'; +import type { QuestionBridge } from '../tools/askUser.js'; +import type { PendingRequestManager } from '../pending.js'; + +type McpLogLevel = 'info' | 'warn' | 'error'; + +let enableDebugLogs = process.env.NODE_ENV !== 'production'; + +/** + * Safely send message to renderer webContents with proper destruction checks. + * This prevents "Object has been destroyed" errors during app shutdown. + * Returns true if message was sent, false if window/webContents was destroyed. + */ +function safeSendToRenderer(mainWindow: BrowserWindow, channel: string, ...args: unknown[]): boolean { + // Early exit if app is shutting down + if (isShuttingDown) { + return false; + } + try { + if (mainWindow.isDestroyed()) { + return false; + } + // Access webContents property first - if window is destroyed, this may throw + const webContents = mainWindow.webContents; + if (!webContents || webContents.isDestroyed()) { + return false; + } + webContents.send(channel, ...args); + return true; + } catch (error) { + // Log in development but don't throw - this is expected during shutdown + if (enableDebugLogs) { + console.warn(`[MCP IPC] Failed to send ${channel}:`, error); + } + return false; + } +} + +function emitRendererLog(mainWindow: BrowserWindow, level: McpLogLevel, message: string, data?: unknown) { + safeSendToRenderer(mainWindow, 'mcp:log', { level, message, data }); +} + +function logDebug(message: string, data?: unknown) { + if (!enableDebugLogs) { + return; + } + if (data !== undefined) { + console.log(message, data); + return; + } + console.log(message); +} + +function formatWindowInfo(mainWindow: BrowserWindow): string { + const windowId = mainWindow.id; + const contentsId = mainWindow.webContents.id; + return `windowId=${windowId} webContentsId=${contentsId}`; +} + +/** + * Global reference to the pending manager for IPC handlers + * This will be set when the bridge is connected + */ +let globalPendingManager: PendingRequestManager | null = null; + +/** + * Flag to track if the app is shutting down. + * Set this to true to prevent any further IPC sends. + */ +let isShuttingDown = false; + +/** + * Setup IPC handlers for MCP bridge in main process + * This handles communication between the UI (renderer) and the MCP server + */ +export async function setupMcpBridge(mainWindow: BrowserWindow): Promise { + console.log('[MCP IPC] Setting up main process bridge'); + logDebug(`[MCP IPC] Bridge window ${formatWindowInfo(mainWindow)}`); + emitRendererLog(mainWindow, 'info', 'Setting up main process bridge', { windowInfo: formatWindowInfo(mainWindow) }); + + let requestTimeout = 300000; // Default 5 minutes + + + // Attempt to import electron dynamically. If not available (e.g., in test env), skip attaching handlers. + let ipcMain: any = null + try { + const electron = await import('electron') + ipcMain = electron?.ipcMain + enableDebugLogs = !(electron?.app?.isPackaged ?? false); + if (!ipcMain || typeof ipcMain.on !== 'function') { + console.warn('[MCP IPC] ipcMain not available on electron import, skipping IPC handler setup') + emitRendererLog(mainWindow, 'warn', 'ipcMain not available on electron import, skipping IPC handler setup') + return + } + } catch (err) { + console.warn('[MCP IPC] Electron not available, skipping IPC handler setup') + emitRendererLog(mainWindow, 'warn', 'Electron not available, skipping IPC handler setup') + return + } + + // Handler: Debug messages from renderer + ipcMain.on('mcp:debug', (_event: any, data: any) => { + const { message, instanceId } = data; + const senderId = _event?.sender?.id; + logDebug(`[MCP IPC DEBUG] ${message}${instanceId ? ` (instance: ${instanceId})` : ''} senderWebContentsId=${senderId}`); + emitRendererLog(mainWindow, 'info', message, { instanceId, senderWebContentsId: senderId }); + }); + + // Handler: UI sends answer for MCP question + ipcMain.on('mcp:answer', (_event: any, data: any) => { + const { requestId, answers } = data; + const senderId = _event?.sender?.id; + console.log(`[MCP IPC] Received answer from UI: ${requestId}`); + logDebug(`[MCP IPC] Answer senderWebContentsId=${senderId}`); + emitRendererLog(mainWindow, 'info', 'Received answer from UI', { requestId, senderWebContentsId: senderId }); + + if (globalPendingManager) { + const resolved = globalPendingManager.resolve(requestId, answers); + if (resolved) { + console.log(`[MCP IPC] Request ${requestId} resolved successfully`); + emitRendererLog(mainWindow, 'info', 'Request resolved successfully', { requestId }); + } else { + console.warn(`[MCP IPC] No pending request for answer: ${requestId}`); + emitRendererLog(mainWindow, 'warn', 'No pending request for answer', { requestId }); + } + } else { + console.warn('[MCP IPC] Pending manager not initialized, cannot process answer'); + emitRendererLog(mainWindow, 'warn', 'Pending manager not initialized, cannot process answer'); + } + }); + + // Handler: UI sends cancel for MCP question + ipcMain.on('mcp:cancel', (_event: any, data: any) => { + const { requestId } = data; + const senderId = _event?.sender?.id; + console.log(`[MCP IPC] Received cancel from UI: ${requestId}`); + logDebug(`[MCP IPC] Cancel senderWebContentsId=${senderId}`); + emitRendererLog(mainWindow, 'info', 'Received cancel from UI', { requestId, senderWebContentsId: senderId }); + + if (globalPendingManager) { + const rejected = globalPendingManager.reject(requestId, new Error('cancelled')); + if (rejected) { + console.log(`[MCP IPC] Request ${requestId} cancelled successfully`); + emitRendererLog(mainWindow, 'info', 'Request cancelled successfully', { requestId }); + // Notify UI that the question was rejected + safeSendToRenderer(mainWindow, 'ask_user.rejected', { + requestId, + reason: 'cancelled', + timedOut: false, + cancelled: true + }); + } else { + console.warn(`[MCP IPC] No pending request for cancel: ${requestId}`); + emitRendererLog(mainWindow, 'warn', 'No pending request for cancel', { requestId }); + } + } else { + console.warn('[MCP IPC] Pending manager not initialized, cannot process cancel'); + emitRendererLog(mainWindow, 'warn', 'Pending manager not initialized, cannot process cancel'); + } + }); + + // Handler: UI sends configuration update + ipcMain.on('mcp:config', (_event: any, data: any) => { + const { requestTimeout: timeout } = data; + if (typeof timeout === 'number' && timeout > 0) { + console.log(`[MCP IPC] Updating request timeout to ${timeout}ms`); + // Store this in a way accessible to the render handler. + // Since we are inside setupMcpBridge, we can use a closure variable if we define it above. + // See below for variable definition. + requestTimeout = timeout; + emitRendererLog(mainWindow, 'info', `Updated request timeout to ${timeout}ms`); + } + }); + + // Handler: UI confirms question was rendered/displayed + ipcMain.on('mcp:renderConfirmed', (_event: any, data: any) => { + const { requestId } = data; + const senderId = _event?.sender?.id; + console.log(`[MCP IPC] Received render confirmation from UI: ${requestId}`); + logDebug(`[MCP IPC] Render confirmation senderWebContentsId=${senderId}`); + emitRendererLog(mainWindow, 'info', 'Received render confirmation from UI', { requestId, senderWebContentsId: senderId }); + + if (globalPendingManager) { + const pending = globalPendingManager.get(requestId); + if (pending?.renderConfirmed || pending?.timeout) { + logDebug(`[MCP IPC] Render already confirmed for ${requestId}, skipping duplicate confirmation`); + emitRendererLog(mainWindow, 'info', 'Render already confirmed, skipping duplicate', { requestId }); + return; + } + + const confirmed = globalPendingManager.confirmRender(requestId); + if (confirmed) { + console.log(`[MCP IPC] Render confirmed for ${requestId}, starting user response timer (${requestTimeout}ms)`); + emitRendererLog(mainWindow, 'info', 'Render confirmed, starting user response timer', { requestId, timeout: requestTimeout }); + + // Start the user response timeout + const activePending = globalPendingManager.get(requestId); + if (activePending) { + activePending.timeout = setTimeout(() => { + console.log(`[MCP IPC] User response timeout for ${requestId}`); + // Notify UI that question timed out so it can clean up wizard and move to failed notifications + safeSendToRenderer(mainWindow, 'ask_user.rejected', { + requestId, + reason: 'timeout', + timedOut: true, + cancelled: false + }); + globalPendingManager?.reject(requestId, new Error('Question timeout')); + }, requestTimeout); + } + } else { + console.warn(`[MCP IPC] No pending request for render confirmation: ${requestId}`); + emitRendererLog(mainWindow, 'warn', 'No pending request for render confirmation', { requestId }); + } + } else { + console.warn('[MCP IPC] Pending manager not initialized, cannot process render confirmation'); + emitRendererLog(mainWindow, 'warn', 'Pending manager not initialized'); + } + }); + + // Cleanup on window close + mainWindow.on('closed', () => { + console.log('[MCP IPC] Window closed, cleaning up pending requests'); + // Set shutdown flag to prevent any further sends + isShuttingDown = true; + // Don't try to send logs or messages to a closed window + // Just clean up the pending requests and clear timeouts + if (globalPendingManager) { + for (const request of globalPendingManager.getAll()) { + // Clear any pending timeouts for this request + if (request.timeout) { + clearTimeout(request.timeout); + (request as any).timeout = null; + } + // Reject the promise without trying to notify the UI + // The window is closed, so the UI won't receive messages anyway + globalPendingManager.reject(request.id, new Error('Window closed')); + } + } + }); + + console.log('[MCP IPC] Main process bridge setup complete'); + emitRendererLog(mainWindow, 'info', 'Main process bridge setup complete'); +} + +/** + * Create a bridge that uses IPC to communicate with the UI + * Call this after MCP server is initialized to connect it to IPC + */ +export function createIpcBridge(mainWindow: BrowserWindow, pendingManager: PendingRequestManager): QuestionBridge { + console.log('[MCP IPC] Creating IPC bridge for MCP server'); + logDebug(`[MCP IPC] Bridge window ${formatWindowInfo(mainWindow)}`); + + return { + sendQuestion: (requestId: string, questions: Array, title?: string) => { + console.log(`[MCP IPC] Sending question to UI: ${requestId}`); + logDebug(`[MCP IPC] Target window ${formatWindowInfo(mainWindow)}`); + emitRendererLog(mainWindow, 'info', 'Sending question to UI', { requestId, questionCount: questions.length, title: title ?? null, windowInfo: formatWindowInfo(mainWindow) }); + + if (mainWindow.isDestroyed() || mainWindow.webContents.isDestroyed()) { + console.warn(`[MCP IPC] Window/webContents destroyed; cannot send question: ${requestId}`); + emitRendererLog(mainWindow, 'warn', 'Window/webContents destroyed; cannot send question', { requestId }); + pendingManager.reject(requestId, new Error('Window destroyed')); + return; + } + + // Send to renderer process + try { + mainWindow.webContents.send('ask_user.asked', { + requestId, + questions, + title, + source: 'mcp' + }); + } catch (error) { + console.error(`[MCP IPC] Failed to send question ${requestId}:`, error); + emitRendererLog(mainWindow, 'error', 'Failed to send question', { requestId, error }); + pendingManager.reject(requestId, new Error('IPC send failed')); + return; + } + + // Create a promise that waits for the answer + // This will be resolved by the IPC handlers above + const pending = pendingManager.get(requestId); + if (pending) { + // The pending manager already handles the timeout + // We just need to make sure the promise is set up correctly + console.log(`[MCP IPC] Question ${requestId} registered in pending manager`); + emitRendererLog(mainWindow, 'info', 'Question registered in pending manager', { requestId }); + } else { + console.warn(`[MCP IPC] Question ${requestId} not found in pending manager`); + emitRendererLog(mainWindow, 'warn', 'Question not found in pending manager', { requestId }); + } + }, + onAnswer: (_callback: (requestId: string, answers: QuestionAnswer[]) => void) => { + // Already handled via 'mcp:answer' IPC handler in setupMcpBridge + console.log('[MCP IPC] Answer handler registered (via IPC)'); + }, + onCancel: (_callback: (requestId: string) => void) => { + // Already handled via 'mcp:cancel' IPC handler in setupMcpBridge + console.log('[MCP IPC] Cancel handler registered (via IPC)'); + }, + onRenderConfirmed: (_callback: (requestId: string) => void) => { + // Handled via 'mcp:renderConfirmed' IPC handler above + console.log('[MCP IPC] Render confirmation handler registered (via IPC)'); + } + }; +} + +/** + * Connect the MCP server to IPC + * This creates an IPC bridge and connects it to the server + */ +export function connectMcpBridge(mcpServer: any, mainWindow: BrowserWindow): void { + console.log('[MCP IPC] Connecting MCP server to IPC bridge'); + + // Get the pending manager from the server + const pendingManager = mcpServer.getPendingManager(); + + // Set global reference for IPC handlers + globalPendingManager = pendingManager; + + // Create the IPC bridge + const ipcBridge = createIpcBridge(mainWindow, pendingManager); + + // Connect the bridge to the server + mcpServer.connectBridge(ipcBridge); + + console.log('[MCP IPC] MCP server connected to IPC bridge'); +} + +/** + * Signal that the app is shutting down. + * This prevents any further IPC sends and cleans up pending requests. + */ +export function shutdownBridge() { + console.log('[MCP IPC] Shutdown signal received'); + isShuttingDown = true; + + // Clear all pending timeouts and reject all pending requests + if (globalPendingManager) { + for (const request of globalPendingManager.getAll()) { + if (request.timeout) { + clearTimeout(request.timeout); + (request as any).timeout = null; + } + globalPendingManager.reject(request.id, new Error('App shutting down')); + } + } +} diff --git a/packages/mcp-server/src/bridge/renderer.ts b/packages/mcp-server/src/bridge/renderer.ts new file mode 100644 index 00000000..934e4c43 --- /dev/null +++ b/packages/mcp-server/src/bridge/renderer.ts @@ -0,0 +1,80 @@ +import type { QuestionInfo, QuestionAnswer } from '../tools/schemas.js'; +import type { IpcBridgeRenderer } from './types.js'; + +// Type declarations for Electron APIs +declare global { + interface Window { + require: (module: string) => any; + dispatchEvent: (event: Event) => void; + } +} + +/** + * Initialize renderer-side IPC listeners + */ +export function initMcpBridge(instanceId: string): void { + console.log(`[MCP Bridge Renderer] Initializing for instance: ${instanceId}`); + + // Check if we're in Electron environment + if (typeof window === 'undefined' || !window.require) { + console.warn('[MCP Bridge Renderer] Not in Electron environment, skipping MCP bridge'); + return; + } + + try { + const { ipcRenderer } = window.require('electron'); + + console.log('[MCP Bridge Renderer] Setting up IPC listeners'); + + // Listen for questions from MCP server (via main process) + ipcRenderer.on('ask_user.asked', (_event, payload: any) => { + console.log('[MCP Bridge Renderer] Received question:', payload); + + // Map MCP question format to CodeNomad question format + const { requestId, questions, title, source } = payload; + + // Add to existing question queue + // This will be connected to actual store in Phase 4 + if (window.dispatchEvent) { + const event = new CustomEvent('mcp-question-received'); + window.dispatchEvent(event); + } + }); + + console.log('[MCP Bridge Renderer] Initialized successfully'); + } catch (error) { + console.error('[MCP Bridge Renderer] Failed to initialize:', error); + } +} + +/** + * Send answer to main process (for MCP questions) + */ +export function sendMcpAnswer(requestId: string, answers: QuestionAnswer[]): void { + console.log(`[MCP Bridge Renderer] Sending answer: ${requestId}`); + + try { + if (typeof window !== 'undefined' && window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.send('mcp:answer', { requestId, answers }); + } + } catch (error) { + console.error('[MCP Bridge Renderer] Failed to send answer:', error); + } +} + +/** + * Send cancel to main process (for MCP questions) + */ +export function sendMcpCancel(requestId: string): void { + console.log(`[MCP Bridge Renderer] Sending cancel: ${requestId}`); + + try { + if (typeof window !== 'undefined' && window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.send('mcp:cancel', { requestId }); + } + } catch (error) { + console.error('[MCP Bridge Renderer] Failed to send cancel:', error); + } +} diff --git a/packages/mcp-server/src/bridge/types.ts b/packages/mcp-server/src/bridge/types.ts new file mode 100644 index 00000000..5f90ca94 --- /dev/null +++ b/packages/mcp-server/src/bridge/types.ts @@ -0,0 +1,61 @@ +import type { QuestionInfo, QuestionAnswer } from '../tools/schemas.js'; + +/** + * Bridge interface for MCP server ↔ UI communication + */ +export interface QuestionBridge { + /** + * Send question from MCP server to UI + */ + sendQuestion(requestId: string, questions: Array, title?: string): void; + + /** + * Register callback for when user answers + */ + onAnswer(callback: (requestId: string, answers: QuestionAnswer[]) => void): void; + + /** + * Register callback for when user cancels + */ + onCancel(callback: (requestId: string) => void): void; +} + +/** + * Main process IPC bridge interface + */ +export interface IpcBridgeMain { + /** + * Setup IPC handlers for MCP bridge + */ + setup(): void; + + /** + * Send answer from UI to pending request + */ + handleAnswer(requestId: string, answers: QuestionAnswer[]): void; + + /** + * Send cancel from UI to pending request + */ + handleCancel(requestId: string): void; +} + +/** + * Renderer process IPC bridge interface + */ +export interface IpcBridgeRenderer { + /** + * Initialize renderer-side IPC listeners + */ + init(): void; + + /** + * Send answer to main process + */ + sendAnswer(requestId: string, answers: QuestionAnswer[]): void; + + /** + * Send cancel to main process + */ + sendCancel(requestId: string): void; +} diff --git a/packages/mcp-server/src/config/registration.ts b/packages/mcp-server/src/config/registration.ts new file mode 100644 index 00000000..b3a87add --- /dev/null +++ b/packages/mcp-server/src/config/registration.ts @@ -0,0 +1,324 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as os from 'os'; +import * as http from 'http'; +import { randomBytes } from 'crypto'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +export interface McpServerConfig { + command: string; + args: string[]; +} + +export interface McpInstanceConfigFile { + instanceId: string; + pid: number; + port: number; + /** + * Deprecated: Token is intentionally not persisted to disk. + * This remains optional to tolerate older config files. + */ + token?: string; + /** + * Deprecated: Server path is intentionally not persisted to disk. + * This remains optional to tolerate older config files. + */ + serverPath?: string; + startedAt: string; +} + +export interface McpRegistrationConfig { + instanceId: string; + port: number; + token: string; + serverPath?: string; +} + +const CODENOMAD_HOME_DIRNAME = '.codenomad'; +const CODENOMAD_INSTANCES_DIRNAME = 'instances'; + +function getCodeNomadBaseDir(): string { + return path.join(os.homedir(), CODENOMAD_HOME_DIRNAME); +} + +function getInstancesDir(): string { + return path.join(getCodeNomadBaseDir(), CODENOMAD_INSTANCES_DIRNAME); +} + +function getLegacyAntigravityConfigPath(): string { + return path.join(os.homedir(), '.gemini', 'antigravity', 'mcp_config.json'); +} + +function safeUnlink(filePath: string): void { + try { + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); + } + } catch { + // ignore + } +} + +function safeRmDir(dirPath: string): void { + try { + if (fs.existsSync(dirPath)) { + fs.rmSync(dirPath, { recursive: true, force: true }); + } + } catch { + // ignore + } +} + +function isPidAlive(pid: number | undefined): boolean { + if (!pid || !Number.isFinite(pid) || pid <= 0) return false; + try { + process.kill(pid, 0); + return true; + } catch (error) { + // EPERM means it exists but we can't signal it. + if (error && typeof error === 'object' && 'code' in error && (error as any).code === 'EPERM') { + return true; + } + return false; + } +} + +function probeHealth(port: number, timeoutMs: number): Promise { + return new Promise((resolve) => { + if (!Number.isFinite(port) || port <= 0) { + resolve(false); + return; + } + + const req = http.get( + { + hostname: '127.0.0.1', + port, + path: '/health', + timeout: timeoutMs, + }, + (res) => { + res.resume(); + resolve(res.statusCode === 200); + }, + ); + + req.on('timeout', () => { + req.destroy(new Error('timeout')); + resolve(false); + }); + + req.on('error', () => resolve(false)); + }); +} + +/** + * Get MCP config file path + */ +export function getMcpConfigPath(): string { + return path.join(getCodeNomadBaseDir(), 'mcp_config.json'); +} + +export function getMcpInstanceConfigPath(instanceId: string): string { + return path.join(getInstancesDir(), instanceId, 'config.json'); +} + +/** + * Read existing MCP config + */ +export function readMcpConfig(): { mcpServers: Record } { + const configPath = getMcpConfigPath(); + + if (!fs.existsSync(configPath)) { + return { mcpServers: {} }; + } + + try { + const content = fs.readFileSync(configPath, 'utf8'); + return JSON.parse(content); + } catch (error) { + console.warn('[MCP Config] Failed to read existing config:', error); + return { mcpServers: {} }; + } +} + +/** + * Best-effort cleanup for legacy Antigravity registration. + * This intentionally does not create the legacy file; it only removes the `ask-user` entry if present. + */ +export function cleanupLegacyAntigravityRegistration(): void { + const legacyPath = getLegacyAntigravityConfigPath(); + if (!fs.existsSync(legacyPath)) return; + + try { + const content = fs.readFileSync(legacyPath, 'utf8'); + const parsed = JSON.parse(content) as any; + const mcpServers = parsed?.mcpServers; + if (!mcpServers || typeof mcpServers !== 'object' || !mcpServers['ask-user']) { + return; + } + + delete mcpServers['ask-user']; + const updated = { ...parsed, mcpServers }; + + const tempPath = `${legacyPath}.tmp.${process.pid}.${randomBytes(8).toString('hex')}`; + fs.writeFileSync(tempPath, JSON.stringify(updated, null, 2) + '\n'); + fs.renameSync(tempPath, legacyPath); + safeUnlink(tempPath); + + console.log('[MCP Config] Removed legacy Antigravity ask-user registration'); + } catch (error) { + console.warn('[MCP Config] Failed to clean up legacy Antigravity registration:', error); + } +} + +export function readMcpInstanceConfig(instanceId: string): McpInstanceConfigFile | null { + const configPath = getMcpInstanceConfigPath(instanceId); + + if (!fs.existsSync(configPath)) { + return null; + } + + try { + const content = fs.readFileSync(configPath, 'utf8'); + return JSON.parse(content) as McpInstanceConfigFile; + } catch (error) { + console.warn('[MCP Config] Failed to read instance config:', error); + return null; + } +} + +/** + * Write MCP config with CodeNomad entry + * + * @param port - MCP server port + * @param token - MCP server auth token + * @param serverPath - Absolute path to the MCP server entry point (server.js) + */ +export function writeMcpConfig(config: McpRegistrationConfig): void; +/** + * @deprecated Prefer passing an object with a stable instanceId. + */ +export function writeMcpConfig(port: number, token: string, serverPath?: string): void; +export function writeMcpConfig( + configOrPort: McpRegistrationConfig | number, + legacyToken?: string, + legacyServerPath?: string, +): void { + try { + const config: McpRegistrationConfig = + typeof configOrPort === 'number' + ? { + instanceId: `pid-${process.pid}`, + port: configOrPort, + token: legacyToken ?? '', + serverPath: legacyServerPath, + } + : configOrPort; + + if (!config.instanceId || config.instanceId.trim().length === 0) { + throw new Error('instanceId is required'); + } + + if (!config.port || !Number.isFinite(config.port)) { + throw new Error('port is required'); + } + + if (!config.token || config.token.trim().length === 0) { + throw new Error('token is required'); + } + + const instanceConfig: McpInstanceConfigFile = { + instanceId: config.instanceId, + pid: process.pid, + port: config.port, + startedAt: new Date().toISOString(), + }; + + const configPath = getMcpInstanceConfigPath(config.instanceId); + const configDir = path.dirname(configPath); + fs.mkdirSync(configDir, { recursive: true }); + + const tempPath = `${configPath}.tmp.${process.pid}.${randomBytes(8).toString('hex')}`; + const payload = JSON.stringify(instanceConfig, null, 2) + '\n'; + fs.writeFileSync(tempPath, payload, { mode: 0o600 }); + fs.renameSync(tempPath, configPath); + safeUnlink(tempPath); + + console.log(`[MCP Config] Registered CodeNomad instance ${config.instanceId} on port ${config.port}`); + } catch (error) { + console.error('[MCP Config] Failed to write instance config:', error); + } +} + +/** + * Remove CodeNomad entry from MCP config + */ +export function unregisterFromMcpConfig(instanceId?: string): void { + const resolvedInstanceId = instanceId && instanceId.trim().length > 0 ? instanceId : `pid-${process.pid}`; + const configPath = getMcpInstanceConfigPath(resolvedInstanceId); + const instanceDir = path.dirname(configPath); + + try { + if (!fs.existsSync(configPath) && !fs.existsSync(instanceDir)) { + console.log('[MCP Config] No instance config found, nothing to unregister'); + return; + } + + safeUnlink(configPath); + safeRmDir(instanceDir); + console.log(`[MCP Config] Unregistered CodeNomad instance ${resolvedInstanceId}`); + } catch (error) { + console.error('[MCP Config] Failed to unregister instance config:', error); + } +} + +export async function cleanupStaleInstances(options?: { healthTimeoutMs?: number }): Promise { + const instancesDir = getInstancesDir(); + const timeoutMs = options?.healthTimeoutMs ?? 800; + + try { + if (!fs.existsSync(instancesDir)) return; + const instanceIds = fs.readdirSync(instancesDir); + + for (const instanceId of instanceIds) { + const instanceDir = path.join(instancesDir, instanceId); + const configPath = path.join(instanceDir, 'config.json'); + + try { + if (!fs.existsSync(configPath)) { + safeRmDir(instanceDir); + continue; + } + + const content = fs.readFileSync(configPath, 'utf8'); + const parsed = JSON.parse(content) as Partial; + + const pid = typeof parsed.pid === 'number' ? parsed.pid : undefined; + const port = typeof parsed.port === 'number' ? parsed.port : undefined; + + if (isPidAlive(pid)) { + continue; + } + + const healthy = port ? await probeHealth(port, timeoutMs) : false; + if (healthy) { + // Something is listening, but the stored PID is gone. + // Keep the file to avoid accidental cleanup during PID reuse / permission edge-cases. + continue; + } + + safeRmDir(instanceDir); + console.log(`[MCP Config] Cleaned up stale instance ${instanceId}`); + } catch { + // Invalid config or unreadable dir: remove. + safeRmDir(instanceDir); + } + } + } catch (error) { + console.warn('[MCP Config] Failed during stale instance cleanup:', error); + } +} diff --git a/packages/mcp-server/src/index.ts b/packages/mcp-server/src/index.ts new file mode 100644 index 00000000..e12f52f2 --- /dev/null +++ b/packages/mcp-server/src/index.ts @@ -0,0 +1,2 @@ +export { CodeNomadMcpServer } from './server.js'; +export type { ServerConfig } from './server.js'; diff --git a/packages/mcp-server/src/pending.ts b/packages/mcp-server/src/pending.ts new file mode 100644 index 00000000..f6b2f3f2 --- /dev/null +++ b/packages/mcp-server/src/pending.ts @@ -0,0 +1,202 @@ +// TypeScript workaround - define types inline to avoid import issues + +export interface QuestionAnswer { + questionId: string; + values: string[]; + customText?: string; +} + +/** + * Pending request waiting for user response + */ +export interface PendingRequest { + id: string; + questions: any[]; + resolve: (result: PendingRequestResult) => void; + reject: (error: Error) => void; + createdAt: number; + timeout: NodeJS.Timeout | null; + // NEW FIELDS + renderTimeout: NodeJS.Timeout | null; // Timer for UI render confirmation + renderConfirmed: boolean; // Whether UI confirmed display + maxRetries: number; // Max retry attempts allowed + retryCount: number; // Current retry attempt number +} + +export interface PendingRequestResult { + answered: boolean; + cancelled: boolean; + timedOut: boolean; + // NEW FIELDS + shouldRetry: boolean; + retryReason: string | null; + renderConfirmed: boolean; + answers: QuestionAnswer[]; +} + +/** + * Manages pending question requests with Promise-based resolution + */ +export class PendingRequestManager { + private pending = new Map(); + + /** + * Add a pending request + */ + add(request: PendingRequest): void { + this.pending.set(request.id, request); + } + + /** + * Resolve a request with user answers + */ + resolve(id: string, answers: QuestionAnswer[]): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + + // Clear timeout if set + if (request.timeout) { + clearTimeout(request.timeout); + } + if (request.renderTimeout) { + clearTimeout(request.renderTimeout); + } + + // Resolve promise + request.resolve({ + answered: true, + cancelled: false, + timedOut: false, + shouldRetry: false, + retryReason: null, + renderConfirmed: request.renderConfirmed, + answers + }); + + // Remove from pending map + this.pending.delete(id); + return true; + } + + /** + * Reject a request with error + */ + reject(id: string, error: Error): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + + // Clear timeout if set + if (request.timeout) { + clearTimeout(request.timeout); + } + if (request.renderTimeout) { + clearTimeout(request.renderTimeout); + } + + const isCancelled = error.message === 'cancelled'; + const isTimedOut = error.message === 'Question timeout'; + const isRenderTimeout = error.message === 'Render timeout'; + + // Determine if we should retry + const shouldRetry = isRenderTimeout && request.retryCount < request.maxRetries; + const retryReason = shouldRetry + ? `UI failed to render question (attempt ${request.retryCount + 1}/${request.maxRetries})` + : isRenderTimeout + ? `Max retries (${request.maxRetries}) exceeded` + : null; + + // Reject promise + request.resolve({ + answered: false, + cancelled: isCancelled, + timedOut: isTimedOut, + shouldRetry, + retryReason, + renderConfirmed: request.renderConfirmed, + answers: [] + }); + + // Remove from pending map + this.pending.delete(id); + return true; + } + + /** + * Get a pending request by ID + */ + get(id: string): PendingRequest | undefined { + return this.pending.get(id); + } + + /** + * Get all pending requests + */ + getAll(): PendingRequest[] { + return Array.from(this.pending.values()); + } + + /** + * Cleanup old requests (older than specified age in ms) + */ + cleanup(maxAgeMs: number): void { + const now = Date.now(); + for (const [id, request] of Array.from(this.pending.entries())) { + if (now - request.createdAt > maxAgeMs) { + this.reject(id, new Error('Request expired')); + } + } + } + + /** + * Get pending request count + */ + count(): number { + return this.pending.size; + } + + /** + * Mark request as having confirmed render + */ + confirmRender(id: string): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + + // Clear render timeout + if (request.renderTimeout) { + clearTimeout(request.renderTimeout); + request.renderTimeout = null; + } + + request.renderConfirmed = true; + return true; + } + + /** + * Check if request can be retried + */ + canRetry(id: string): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + return request.retryCount < request.maxRetries; + } + + /** + * Increment retry count for a request + */ + incrementRetry(id: string): boolean { + const request = this.pending.get(id); + if (!request) { + return false; + } + request.retryCount += 1; + return true; + } +} diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts new file mode 100644 index 00000000..23ee9e27 --- /dev/null +++ b/packages/mcp-server/src/server.ts @@ -0,0 +1,487 @@ +import { createServer as createHttpServer, type Server as HttpServer, type IncomingMessage, type ServerResponse } from 'http'; +import * as crypto from 'crypto'; +import type { CnAskUserInput, CnAskUserOutput } from './tools/schemas.js'; +import { askUser, type QuestionBridge } from './tools/askUser.js'; +import { PendingRequestManager } from './pending.js'; + +export interface ServerConfig { + port?: number; + host?: string; +} + +export class CodeNomadMcpServer { + private httpServer: HttpServer | null = null; + private port: number | undefined; + private authToken: string | undefined = undefined; + private pendingManager: PendingRequestManager; + private bridge: QuestionBridge; + + constructor(config: ServerConfig = {}) { + this.pendingManager = new PendingRequestManager(); + this.bridge = { + sendQuestion: (requestId, questions, title) => { + console.log(`[MCP] Sending question to UI: ${requestId}`); + // TODO: Will be connected to Electron IPC bridge + }, + onAnswer: (callback) => { + console.log('[MCP] Answer handler registered'); + // TODO: Will be connected to Electron IPC bridge + }, + onCancel: (callback) => { + console.log('[MCP] Cancel handler registered'); + // TODO: Will be connected to Electron IPC bridge + }, + onRenderConfirmed: (callback) => { + console.log('[MCP] Render confirmation handler registered'); + // TODO: Will be connected to Electron IPC bridge + } + }; + } + + /** + * Start the MCP server + */ + async start(): Promise { + console.log('[MCP] Starting CodeNomad MCP Server (Raw JSON-RPC mode)...'); + + // Find available port + this.port = await this.findAvailablePort(); + console.log(`[MCP] Using port: ${this.port}`); + + // Generate auth token + this.authToken = crypto.randomBytes(32).toString('hex'); + console.log(`[MCP] Generated auth token: ${this.authToken.substring(0, 8)}...`); + + // Create HTTP server + this.httpServer = createHttpServer(async (req, res) => { + await this.handleHttpRequest(req, res); + }); + + // Start listening + await new Promise((resolve) => { + this.httpServer!.listen(this.port!, '127.0.0.1', () => { + console.log(`[MCP] HTTP server listening on http://127.0.0.1:${this.port}`); + resolve(); + }); + }); + } + + /** + * Stop the MCP server + */ + async stop(): Promise { + console.log('[MCP] Stopping CodeNomad MCP Server...'); + + // Cleanup pending requests + for (const req of this.pendingManager.getAll()) { + this.pendingManager.reject(req.id, new Error('Server shutting down')); + } + + // Close HTTP server + if (this.httpServer) { + this.httpServer.close(); + this.httpServer = null; + } + + console.log('[MCP] Server stopped'); + } + + /** + * Get server port + */ + getPort(): number | undefined { + return this.port; + } + + /** + * Get auth token + */ + getAuthToken(): string | undefined { + return this.authToken; + } + + /** + * Check if server is running + */ + isRunning(): boolean { + return this.httpServer !== null; + } + + /** + * Connect an external IPC bridge to handle questions + * This allows the main process to provide IPC communication + */ + connectBridge(bridge: QuestionBridge): void { + console.log('[MCP] Connecting external IPC bridge'); + this.bridge = bridge; + } + + /** + * Get the pending request manager for external use + */ + getPendingManager(): PendingRequestManager { + return this.pendingManager; + } + + /** + * Get tool schema for ask_user + */ + private getAskUserToolSchema() { + return { + name: "ask_user", + description: `Ask the user questions through CodeNomad's interface. + +IMPORTANT INSTRUCTIONS FOR AI AGENT: +1. This tool blocks until the user responds or a timeout occurs. +2. If the response has shouldRetry=true, you MUST retry calling this tool immediately with the same parameters. +3. If shouldRetry=false and timedOut=true, inform the user the question timed out and ask if they want to continue. +4. If shouldRetry=false and max retries were exceeded, inform the user there was a technical issue displaying the question. + +The tool will automatically retry up to 3 times if the UI fails to render the question. You only need to retry when shouldRetry=true is returned.`, + inputSchema: { + type: "object", + properties: { + questions: { + type: "array", + description: "Array of questions to ask user", + items: { + type: "object", + properties: { + question: { type: "string" }, + type: { type: "string", enum: ["text", "select", "multi-select", "confirm"] }, + options: { type: "array", items: { type: "string" } }, + required: { type: "boolean" }, + placeholder: { type: "string" } + }, + required: ["question"] + }, + minItems: 1, + maxItems: 10 + }, + title: { + type: "string", + description: "Optional title for question dialog", + maxLength: 100 + }, + maxRetries: { + type: "integer", + description: "Maximum retry attempts if UI fails to render (0-5, default: 3)", + minimum: 0, + maximum: 5, + default: 3 + }, + renderTimeout: { + type: "integer", + description: "Milliseconds to wait for UI render confirmation (10000-60000, default: 30000)", + minimum: 10000, + maximum: 60000, + default: 30000 + } + }, + required: ["questions"] + } + }; + } + + /** + * Handle HTTP requests with raw JSON-RPC + */ + private async handleHttpRequest(req: IncomingMessage, res: ServerResponse): Promise { + const url = req.url || '/'; + const method = req.method || 'GET'; + + console.log(`[MCP] Request: ${method} ${url}`); + console.log(`[MCP] Headers:`, { + 'content-type': req.headers['content-type'], + 'content-length': req.headers['content-length'], + 'transfer-encoding': req.headers['transfer-encoding'] + }); + + // Health check endpoint + if (url === '/health') { + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ + status: 'running', + port: this.port, + pendingRequests: this.pendingManager.count() + })); + return; + } + + // Handle CORS preflight + if (method === 'OPTIONS') { + res.writeHead(204, { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Accept', + 'Access-Control-Max-Age': '86400' + }); + res.end(); + return; + } + + // Add CORS headers to all responses + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Accept'); + + // Handle POST requests for JSON-RPC + if (method === 'POST') { + try { + const body = await this.readJsonBody(req); + console.log(`[MCP] Parsed body:`, body ? JSON.stringify(body).substring(0, 200) : 'null'); + + // Handle JSON-RPC requests + if (body && typeof body === 'object') { + const jsonrpc = await this.handleJsonRpc(body); + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify(jsonrpc)); + return; + } else { + console.log(`[MCP] Body is not an object:`, typeof body); + } + } catch (error) { + console.error(`[MCP] Error handling request:`, error); + if (!res.headersSent) { + res.writeHead(500, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ + jsonrpc: '2.0', + id: null, + error: { + code: -32603, + message: 'Internal error', + data: error instanceof Error ? error.message : String(error) + } + })); + } + return; + } + } + + // 404 for other requests + if (!res.headersSent) { + res.writeHead(404, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: 'Not found' })); + } + } + + /** + * Read JSON body from request + */ + private async readJsonBody(req: IncomingMessage): Promise { + return new Promise((resolve, reject) => { + let data = ''; + let dataReceived = false; + + const timeout = setTimeout(() => { + console.error(`[MCP] readJsonBody timeout: received=${dataReceived}, data length=${data.length}`); + reject(new Error('Request body read timeout')); + }, 5000); + + req.on('data', chunk => { + dataReceived = true; + data += chunk; + }); + + req.on('end', () => { + clearTimeout(timeout); + console.log(`[MCP] Request body read complete: ${data.length} bytes`); + try { + const parsed = data ? JSON.parse(data) : null; + console.log(`[MCP] JSON parsed successfully:`, parsed ? 'object present' : 'null'); + resolve(parsed); + } catch (error) { + console.error(`[MCP] JSON parse error:`, error); + reject(error); + } + }); + + req.on('error', error => { + clearTimeout(timeout); + console.error(`[MCP] Request stream error:`, error); + reject(error); + }); + }); + } + + /** + * Handle JSON-RPC requests + */ + private async handleJsonRpc(request: any): Promise { + const { jsonrpc, id, method, params } = request; + + // Validate JSON-RPC 2.0 basic structure + if (jsonrpc !== '2.0') { + return { + jsonrpc: '2.0', + id, + error: { + code: -32600, + message: 'Invalid Request' + } + }; + } + + try { + switch (method) { + case 'tools/list': + return this.handleToolsList(id); + + case 'tools/call': + return this.handleToolsCall(id, params); + + case 'initialize': + return this.handleInitialize(id); + + default: + return { + jsonrpc: '2.0', + id, + error: { + code: -32601, + message: 'Method not found', + data: method + } + }; + } + } catch (error) { + console.error(`[MCP] Error handling ${method}:`, error); + return { + jsonrpc: '2.0', + id, + error: { + code: -32603, + message: 'Internal error', + data: error instanceof Error ? error.message : String(error) + } + }; + } + } + + /** + * Handle initialize method + */ + private handleInitialize(id: string | number | undefined): any { + console.log('[MCP] Handling initialize'); + return { + jsonrpc: '2.0', + id, + result: { + protocolVersion: '2024-11-05', + capabilities: { + tools: {} + }, + serverInfo: { + name: 'CodeNomad Ask User', + version: '1.0.0' + } + } + }; + } + + /** + * Handle tools/list method + */ + private handleToolsList(id: string | number | undefined): any { + console.log('[MCP] Handling tools/list'); + return { + jsonrpc: '2.0', + id, + result: { + tools: [this.getAskUserToolSchema()] + } + }; + } + + /** + * Handle tools/call method + */ + private async handleToolsCall(id: string | number | undefined, params: any): Promise { + const { name, arguments: args } = params; + + console.log(`[MCP] Handling tools/call: ${name}`); + + if (name !== 'ask_user') { + return { + jsonrpc: '2.0', + id, + error: { + code: -32602, + message: 'Invalid params', + data: `Unknown tool: ${name}` + } + }; + } + + try { + // Validate input manually + const input = args as CnAskUserInput; + + const isDev = process.env.NODE_ENV !== 'production'; + if (isDev) { + console.log(`[🔧 MCP TOOL INVOKED] ask_user (ZERO-COST)`, { + requestId: id, + questionCount: input.questions?.length || 0, + hasTitle: !!input.title, + timestamp: new Date().toISOString() + }); + } + + const result = await askUser(input, this.bridge, this.pendingManager); + + // Log the structured result for easier tracing during debugging + if (isDev) { + console.log(`[🔧 MCP TOOL RESULT] ask_user completed for ${id}:`, result); + } + + return { + jsonrpc: '2.0', + id, + result: { + content: [{ + type: 'text', + text: JSON.stringify(result) + }] + } + }; + } catch (error) { + console.error(`[MCP] Tool error:`, error); + return { + jsonrpc: '2.0', + id, + result: { + content: [{ + type: 'text', + text: JSON.stringify({ + answered: false, + cancelled: false, + timedOut: false, + answers: [], + error: error instanceof Error ? error.message : String(error) + }) + }], + isError: true + } + }; + } + } + + /** + * Find an available port + */ + private async findAvailablePort(): Promise { + return new Promise((resolve, reject) => { + const server = createHttpServer(); + server.listen(0, '127.0.0.1', () => { + const address = server.address(); + if (address && typeof address !== 'string') { + const port = address.port; + server.close(() => resolve(port)); + } else { + reject(new Error('Failed to get port')); + } + }); + server.on('error', reject); + }); + } +} diff --git a/packages/mcp-server/src/tools/askUser.ts b/packages/mcp-server/src/tools/askUser.ts new file mode 100644 index 00000000..3e49eb5b --- /dev/null +++ b/packages/mcp-server/src/tools/askUser.ts @@ -0,0 +1,96 @@ +import type { CnAskUserInput, CnAskUserOutput, QuestionInfo } from './schemas.js'; +import type { PendingRequestManager } from '../pending.js'; + +export function generateRequestId(): string { + return `req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`; +} + +/** + * Main ask_user tool implementation + * Blocks until user responds or timeout/cancellation + */ +export async function askUser( + input: CnAskUserInput, + bridge: QuestionBridge, + pendingManager: PendingRequestManager +): Promise { + + const requestId = generateRequestId(); + const maxRetries = input.maxRetries ?? 3; + const renderTimeoutMs = input.renderTimeout ?? 30000; + + console.log(`[MCP] ask_user called: ${requestId}`, { + questions: input.questions.length, + title: input.title ?? null, + maxRetries, + renderTimeoutMs + }); + + // Generate IDs for questions if not provided + const questionsWithIds: Array = input.questions.map((q, index) => ({ + ...q, + id: q.id || `${requestId}_${index}` + })); + + // Create Promise that blocks until response + return new Promise((resolve) => { + // Create render timeout + const renderTimer = setTimeout(() => { + console.log(`[MCP] Render timeout for ${requestId} - UI did not confirm display`); + + // Check if we can retry + const pending = pendingManager.get(requestId); + if (pending && pendingManager.canRetry(requestId)) { + // Increment retry and reject with render timeout + pendingManager.incrementRetry(requestId); + pendingManager.reject(requestId, new Error('Render timeout')); + } else { + // Max retries exceeded or no pending request + pendingManager.reject(requestId, new Error('Render timeout - max retries exceeded')); + } + }, renderTimeoutMs); + + // Add to pending manager + pendingManager.add({ + id: requestId, + questions: questionsWithIds, + resolve: (result) => resolve(result), + reject: (error) => { + console.error(`[MCP] Request rejected: ${requestId}`, error); + const isRenderTimeout = error.message.includes('Render timeout'); + resolve({ + answered: false, + cancelled: error.message === 'cancelled', + timedOut: error.message === 'Question timeout', + shouldRetry: isRenderTimeout && !error.message.includes('max retries'), + retryReason: isRenderTimeout + ? error.message.includes('max retries') + ? `Max retries (${maxRetries}) exceeded` + : 'UI failed to render question within timeout' + : null, + renderConfirmed: false, + answers: [] + }); + }, + createdAt: Date.now(), + timeout: null, // Will be set after render confirmation + renderTimeout: renderTimer, + renderConfirmed: false, + maxRetries, + retryCount: 0 + }); + + // Send question to bridge + bridge.sendQuestion(requestId, questionsWithIds, input.title); + }); +} + +/** + * Bridge interface for communicating with UI + */ +export interface QuestionBridge { + sendQuestion(requestId: string, questions: Array, title?: string): void; + onAnswer(callback: (requestId: string, answers: any[]) => void): void; + onCancel(callback: (requestId: string) => void): void; + onRenderConfirmed(callback: (requestId: string) => void): void; // NEW +} diff --git a/packages/mcp-server/src/tools/schemas.ts b/packages/mcp-server/src/tools/schemas.ts new file mode 100644 index 00000000..1d4fbc73 --- /dev/null +++ b/packages/mcp-server/src/tools/schemas.ts @@ -0,0 +1,67 @@ +import { z } from 'zod'; + +/** + * Question types supported by the ask_user tool + */ +export type QuestionType = 'text' | 'select' | 'multi-select' | 'confirm'; + +/** + * Single question definition + */ +export const QuestionInfoSchema = z.object({ + id: z.string().optional(), + question: z.string().min(1).max(1000), + type: z.enum(['text', 'select', 'multi-select', 'confirm']).optional().default('text'), + options: z.array(z.string()).optional(), + required: z.boolean().optional().default(true), + placeholder: z.string().optional(), +}).refine( + (data) => { + // Options required for select types + if (data.type === 'select' || data.type === 'multi-select') { + return data.options && data.options.length > 0; + } + return true; + }, + { message: "Options required for select/multi-select types" } +); + +/** + * Tool input schema for ask_user + */ +export const CnAskUserInputSchema = z.object({ + questions: z.array(QuestionInfoSchema).min(1).max(10), + title: z.string().max(100).optional(), + maxRetries: z.number().int().min(0).max(5).optional().default(3) + .describe("Maximum retry attempts if UI fails to render (0-5, default: 3)"), + renderTimeout: z.number().int().min(10000).max(60000).optional().default(30000) + .describe("Milliseconds to wait for UI render confirmation (10-60s, default: 30s)"), +}); + +/** + * Tool output schema + */ +export const QuestionAnswerSchema = z.object({ + questionId: z.string(), + values: z.array(z.string()), + customText: z.string().optional(), +}); + +export const CnAskUserOutputSchema = z.object({ + answered: z.boolean(), + cancelled: z.boolean(), + timedOut: z.boolean(), + shouldRetry: z.boolean() + .describe("If true, the agent MUST retry this question immediately in the same session"), + retryReason: z.string().nullable() + .describe("Human-readable reason for retry (for debugging)"), + renderConfirmed: z.boolean() + .describe("Whether the UI confirmed the question was displayed"), + answers: z.array(QuestionAnswerSchema), +}); + +// Export inferred types +export type QuestionInfo = z.infer; +export type CnAskUserInput = z.infer; +export type QuestionAnswer = z.infer; +export type CnAskUserOutput = z.infer; diff --git a/packages/mcp-server/tsconfig.json b/packages/mcp-server/tsconfig.json new file mode 100644 index 00000000..50cab641 --- /dev/null +++ b/packages/mcp-server/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "lib": ["ES2022", "DOM"], + "outDir": "./dist", + "rootDir": "./src", + "composite": true, + "declaration": true, + "declarationMap": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "noImplicitAny": false, + "moduleResolution": "node", + "strict": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/mcp-server/tsconfig.tsbuildinfo b/packages/mcp-server/tsconfig.tsbuildinfo new file mode 100644 index 00000000..bb24f108 --- /dev/null +++ b/packages/mcp-server/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../node_modules/typescript/lib/lib.esnext.float16.d.ts","../../node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/zod/v3/helpers/typealiases.d.cts","../../node_modules/zod/v3/helpers/util.d.cts","../../node_modules/zod/v3/index.d.cts","../../node_modules/zod/v3/zoderror.d.cts","../../node_modules/zod/v3/locales/en.d.cts","../../node_modules/zod/v3/errors.d.cts","../../node_modules/zod/v3/helpers/parseutil.d.cts","../../node_modules/zod/v3/helpers/enumutil.d.cts","../../node_modules/zod/v3/helpers/errorutil.d.cts","../../node_modules/zod/v3/helpers/partialutil.d.cts","../../node_modules/zod/v3/standard-schema.d.cts","../../node_modules/zod/v3/types.d.cts","../../node_modules/zod/v3/external.d.cts","../../node_modules/zod/index.d.cts","./src/tools/schemas.ts","./src/pending.ts","./src/tools/askuser.ts","./src/server.ts","./src/index.ts","./src/__tests__/askuser.test.ts","../../node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/@types/node/globals.typedarray.d.ts","../../node_modules/@types/node/buffer.buffer.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/web-globals/abortcontroller.d.ts","../../node_modules/@types/node/web-globals/blob.d.ts","../../node_modules/@types/node/web-globals/console.d.ts","../../node_modules/@types/node/web-globals/crypto.d.ts","../../node_modules/@types/node/web-globals/domexception.d.ts","../../node_modules/@types/node/web-globals/encoding.d.ts","../../node_modules/@types/node/web-globals/events.d.ts","../../node_modules/buffer/index.d.ts","../../node_modules/undici-types/utility.d.ts","../../node_modules/undici-types/header.d.ts","../../node_modules/undici-types/readable.d.ts","../../node_modules/undici-types/fetch.d.ts","../../node_modules/undici-types/formdata.d.ts","../../node_modules/undici-types/connector.d.ts","../../node_modules/undici-types/client-stats.d.ts","../../node_modules/undici-types/client.d.ts","../../node_modules/undici-types/errors.d.ts","../../node_modules/undici-types/dispatcher.d.ts","../../node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/undici-types/global-origin.d.ts","../../node_modules/undici-types/pool-stats.d.ts","../../node_modules/undici-types/pool.d.ts","../../node_modules/undici-types/handlers.d.ts","../../node_modules/undici-types/balanced-pool.d.ts","../../node_modules/undici-types/h2c-client.d.ts","../../node_modules/undici-types/agent.d.ts","../../node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/undici-types/mock-call-history.d.ts","../../node_modules/undici-types/mock-agent.d.ts","../../node_modules/undici-types/mock-client.d.ts","../../node_modules/undici-types/mock-pool.d.ts","../../node_modules/undici-types/snapshot-agent.d.ts","../../node_modules/undici-types/mock-errors.d.ts","../../node_modules/undici-types/proxy-agent.d.ts","../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/undici-types/retry-handler.d.ts","../../node_modules/undici-types/retry-agent.d.ts","../../node_modules/undici-types/api.d.ts","../../node_modules/undici-types/cache-interceptor.d.ts","../../node_modules/undici-types/interceptors.d.ts","../../node_modules/undici-types/util.d.ts","../../node_modules/undici-types/cookies.d.ts","../../node_modules/undici-types/patch.d.ts","../../node_modules/undici-types/websocket.d.ts","../../node_modules/undici-types/eventsource.d.ts","../../node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/undici-types/content-type.d.ts","../../node_modules/undici-types/cache.d.ts","../../node_modules/undici-types/index.d.ts","../../node_modules/@types/node/web-globals/fetch.d.ts","../../node_modules/@types/node/web-globals/importmeta.d.ts","../../node_modules/@types/node/web-globals/messaging.d.ts","../../node_modules/@types/node/web-globals/navigator.d.ts","../../node_modules/@types/node/web-globals/performance.d.ts","../../node_modules/@types/node/web-globals/storage.d.ts","../../node_modules/@types/node/web-globals/streams.d.ts","../../node_modules/@types/node/web-globals/timers.d.ts","../../node_modules/@types/node/web-globals/url.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/inspector.generated.d.ts","../../node_modules/@types/node/inspector/promises.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/path/posix.d.ts","../../node_modules/@types/node/path/win32.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/quic.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/sea.d.ts","../../node_modules/@types/node/sqlite.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/test/reporters.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/util/types.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/electron/electron.d.ts","./src/bridge/ipc.ts","./src/__tests__/ipc-bridge.test.ts","./src/__tests__/ipc-setup.test.ts","./src/__tests__/pending.test.ts","./src/__tests__/schemas.test.ts","./src/bridge/types.ts","./src/bridge/renderer.ts","./src/config/registration.ts","../../node_modules/@babel/types/lib/index.d.ts","../../node_modules/@types/babel__generator/index.d.ts","../../node_modules/@babel/parser/typings/babel-parser.d.ts","../../node_modules/@types/babel__template/index.d.ts","../../node_modules/@types/babel__traverse/index.d.ts","../../node_modules/@types/babel__core/index.d.ts","../../node_modules/keyv/src/index.d.ts","../../node_modules/@types/http-cache-semantics/index.d.ts","../../node_modules/@types/responselike/index.d.ts","../../node_modules/@types/cacheable-request/index.d.ts","../../node_modules/@types/ms/index.d.ts","../../node_modules/@types/debug/index.d.ts","../../node_modules/@types/trusted-types/lib/index.d.ts","../../node_modules/@types/trusted-types/index.d.ts","../../node_modules/@types/dompurify/index.d.ts","../../node_modules/@types/estree/index.d.ts","../../node_modules/@types/fs-extra/index.d.ts","../../node_modules/@types/unist/index.d.ts","../../node_modules/@types/hast/index.d.ts","../../node_modules/@types/keyv/index.d.ts","../../node_modules/@types/mdast/index.d.ts","../../node_modules/xmlbuilder/typings/index.d.ts","../../node_modules/@types/plist/index.d.ts","../../node_modules/@types/resolve/index.d.ts","../../node_modules/@types/verror/index.d.ts","../../node_modules/@types/yauzl/index.d.ts"],"fileIdsList":[[83,146,154,158,161,163,164,165,177,212],[83,146,154,158,161,163,164,165,177],[83,146,154,158,161,163,164,165,177,212,213,214,215,216],[83,146,154,158,161,163,164,165,177,212,214],[83,146,154,157,158,160,161,163,164,165,177,194,202,218,219,220],[83,146,154,158,161,163,164,165,177,222],[83,146,154,158,161,163,164,165,177,225],[83,146,154,158,161,163,164,165,177,202],[83,146,154,158,161,163,164,165,177,229],[83,146,154,157,158,161,163,164,165,177,202],[83,143,144,146,154,158,161,163,164,165,177],[83,145,146,154,158,161,163,164,165,177],[146,154,158,161,163,164,165,177],[83,146,154,158,161,163,164,165,177,185],[83,146,147,152,154,157,158,161,163,164,165,167,177,182,194],[83,146,147,148,154,157,158,161,163,164,165,177],[83,146,149,154,158,161,163,164,165,177,195],[83,146,150,151,154,158,161,163,164,165,168,177],[83,146,151,154,158,161,163,164,165,177,182,191],[83,146,152,154,157,158,161,163,164,165,167,177],[83,145,146,153,154,158,161,163,164,165,177],[83,146,154,155,158,161,163,164,165,177],[83,146,154,156,157,158,161,163,164,165,177],[83,145,146,154,157,158,161,163,164,165,177],[83,146,154,157,158,159,161,163,164,165,177,182,194],[83,146,154,157,158,159,161,163,164,165,177,182,185],[83,133,146,154,157,158,160,161,163,164,165,167,177,182,194],[83,146,154,157,158,160,161,163,164,165,167,177,182,191,194],[83,146,154,158,160,161,162,163,164,165,177,182,191,194],[81,82,83,84,85,86,87,88,89,90,91,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201],[83,146,154,157,158,161,163,164,165,177],[83,146,154,158,161,163,165,177],[83,146,154,158,161,163,164,165,166,177,194],[83,146,154,157,158,161,163,164,165,167,177,182],[83,146,154,158,161,163,164,165,168,177],[83,146,154,158,161,163,164,165,169,177],[83,146,154,157,158,161,163,164,165,172,177],[83,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201],[83,146,154,158,161,163,164,165,174,177],[83,146,154,158,161,163,164,165,175,177],[83,146,151,154,158,161,163,164,165,167,177,185],[83,146,154,157,158,161,163,164,165,177,178],[83,146,154,158,161,163,164,165,177,179,195,198],[83,146,154,157,158,161,163,164,165,177,182,184,185],[83,146,154,158,161,163,164,165,177,183,185],[83,146,154,158,161,163,164,165,177,185,195],[83,146,154,158,161,163,164,165,177,186],[83,143,146,154,158,161,163,164,165,177,182,188],[83,146,154,158,161,163,164,165,177,182,187],[83,146,154,157,158,161,163,164,165,177,189,190],[83,146,154,158,161,163,164,165,177,189,190],[83,146,151,154,158,161,163,164,165,167,177,182,191],[83,146,154,158,161,163,164,165,177,192],[83,146,154,158,161,163,164,165,167,177,193],[83,146,154,158,160,161,163,164,165,175,177,194],[83,146,154,158,161,163,164,165,177,195,196],[83,146,151,154,158,161,163,164,165,177,196],[83,146,154,158,161,163,164,165,177,182,197],[83,146,154,158,161,163,164,165,166,177,198],[83,146,154,158,161,163,164,165,177,199],[83,146,149,154,158,161,163,164,165,177],[83,146,151,154,158,161,163,164,165,177],[83,146,154,158,161,163,164,165,177,195],[83,133,146,154,158,161,163,164,165,177],[83,146,154,158,161,163,164,165,177,194],[83,146,154,158,161,163,164,165,177,200],[83,146,154,158,161,163,164,165,172,177],[83,146,154,158,161,163,164,165,177,190],[83,133,146,154,157,158,159,161,163,164,165,172,177,182,185,194,197,198,200],[83,146,154,158,161,163,164,165,177,182,201],[83,146,154,158,161,163,164,165,177,202,233],[83,146,154,158,160,161,163,164,165,177,182,202],[83,146,154,158,161,163,164,165,177,224],[83,146,154,157,158,161,163,164,165,177,182,202],[83,99,102,105,106,146,154,158,161,163,164,165,177,194],[83,102,146,154,158,161,163,164,165,177,182,194],[83,102,106,146,154,158,161,163,164,165,177,194],[83,146,154,158,161,163,164,165,177,182],[83,96,146,154,158,161,163,164,165,177],[83,100,146,154,158,161,163,164,165,177],[83,98,99,102,146,154,158,161,163,164,165,177,194],[83,146,154,158,161,163,164,165,167,177,191],[83,96,146,154,158,161,163,164,165,177,202],[83,98,102,146,154,158,161,163,164,165,167,177,194],[83,93,94,95,97,101,146,154,157,158,161,163,164,165,177,182,194],[83,102,110,118,146,154,158,161,163,164,165,177],[83,94,100,146,154,158,161,163,164,165,177],[83,102,127,128,146,154,158,161,163,164,165,177],[83,94,97,102,146,154,158,161,163,164,165,177,185,194,202],[83,102,146,154,158,161,163,164,165,177],[83,98,102,146,154,158,161,163,164,165,177,194],[83,93,146,154,158,161,163,164,165,177],[83,96,97,98,100,101,102,103,104,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,128,129,130,131,132,146,154,158,161,163,164,165,177],[83,102,120,123,146,154,158,161,163,164,165,177],[83,102,110,111,112,146,154,158,161,163,164,165,177],[83,100,102,111,113,146,154,158,161,163,164,165,177],[83,101,146,154,158,161,163,164,165,177],[83,94,96,102,146,154,158,161,163,164,165,177],[83,102,106,111,113,146,154,158,161,163,164,165,177],[83,106,146,154,158,161,163,164,165,177],[83,100,102,105,146,154,158,161,163,164,165,177,194],[83,94,98,102,110,146,154,158,161,163,164,165,177],[83,102,120,146,154,158,161,163,164,165,177],[83,113,146,154,158,161,163,164,165,177],[83,96,102,127,146,154,158,161,163,164,165,177,185,200,202],[73,83,146,154,158,161,163,164,165,177],[64,65,83,146,154,158,161,163,164,165,177],[61,62,64,66,67,72,83,146,154,158,161,163,164,165,177],[62,64,83,146,154,158,161,163,164,165,177],[72,83,146,154,158,161,163,164,165,177],[64,83,146,154,158,161,163,164,165,177],[61,62,64,67,68,69,70,71,83,146,154,158,161,163,164,165,177],[61,62,63,83,146,154,158,161,163,164,165,177],[75,76,77,83,143,146,154,158,161,163,164,165,177,187],[76,83,143,146,154,158,161,163,164,165,177,187,204],[83,143,146,154,158,161,163,164,165,177,187,204],[76,83,143,146,154,158,161,163,164,165,177,187],[75,83,143,146,154,158,161,163,164,165,177,187],[75,76,77,83,146,154,158,161,163,164,165,177,203],[75,83,146,154,158,161,163,164,165,177,209],[75,83,146,154,158,161,163,164,165,177],[83,146,151,154,158,160,161,163,164,165,168,169,177,194],[78,83,146,154,158,161,163,164,165,177],[75,76,77,83,146,151,154,158,160,161,163,164,165,177],[75,76,83,146,154,158,161,163,164,165,177],[74,83,146,154,158,161,163,164,165,177]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"d3cfde44f8089768ebb08098c96d01ca260b88bccf238d55eee93f1c620ff5a5","impliedFormat":1},{"version":"293eadad9dead44c6fd1db6de552663c33f215c55a1bfa2802a1bceed88ff0ec","impliedFormat":1},{"version":"833e92c058d033cde3f29a6c7603f517001d1ddd8020bc94d2067a3bc69b2a8e","impliedFormat":1},{"version":"08b2fae7b0f553ad9f79faec864b179fc58bc172e295a70943e8585dd85f600c","impliedFormat":1},{"version":"f12edf1672a94c578eca32216839604f1e1c16b40a1896198deabf99c882b340","impliedFormat":1},{"version":"e3498cf5e428e6c6b9e97bd88736f26d6cf147dedbfa5a8ad3ed8e05e059af8a","impliedFormat":1},{"version":"dba3f34531fd9b1b6e072928b6f885aa4d28dd6789cbd0e93563d43f4b62da53","impliedFormat":1},{"version":"f672c876c1a04a223cf2023b3d91e8a52bb1544c576b81bf64a8fec82be9969c","impliedFormat":1},{"version":"e4b03ddcf8563b1c0aee782a185286ed85a255ce8a30df8453aade2188bbc904","impliedFormat":1},{"version":"2329d90062487e1eaca87b5e06abcbbeeecf80a82f65f949fd332cfcf824b87b","impliedFormat":1},{"version":"25b3f581e12ede11e5739f57a86e8668fbc0124f6649506def306cad2c59d262","impliedFormat":1},{"version":"4fdb529707247a1a917a4626bfb6a293d52cd8ee57ccf03830ec91d39d606d6d","impliedFormat":1},{"version":"a9ebb67d6bbead6044b43714b50dcb77b8f7541ffe803046fdec1714c1eba206","impliedFormat":1},{"version":"5780b706cece027f0d4444fbb4e1af62dc51e19da7c3d3719f67b22b033859b9","impliedFormat":1},{"version":"30e462277e91d80815bdd79f5d638c9d2a2bd03fadd73da6965f8f1da0c030a3","signature":"0db6915e5f2d4a14817d5db90128d46354346f16f277c6c30b1cf71bccf5ed16"},{"version":"75c00c94682085ba47b0b18ad18172ab426c4d5ab19da5f44707fe9e6c4832db","signature":"7b47727ed69f58bba93952bc4eaa37e331b8cf91589c41fc1636b4828c03e075"},{"version":"5bb786d2b7982e8db815b3b2f71fad3e017ab181c04a48eed5c4acd2c7fa5cd4","signature":"45f1299f124e26d46d8e4116e255dfd555243b38ed9aa7b51ed84047388cf2fb"},{"version":"e1a4e96e6358e804e969a542d034911962b8334d6225a69ca16070e899dadaf5","signature":"7a9c80a51016a24715cec6d4f74508bd81a3cdf4305a525d90af6d73f87aca9e"},"ac366c4a8c2403e80b43b8c04727cb4d61a6f5d0c01ba522039d5c1c9db5a5ca",{"version":"d466e15759e22e88d567312c23ee77344b69d06904f900434eb31ec8894c8301","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"0ccdaa19852d25ecd84eec365c3bfa16e7859cadecf6e9ca6d0dbbbee439743f","affectsGlobalScope":true,"impliedFormat":1},{"version":"438b41419b1df9f1fbe33b5e1b18f5853432be205991d1b19f5b7f351675541e","affectsGlobalScope":true,"impliedFormat":1},{"version":"096116f8fedc1765d5bd6ef360c257b4a9048e5415054b3bf3c41b07f8951b0b","affectsGlobalScope":true,"impliedFormat":1},{"version":"e5e01375c9e124a83b52ee4b3244ed1a4d214a6cfb54ac73e164a823a4a7860a","affectsGlobalScope":true,"impliedFormat":1},{"version":"f90ae2bbce1505e67f2f6502392e318f5714bae82d2d969185c4a6cecc8af2fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"4b58e207b93a8f1c88bbf2a95ddc686ac83962b13830fe8ad3f404ffc7051fb4","affectsGlobalScope":true,"impliedFormat":1},{"version":"1fefabcb2b06736a66d2904074d56268753654805e829989a46a0161cd8412c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"c18a99f01eb788d849ad032b31cafd49de0b19e083fe775370834c5675d7df8e","affectsGlobalScope":true,"impliedFormat":1},{"version":"5247874c2a23b9a62d178ae84f2db6a1d54e6c9a2e7e057e178cc5eea13757fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"cdcf9ea426ad970f96ac930cd176d5c69c6c24eebd9fc580e1572d6c6a88f62c","impliedFormat":1},{"version":"23cd712e2ce083d68afe69224587438e5914b457b8acf87073c22494d706a3d0","impliedFormat":1},{"version":"487b694c3de27ddf4ad107d4007ad304d29effccf9800c8ae23c2093638d906a","impliedFormat":1},{"version":"3a80bc85f38526ca3b08007ee80712e7bb0601df178b23fbf0bf87036fce40ce","impliedFormat":1},{"version":"ccf4552357ce3c159ef75f0f0114e80401702228f1898bdc9402214c9499e8c0","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"68834d631c8838c715f225509cfc3927913b9cc7a4870460b5b60c8dbdb99baf","impliedFormat":1},{"version":"2931540c47ee0ff8a62860e61782eb17b155615db61e36986e54645ec67f67c2","impliedFormat":1},{"version":"ccab02f3920fc75c01174c47fcf67882a11daf16baf9e81701d0a94636e94556","impliedFormat":1},{"version":"f6faf5f74e4c4cc309a6c6a6c4da02dbb840be5d3e92905a23dcd7b2b0bd1986","impliedFormat":1},{"version":"ea6bc8de8b59f90a7a3960005fd01988f98fd0784e14bc6922dde2e93305ec7d","impliedFormat":1},{"version":"36107995674b29284a115e21a0618c4c2751b32a8766dd4cb3ba740308b16d59","impliedFormat":1},{"version":"914a0ae30d96d71915fc519ccb4efbf2b62c0ddfb3a3fc6129151076bc01dc60","impliedFormat":1},{"version":"33e981bf6376e939f99bd7f89abec757c64897d33c005036b9a10d9587d80187","impliedFormat":1},{"version":"7fd1b31fd35876b0aa650811c25ec2c97a3c6387e5473eb18004bed86cdd76b6","impliedFormat":1},{"version":"b41767d372275c154c7ea6c9d5449d9a741b8ce080f640155cc88ba1763e35b3","impliedFormat":1},{"version":"3bacf516d686d08682751a3bd2519ea3b8041a164bfb4f1d35728993e70a2426","impliedFormat":1},{"version":"7fb266686238369442bd1719bc0d7edd0199da4fb8540354e1ff7f16669b4323","impliedFormat":1},{"version":"0a60a292b89ca7218b8616f78e5bbd1c96b87e048849469cccb4355e98af959a","impliedFormat":1},{"version":"0b6e25234b4eec6ed96ab138d96eb70b135690d7dd01f3dd8a8ab291c35a683a","impliedFormat":1},{"version":"9666f2f84b985b62400d2e5ab0adae9ff44de9b2a34803c2c5bd3c8325b17dc0","impliedFormat":1},{"version":"40cd35c95e9cf22cfa5bd84e96408b6fcbca55295f4ff822390abb11afbc3dca","impliedFormat":1},{"version":"b1616b8959bf557feb16369c6124a97a0e74ed6f49d1df73bb4b9ddf68acf3f3","impliedFormat":1},{"version":"5b03a034c72146b61573aab280f295b015b9168470f2df05f6080a2122f9b4df","impliedFormat":1},{"version":"40b463c6766ca1b689bfcc46d26b5e295954f32ad43e37ee6953c0a677e4ae2b","impliedFormat":1},{"version":"249b9cab7f5d628b71308c7d9bb0a808b50b091e640ba3ed6e2d0516f4a8d91d","impliedFormat":1},{"version":"80aae6afc67faa5ac0b32b5b8bc8cc9f7fa299cff15cf09cc2e11fd28c6ae29e","impliedFormat":1},{"version":"f473cd2288991ff3221165dcf73cd5d24da30391f87e85b3dd4d0450c787a391","impliedFormat":1},{"version":"499e5b055a5aba1e1998f7311a6c441a369831c70905cc565ceac93c28083d53","impliedFormat":1},{"version":"54c3e2371e3d016469ad959697fd257e5621e16296fa67082c2575d0bf8eced0","impliedFormat":1},{"version":"beb8233b2c220cfa0feea31fbe9218d89fa02faa81ef744be8dce5acb89bb1fd","impliedFormat":1},{"version":"c183b931b68ad184bc8e8372bf663f3d33304772fb482f29fb91b3c391031f3e","impliedFormat":1},{"version":"5d0375ca7310efb77e3ef18d068d53784faf62705e0ad04569597ae0e755c401","impliedFormat":1},{"version":"59af37caec41ecf7b2e76059c9672a49e682c1a2aa6f9d7dc78878f53aa284d6","impliedFormat":1},{"version":"addf417b9eb3f938fddf8d81e96393a165e4be0d4a8b6402292f9c634b1cb00d","impliedFormat":1},{"version":"48cc3ec153b50985fb95153258a710782b25975b10dd4ac8a4f3920632d10790","impliedFormat":1},{"version":"adf27937dba6af9f08a68c5b1d3fce0ca7d4b960c57e6d6c844e7d1a8e53adae","impliedFormat":1},{"version":"e1528ca65ac90f6fa0e4a247eb656b4263c470bb22d9033e466463e13395e599","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"866078923a56d026e39243b4392e282c1c63159723996fa89243140e1388a98d","impliedFormat":1},{"version":"c3f5289820990ab66b70c7fb5b63cb674001009ff84b13de40619619a9c8175f","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3275d55fac10b799c9546804126239baf020d220136163f763b55a74e50e750","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa68a0a3b7cb32c00e39ee3cd31f8f15b80cac97dce51b6ee7fc14a1e8deb30b","affectsGlobalScope":true,"impliedFormat":1},{"version":"1cf059eaf468efcc649f8cf6075d3cb98e9a35a0fe9c44419ec3d2f5428d7123","affectsGlobalScope":true,"impliedFormat":1},{"version":"6c36e755bced82df7fb6ce8169265d0a7bb046ab4e2cb6d0da0cb72b22033e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"7a93de4ff8a63bafe62ba86b89af1df0ccb5e40bb85b0c67d6bbcfdcf96bf3d4","affectsGlobalScope":true,"impliedFormat":1},{"version":"90e85f9bc549dfe2b5749b45fe734144e96cd5d04b38eae244028794e142a77e","affectsGlobalScope":true,"impliedFormat":1},{"version":"e0a5deeb610b2a50a6350bd23df6490036a1773a8a71d70f2f9549ab009e67ee","affectsGlobalScope":true,"impliedFormat":1},{"version":"435b3711465425770ed2ee2f1cf00ce071835265e0851a7dc4600ab4b007550e","impliedFormat":1},{"version":"7e49f52a159435fc8df4de9dc377ef5860732ca2dc9efec1640531d3cf5da7a3","impliedFormat":1},{"version":"dd4bde4bdc2e5394aed6855e98cf135dfdf5dd6468cad842e03116d31bbcc9bc","impliedFormat":1},{"version":"4d4e879009a84a47c05350b8dca823036ba3a29a3038efed1be76c9f81e45edf","affectsGlobalScope":true,"impliedFormat":1},{"version":"237ba5ac2a95702a114a309e39c53a5bddff5f6333b325db9764df9b34f3502b","impliedFormat":1},{"version":"9ba13b47cb450a438e3076c4a3f6afb9dc85e17eae50f26d4b2d72c0688c9251","impliedFormat":1},{"version":"b64cd4401633ea4ecadfd700ddc8323a13b63b106ac7127c1d2726f32424622c","impliedFormat":1},{"version":"37c6e5fe5715814412b43cc9b50b24c67a63c4e04e753e0d1305970d65417a60","impliedFormat":1},{"version":"1d024184fb57c58c5c91823f9d10b4915a4867b7934e89115fd0d861a9df27c8","impliedFormat":1},{"version":"ee0e4946247f842c6dd483cbb60a5e6b484fee07996e3a7bc7343dfb68a04c5d","impliedFormat":1},{"version":"ef051f42b7e0ef5ca04552f54c4552eac84099d64b6c5ad0ef4033574b6035b8","impliedFormat":1},{"version":"853a43154f1d01b0173d9cbd74063507ece57170bad7a3b68f3fa1229ad0a92f","impliedFormat":1},{"version":"56231e3c39a031bfb0afb797690b20ed4537670c93c0318b72d5180833d98b72","impliedFormat":1},{"version":"5cc7c39031bfd8b00ad58f32143d59eb6ffc24f5d41a20931269011dccd36c5e","impliedFormat":1},{"version":"b0b69c61b0f0ec8ca15db4c8c41f6e77f4cacb784d42bca948f42dea33e8757e","affectsGlobalScope":true,"impliedFormat":1},{"version":"f96a48183254c00d24575401f1a761b4ce4927d927407e7862a83e06ce5d6964","impliedFormat":1},{"version":"cc25940cfb27aa538e60d465f98bb5068d4d7d33131861ace43f04fe6947d68f","impliedFormat":1},{"version":"f83fb2b1338afbb3f9d733c7d6e8b135826c41b0518867df0c0ace18ae1aa270","impliedFormat":1},{"version":"01ff95aa1443e3f7248974e5a771f513cb2ac158c8898f470a1792f817bee497","impliedFormat":1},{"version":"757227c8b345c57d76f7f0e3bbad7a91ffca23f1b2547cbed9e10025816c9cb7","impliedFormat":1},{"version":"42a05d8f239f74587d4926aba8cc54792eed8e8a442c7adc9b38b516642aadfe","impliedFormat":1},{"version":"5d21b58d60383cc6ab9ad3d3e265d7d25af24a2c9b506247e0e50b0a884920be","impliedFormat":1},{"version":"101f482fd48cb4c7c0468dcc6d62c843d842977aea6235644b1edd05e81fbf22","impliedFormat":1},{"version":"ae6757460f37078884b1571a3de3ebaf724d827d7e1d53626c02b3c2a408ac63","affectsGlobalScope":true,"impliedFormat":1},{"version":"9451a46a89ed209e2e08329e6cac59f89356eae79a7230f916d8cc38725407c7","impliedFormat":1},{"version":"3ef397f12387eff17f550bc484ea7c27d21d43816bbe609d495107f44b97e933","impliedFormat":1},{"version":"1023282e2ba810bc07905d3668349fbd37a26411f0c8f94a70ef3c05fe523fcf","impliedFormat":1},{"version":"b214ebcf76c51b115453f69729ee8aa7b7f8eccdae2a922b568a45c2d7ff52f7","impliedFormat":1},{"version":"429c9cdfa7d126255779efd7e6d9057ced2d69c81859bbab32073bad52e9ba76","impliedFormat":1},{"version":"e236b5eba291f51bdf32c231673e6cab81b5410850e61f51a7a524dddadc0f95","impliedFormat":1},{"version":"f7ba0e839daa0702e3ff1a1a871c0d8ea2d586ce684dd8a72c786c36a680b1d9","affectsGlobalScope":true,"impliedFormat":1},{"version":"7f2c62938251b45715fd2a9887060ec4fbc8724727029d1cbce373747252bdd7","impliedFormat":1},{"version":"e3ace08b6bbd84655d41e244677b474fd995923ffef7149ddb68af8848b60b05","impliedFormat":1},{"version":"132580b0e86c48fab152bab850fc57a4b74fe915c8958d2ccb052b809a44b61c","impliedFormat":1},{"version":"af4ab0aa8908fc9a655bb833d3bc28e117c4f0e1038c5a891546158beb25accb","impliedFormat":1},{"version":"69c9a5a9392e8564bd81116e1ed93b13205201fb44cb35a7fde8c9f9e21c4b23","impliedFormat":1},{"version":"5f8fc37f8434691ffac1bfd8fc2634647da2c0e84253ab5d2dd19a7718915b35","impliedFormat":1},{"version":"5981c2340fd8b076cae8efbae818d42c11ffc615994cb060b1cd390795f1be2b","impliedFormat":1},{"version":"f64deb26664af64dc274637343bde8d82f930c77af05a412c7d310b77207a448","impliedFormat":1},{"version":"ed4f674fc8c0c993cc7e145069ac44129e03519b910c62be206a0cc777bdc60b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0250da3eb85c99624f974e77ef355cdf86f43980251bc371475c2b397ba55bcd","impliedFormat":1},{"version":"f1c93e046fb3d9b7f8249629f4b63dc068dd839b824dd0aa39a5e68476dc9420","impliedFormat":1},{"version":"3d3a5f27ffbc06c885dd4d5f9ee20de61faf877fe2c3a7051c4825903d9a7fdc","impliedFormat":1},{"version":"12806f9f085598ef930edaf2467a5fa1789a878fba077cd27e85dc5851e11834","impliedFormat":1},{"version":"17d06eb5709839c7ce719f0c38ada6f308fb433f2cd6d8c87b35856e07400950","impliedFormat":1},{"version":"a43fe41c33d0a192a0ecaf9b92e87bef3709c9972e6d53c42c49251ccb962d69","impliedFormat":1},{"version":"a177959203c017fad3ecc4f3d96c8757a840957a4959a3ae00dab9d35961ca6c","affectsGlobalScope":true,"impliedFormat":1},{"version":"6fc727ccf9b36e257ff982ea0badeffbfc2c151802f741bddff00c6af3b784cf","impliedFormat":1},{"version":"2a00d005e3af99cd1cfa75220e60c61b04bfb6be7ca7453bfe2ef6cca37cc03c","impliedFormat":1},{"version":"4844a4c9b4b1e812b257676ed8a80b3f3be0e29bf05e742cc2ea9c3c6865e6c6","impliedFormat":1},{"version":"064878a60367e0407c42fb7ba02a2ea4d83257357dc20088e549bd4d89433e9c","impliedFormat":1},{"version":"14d4bd22d1b05824971b98f7e91b2484c90f1a684805c330476641417c3d9735","impliedFormat":1},{"version":"c3877fef8a43cd434f9728f25a97575b0eb73d92f38b5c87c840daccc3e21d97","impliedFormat":1},{"version":"b484ec11ba00e3a2235562a41898d55372ccabe607986c6fa4f4aba72093749f","impliedFormat":1},{"version":"1dbd83860e7634f9c236647f45dbc5d3c4f9eba8827d87209d6e9826fdf4dbd5","impliedFormat":1},{"version":"41ef7992c555671a8fe54db302788adefa191ded810a50329b79d20a6772d14c","impliedFormat":1},{"version":"041a7781b9127ab568d2cdcce62c58fdea7c7407f40b8c50045d7866a2727130","impliedFormat":1},{"version":"b37f83e7deea729aa9ce5593f78905afb45b7532fdff63041d374f60059e7852","impliedFormat":1},{"version":"e1cb68f3ef3a8dd7b2a9dfb3de482ed6c0f1586ba0db4e7d73c1d2147b6ffc51","impliedFormat":1},{"version":"55cdbeebe76a1fa18bbd7e7bf73350a2173926bd3085bb050cf5a5397025ee4e","impliedFormat":1},{"version":"28186e3905c8f465532e8ca1536b8fdcf7beac3e61f70a261052a38be81dc7ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"b0025d3efe8fdc97649db12fcce114e907fc972aa404e17e3bfcd51e707efe47","signature":"bb52afc6ddec069b3c03a03fe02482a70e072009379b77054579e1fb68992f8e"},{"version":"c7b3cf279a2ae651e00b026955d403536a6bd91e7b76703f1b0deea9185d70d3","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"317832e48a465ef0999895a38eaf188e6c22fde9f9b4d1206971a1d8de409285","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"2a1919d95615f298cbafc1c616c037713981004be293ff6b30ce7a23c463dc0a","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"c961edfa7f13ef464a3758cb22ffcd17e5a494e701a6c62402c0ec3894bbfa82","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"1ab49f65445fbf203ed7b1381b85937ce623b023c49c7aef012786e6d3a89c67","signature":"2414fb03ea1c1f83cbd71a3b042650d455e94065dc577bc13daf8e8cb0a3faf3"},{"version":"946c4a694860ea85c6d58116abce44dd1b9a364a6d119f5cfc703ec0b7740b22","signature":"f28a8ef6aca7e885de3c53ba626b742eccf651a1bda7f6738f50dce58e8f4039","affectsGlobalScope":true},{"version":"9281f1ca7f56acf70225d210b4b4064cf03bdca655031db2d3c54c9c470aa58d","signature":"835047172e303ce43bfc1c05dfb6cbe17b90a55f2cacbd2fcd43596d40b6dccc"},{"version":"556ccd493ec36c7d7cb130d51be66e147b91cc1415be383d71da0f1e49f742a9","impliedFormat":1},{"version":"b6d03c9cfe2cf0ba4c673c209fcd7c46c815b2619fd2aad59fc4229aaef2ed43","impliedFormat":1},{"version":"95aba78013d782537cc5e23868e736bec5d377b918990e28ed56110e3ae8b958","impliedFormat":1},{"version":"670a76db379b27c8ff42f1ba927828a22862e2ab0b0908e38b671f0e912cc5ed","impliedFormat":1},{"version":"13b77ab19ef7aadd86a1e54f2f08ea23a6d74e102909e3c00d31f231ed040f62","impliedFormat":1},{"version":"069bebfee29864e3955378107e243508b163e77ab10de6a5ee03ae06939f0bb9","impliedFormat":1},{"version":"42baf4ca38c38deaf411ea73f37bc39ff56c6e5c761a968b64ac1b25c92b5cd8","impliedFormat":1},{"version":"4f6ae308c5f2901f2988c817e1511520619e9025b9b12cc7cce2ab2e6ffed78a","impliedFormat":1},{"version":"8718fa41d7cf4aa91de4e8f164c90f88e0bf343aa92a1b9b725a9c675c64e16b","impliedFormat":1},{"version":"f992cd6cc0bcbaa4e6c810468c90f2d8595f8c6c3cf050c806397d3de8585562","impliedFormat":1},{"version":"fb893a0dfc3c9fb0f9ca93d0648694dd95f33cbad2c0f2c629f842981dfd4e2e","impliedFormat":1},{"version":"3eb11dbf3489064a47a2e1cf9d261b1f100ef0b3b50ffca6c44dd99d6dd81ac1","impliedFormat":1},{"version":"15fe687c59d62741b4494d5e623d497d55eb38966ecf5bea7f36e48fc3fbe15e","impliedFormat":1},{"version":"2c3b8be03577c98530ef9cb1a76e2c812636a871f367e9edf4c5f3ce702b77f8","affectsGlobalScope":true,"impliedFormat":1},{"version":"ecec8f82ddf42db544c8320eddf7f09a9a788723f7473e82e903401a3d14d488","impliedFormat":1},{"version":"151ff381ef9ff8da2da9b9663ebf657eac35c4c9a19183420c05728f31a6761d","impliedFormat":1},{"version":"ed19da84b7dbf00952ad0b98ce5c194f1903bcf7c94d8103e8e0d63b271543ae","impliedFormat":1},{"version":"89121c1bf2990f5219bfd802a3e7fc557de447c62058d6af68d6b6348d64499a","impliedFormat":1},{"version":"79b4369233a12c6fa4a07301ecb7085802c98f3a77cf9ab97eee27e1656f82e6","impliedFormat":1},{"version":"fec943fdb3275eb6e006b35e04a8e2e99e9adf3f4b969ddf15315ac7575a93e4","impliedFormat":1},{"version":"d4a22007b481fe2a2e6bfd3a42c00cd62d41edb36d30fc4697df2692e9891fc8","impliedFormat":1},{"version":"10a60d0cc51552184ceb31c27ef547eb365b918b0927b155176be3c3d5cba82c","impliedFormat":1},{"version":"1a86aff0e5cf0da881c826ada253aa5256ff0d53c2123c62cd7851559eaee9b9","impliedFormat":1},{"version":"8baa5d0febc68db886c40bf341e5c90dc215a90cd64552e47e8184be6b7e3358","impliedFormat":1},{"version":"62ba45a86b9a31eb84ea03ae0b9e800a507d980c1f38dcec6528f10078cfdedd","impliedFormat":1},{"version":"74d5a87c3616cd5d8691059d531504403aa857e09cbaecb1c64dfb9ace0db185","impliedFormat":1}],"root":[[75,80],[204,211]],"options":{"allowSyntheticDefaultImports":true,"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"module":99,"noImplicitAny":false,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[214,1],[212,2],[217,3],[213,1],[215,4],[216,1],[221,5],[223,6],[226,7],[227,2],[228,8],[230,9],[219,2],[231,10],[232,9],[222,2],[143,11],[144,11],[145,12],[83,13],[146,14],[147,15],[148,16],[81,2],[149,17],[150,18],[151,19],[152,20],[153,21],[154,22],[155,22],[156,23],[157,24],[158,25],[159,26],[84,2],[82,2],[160,27],[161,28],[162,29],[202,30],[163,31],[164,32],[165,31],[166,33],[167,34],[168,35],[169,36],[170,36],[171,36],[172,37],[173,38],[174,39],[175,40],[176,41],[177,42],[178,42],[179,43],[180,2],[181,2],[182,44],[183,45],[184,44],[185,46],[186,47],[187,48],[188,49],[189,50],[190,51],[191,52],[192,53],[193,54],[194,55],[195,56],[196,57],[197,58],[198,59],[199,60],[85,31],[86,2],[87,61],[88,62],[89,2],[90,63],[91,2],[134,64],[135,65],[136,66],[137,66],[138,67],[139,2],[140,14],[141,68],[142,65],[200,69],[201,70],[234,71],[235,2],[220,72],[225,73],[224,2],[229,2],[236,2],[237,74],[92,2],[203,10],[218,31],[59,2],[60,2],[10,2],[12,2],[11,2],[2,2],[13,2],[14,2],[15,2],[16,2],[17,2],[18,2],[19,2],[20,2],[3,2],[21,2],[22,2],[4,2],[23,2],[27,2],[24,2],[25,2],[26,2],[28,2],[29,2],[30,2],[5,2],[31,2],[32,2],[33,2],[34,2],[6,2],[38,2],[35,2],[36,2],[37,2],[39,2],[7,2],[40,2],[45,2],[46,2],[41,2],[42,2],[43,2],[44,2],[8,2],[50,2],[47,2],[48,2],[49,2],[51,2],[9,2],[52,2],[53,2],[54,2],[56,2],[55,2],[1,2],[57,2],[58,2],[110,75],[122,76],[108,77],[123,78],[132,79],[99,80],[100,81],[98,82],[131,8],[126,83],[130,84],[102,85],[119,86],[101,87],[129,88],[96,89],[97,83],[103,90],[104,2],[109,91],[107,90],[94,92],[133,93],[124,94],[113,95],[112,90],[114,96],[117,97],[111,98],[115,99],[127,8],[105,100],[106,101],[118,102],[95,78],[121,103],[120,90],[116,104],[125,2],[93,2],[128,105],[233,78],[74,106],[66,107],[73,108],[68,2],[69,2],[67,109],[70,110],[61,2],[62,2],[63,106],[65,111],[71,2],[72,112],[64,113],[80,114],[205,115],[206,116],[207,117],[208,118],[204,119],[210,120],[209,121],[211,122],[79,123],[76,2],[78,124],[77,125],[75,126]],"latestChangedDtsFile":"./dist/tools/schemas.d.ts","version":"5.9.3"} \ No newline at end of file diff --git a/packages/opencode-config/opencode.jsonc b/packages/opencode-config/opencode.jsonc index c3eb6a56..b0e5c4bc 100644 --- a/packages/opencode-config/opencode.jsonc +++ b/packages/opencode-config/opencode.jsonc @@ -1,3 +1,9 @@ { - "$schema": "https://opencode.ai/config.json" + "$schema": "https://opencode.ai/config.json", + "plugin": [], + "mcp": {}, + "provider": {}, + "experimental": { + "mcp_timeout": 300000 + } } \ No newline at end of file diff --git a/packages/opencode-config/package.json b/packages/opencode-config/package.json index eb4ef9f4..25d51df1 100644 --- a/packages/opencode-config/package.json +++ b/packages/opencode-config/package.json @@ -4,6 +4,6 @@ "private": true, "license": "MIT", "dependencies": { - "@opencode-ai/plugin": "1.1.42" + "@opencode-ai/plugin": "1.2.1" } -} +} \ No newline at end of file diff --git a/packages/opencode-config/plugin/lib/request.ts b/packages/opencode-config/plugin/lib/request.ts index 90df50fe..5025a501 100644 --- a/packages/opencode-config/plugin/lib/request.ts +++ b/packages/opencode-config/plugin/lib/request.ts @@ -1,3 +1,7 @@ +import http from "http" +import https from "https" +import { Readable } from "stream" + export type PluginEvent = { type: string properties?: Record @@ -16,7 +20,8 @@ export function getCodeNomadConfig(): CodeNomadConfig { } export function createCodeNomadRequester(config: CodeNomadConfig) { - const baseUrl = config.baseUrl.replace(/\/+$/, "") + const rawBaseUrl = (config.baseUrl ?? "").trim() + const baseUrl = rawBaseUrl.replace(/\/+$/, "") const pluginBase = `${baseUrl}/workspaces/${encodeURIComponent(config.instanceId)}/plugin` const authorization = buildInstanceAuthorizationHeader() @@ -42,10 +47,10 @@ export function createCodeNomadRequester(config: CodeNomadConfig) { const hasBody = init?.body !== undefined const headers = buildHeaders(init?.headers, hasBody) - return fetch(url, { - ...init, - headers, - }) + // The CodeNomad plugin only talks to the local CodeNomad server. + // Use a single request implementation that tolerates custom/self-signed certs + // without disabling TLS verification for the whole Node process. + return nodeFetch(url, { ...init, headers }, { rejectUnauthorized: false }) } const requestJson = async (path: string, init?: RequestInit): Promise => { @@ -87,6 +92,91 @@ export function createCodeNomadRequester(config: CodeNomadConfig) { } } +async function nodeFetch( + url: string, + init: RequestInit & { headers?: Record }, + tls: { rejectUnauthorized: boolean }, +): Promise { + const parsed = new URL(url) + const isHttps = parsed.protocol === "https:" + const requestFn = isHttps ? https.request : http.request + + const method = (init.method ?? "GET").toUpperCase() + const headers = init.headers ?? {} + const body = init.body + + return await new Promise((resolve, reject) => { + const req = requestFn( + { + protocol: parsed.protocol, + hostname: parsed.hostname, + port: parsed.port ? Number(parsed.port) : undefined, + path: `${parsed.pathname}${parsed.search}`, + method, + headers, + ...(isHttps ? { rejectUnauthorized: tls.rejectUnauthorized } : {}), + }, + (res) => { + const responseHeaders = new Headers() + for (const [key, value] of Object.entries(res.headers)) { + if (value === undefined) continue + if (Array.isArray(value)) { + responseHeaders.set(key, value.join(", ")) + } else { + responseHeaders.set(key, String(value)) + } + } + + // Convert Node stream -> Web ReadableStream for Response. + const webBody = Readable.toWeb(res) as unknown as ReadableStream + resolve(new Response(webBody, { status: res.statusCode ?? 0, headers: responseHeaders })) + }, + ) + + const signal = init.signal + const abort = () => { + const err = new Error("Request aborted") + ;(err as any).name = "AbortError" + req.destroy(err) + reject(err) + } + + if (signal) { + if (signal.aborted) { + abort() + return + } + signal.addEventListener("abort", abort, { once: true }) + req.once("close", () => signal.removeEventListener("abort", abort)) + } + + req.once("error", reject) + + if (body === undefined || body === null) { + req.end() + return + } + + if (typeof body === "string") { + req.end(body) + return + } + + if (body instanceof Uint8Array) { + req.end(Buffer.from(body)) + return + } + + if (body instanceof ArrayBuffer) { + req.end(Buffer.from(new Uint8Array(body))) + return + } + + // Fallback for less common BodyInit types. + req.end(String(body)) + }) +} + function requireEnv(key: string): string { const value = process.env[key] if (!value || !value.trim()) { diff --git a/packages/server/.gitignore b/packages/server/.gitignore index 364fdec1..531f28fe 100644 --- a/packages/server/.gitignore +++ b/packages/server/.gitignore @@ -1 +1,4 @@ public/ + +# Local developer config (may contain secrets) +config-*.json diff --git a/packages/server/README.md b/packages/server/README.md index 87146fc8..2eff0a24 100644 --- a/packages/server/README.md +++ b/packages/server/README.md @@ -31,6 +31,11 @@ You can run CodeNomad directly without installing it: npx @neuralnomads/codenomad --launch ``` +On startup, CodeNomad prints two URLs: + +- `Local Connection URL : ...` (used by desktop shells) +- `Remote Connection URL : ...` (used by browsers/other machines when remote access is enabled) + ### Install Globally Or install it globally to use the `codenomad` command: @@ -44,7 +49,14 @@ You can configure the server using flags or environment variables: | Flag | Env Variable | Description | |------|--------------|-------------| -| `--port ` | `CLI_PORT` | HTTP port (default 9898) | +| `--https ` | `CLI_HTTPS` | Enable HTTPS listener (default `true`) | +| `--http ` | `CLI_HTTP` | Enable HTTP listener (default `false`) | +| `--https-port ` | `CLI_HTTPS_PORT` | HTTPS port (default `9898`, use `0` for auto) | +| `--http-port ` | `CLI_HTTP_PORT` | HTTP port (default `9899`, use `0` for auto) | +| `--tls-key ` | `CLI_TLS_KEY` | TLS private key (PEM). Requires `--tls-cert`. | +| `--tls-cert ` | `CLI_TLS_CERT` | TLS certificate (PEM). Requires `--tls-key`. | +| `--tls-ca ` | `CLI_TLS_CA` | Optional CA chain/bundle (PEM) | +| `--tlsSANs ` | `CLI_TLS_SANS` | Additional TLS SANs (comma-separated) | | `--host ` | `CLI_HOST` | Interface to bind (default 127.0.0.1) | | `--workspace-root ` | `CLI_WORKSPACE_ROOT` | Default root for new workspaces | | `--unrestricted-root` | `CLI_UNRESTRICTED_ROOT` | Allow full-filesystem browsing | @@ -56,6 +68,42 @@ You can configure the server using flags or environment variables: | `--generate-token` | `CODENOMAD_GENERATE_TOKEN` | Emit a one-time local bootstrap token for desktop flows | | `--dangerously-skip-auth` | `CODENOMAD_SKIP_AUTH` | Disable CodeNomad's internal auth (use only behind a trusted perimeter) | +### HTTP vs HTTPS + +- Default: `--https=true --http=false` (HTTPS only). +- To run plain HTTP only (useful for development): + +```sh +codenomad --https=false --http=true +``` + +- To run both HTTPS (for remote) and HTTP loopback (for desktop): + +```sh +codenomad --https=true --http=true +``` + +### Remote Access Binding Rules + +- When remote access is enabled (bind host is non-loopback, e.g. `--host 0.0.0.0`): + - HTTP listens on `127.0.0.1` only. + - HTTPS listens on `--host` (LAN/all interfaces). +- When remote access is disabled (bind host is loopback, e.g. `--host 127.0.0.1`): + - Both HTTP and HTTPS listen on `127.0.0.1`. + +### Self-Signed Certificates + +If `--https=true` and you do not provide `--tls-key/--tls-cert`, CodeNomad generates a local certificate automatically under your config directory: + +- `~/.config/codenomad/tls/ca-cert.pem` +- `~/.config/codenomad/tls/server-cert.pem` + +Certificates are valid for about 30 days and rotate automatically on startup when needed. You can add extra SANs via: + +```sh +codenomad --tlsSANs "localhost,127.0.0.1,my-hostname,192.168.1.10" +``` + ### Authentication - Default behavior: CodeNomad requires a login (username/password) and stores a session cookie in the browser. - `--dangerously-skip-auth` / `CODENOMAD_SKIP_AUTH=true` disables the login prompt and treats all requests as authenticated. @@ -71,8 +119,7 @@ When running as a server CodeNomad can also be installed as a PWA from any suppo > **TLS requirement** > Browsers require a secure (`https://`) connection for PWA installation. -> If you host CodeNomad on a remote machine, serve it behind a reverse proxy (e.g. Caddy, nginx) with a valid TLS certificate. -> Self-signed certificates generally won't work unless they are explicitly trusted by the device/browser (e.g., via a custom CA). +> If you host CodeNomad on a remote machine, use HTTPS. Self-signed certificates generally won't work unless they are explicitly trusted by the device/browser (e.g., via a custom CA). ### Data Storage - **Config**: `~/.config/codenomad/config.json` diff --git a/packages/server/package-lock.json b/packages/server/package-lock.json index 67b83347..dd378455 100644 --- a/packages/server/package-lock.json +++ b/packages/server/package-lock.json @@ -1,12 +1,12 @@ { "name": "@neuralnomads/codenomad", - "version": "0.9.5", + "version": "0.9.2-patch.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@neuralnomads/codenomad", - "version": "0.9.5", + "version": "0.9.2-patch.5", "dependencies": { "@fastify/cors": "^8.5.0", "@fastify/reply-from": "^9.8.0", diff --git a/packages/server/package.json b/packages/server/package.json index 6dd1e93f..d4e44ac5 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,8 +1,7 @@ { "name": "@neuralnomads/codenomad", - "version": "0.9.5", + "version": "0.10.3", "description": "CodeNomad Server", - "license": "MIT", "author": { "name": "Neural Nomads", "email": "codenomad@neuralnomads.ai" @@ -28,6 +27,7 @@ "@fastify/cors": "^8.5.0", "@fastify/reply-from": "^9.8.0", "@fastify/static": "^7.0.4", + "@modelcontextprotocol/sdk": "^1.25.2", "commander": "^12.1.0", "fastify": "^4.28.1", "fuzzysort": "^2.0.4", @@ -39,7 +39,8 @@ "devDependencies": { "@types/yauzl": "^2.10.0", "cross-env": "^7.0.3", - "ts-node": "^10.9.2", + "esbuild": "^0.25.12", + "ts-node": "^1.7.1", "tsx": "^4.20.6", "typescript": "^5.6.3" } diff --git a/packages/server/src/api-types.ts b/packages/server/src/api-types.ts index 08ed8ff7..9cc4a2fe 100644 --- a/packages/server/src/api-types.ts +++ b/packages/server/src/api-types.ts @@ -50,6 +50,38 @@ export interface WorkspaceDeleteResponse { status: WorkspaceStatus } +export type WorktreeKind = "root" | "worktree" + +export interface WorktreeDescriptor { + /** Stable identifier used by CodeNomad + clients ("root" for repo root). */ + slug: string + /** Absolute directory path on the server host. */ + directory: string + kind: WorktreeKind + /** Optional VCS branch name when available. */ + branch?: string +} + +export interface WorktreeListResponse { + worktrees: WorktreeDescriptor[] + /** True when the workspace folder resolves to a Git repository. */ + isGitRepo?: boolean +} + +export interface WorktreeCreateRequest { + slug: string + /** Optional branch name (defaults to slug). */ + branch?: string +} + +export interface WorktreeMap { + version: 1 + /** Default worktree to use for new sessions and as fallback. */ + defaultWorktreeSlug: string + /** Mapping of *parent* session IDs to a worktree slug. */ + parentSessionWorktreeSlug: Record +} + export type LogLevel = "debug" | "info" | "warn" | "error" export interface WorkspaceLogEntry { @@ -204,7 +236,8 @@ export interface NetworkAddress { ip: string family: "ipv4" | "ipv6" scope: "external" | "internal" | "loopback" - url: string + /** Remote URL using the server's remote protocol/port for this IP. */ + remoteUrl: string } export interface LatestReleaseInfo { @@ -230,16 +263,20 @@ export interface SupportMeta { } export interface ServerMeta { - /** Base URL clients should target for REST calls (useful for Electron embedding). */ - httpBaseUrl: string + /** URL desktop apps should use to connect (prefers loopback HTTP when enabled). */ + localUrl: string + /** URL remote clients should use (prefers HTTPS when enabled). */ + remoteUrl?: string /** SSE endpoint advertised to clients (`/api/events` by default). */ eventsUrl: string /** Host the server is bound to (e.g., 127.0.0.1 or 0.0.0.0). */ host: string /** Listening mode derived from host binding. */ listeningMode: "local" | "all" - /** Actual port in use after binding. */ - port: number + /** Actual local port in use after binding. */ + localPort: number + /** Actual remote port in use after binding (when remoteUrl is set). */ + remotePort?: number /** Display label for the host (e.g., hostname or friendly name). */ hostLabel: string /** Absolute path of the filesystem root exposed to clients. */ @@ -249,6 +286,8 @@ export interface ServerMeta { serverVersion?: string ui?: UiMeta support?: SupportMeta + /** Optional update info (dev channel only). */ + update?: LatestReleaseInfo | null } export type BackgroundProcessStatus = "running" | "stopped" | "error" @@ -278,6 +317,82 @@ export interface BackgroundProcessOutputResponse { sizeBytes: number } +// Git Source Control Types +export type GitFileStatus = "modified" | "added" | "deleted" | "renamed" | "copied" | "untracked" | "ignored" + +export interface GitFileChange { + /** Relative path to the file from workspace root */ + path: string + /** Status of the file */ + status: GitFileStatus + /** Whether the file is staged */ + staged: boolean + /** Original path for renamed files */ + originalPath?: string +} + +export interface GitBranch { + /** Branch name */ + name: string + /** Whether this is the current branch */ + current: boolean + /** Whether this is a remote branch */ + remote: boolean + /** Tracking branch for local branches */ + upstream?: string +} + +export interface GitStatus { + /** Current branch name */ + branch: string + /** List of file changes */ + changes: GitFileChange[] + /** Whether the repo has any commits */ + hasCommits: boolean + /** Number of commits ahead of upstream */ + ahead: number + /** Number of commits behind upstream */ + behind: number +} + +export interface GitBranchListResponse { + branches: GitBranch[] + current: string +} + +export interface GitDiffResponse { + /** File path */ + path: string + /** Unified diff content */ + diff: string + /** Whether the file is binary */ + isBinary: boolean +} + +export interface GitCommitRequest { + message: string +} + +export interface GitCommitResponse { + hash: string + message: string +} + +export interface GitCheckoutRequest { + branch: string + create?: boolean +} + +export interface GitStageRequest { + paths: string[] +} + +export interface GitPushResponse { + success: boolean + pushed?: boolean + message?: string +} + export type { Preferences, ModelPreference, diff --git a/packages/server/src/auth/manager.ts b/packages/server/src/auth/manager.ts index ebb7ec79..dde0f72f 100644 --- a/packages/server/src/auth/manager.ts +++ b/packages/server/src/auth/manager.ts @@ -119,10 +119,18 @@ export class AuthManager { reply.header("Set-Cookie", buildSessionCookie(this.cookieName, sessionId)) } + setSessionCookieWithOptions(reply: FastifyReply, sessionId: string, options?: { secure?: boolean }) { + reply.header("Set-Cookie", buildSessionCookie(this.cookieName, sessionId, options)) + } + clearSessionCookie(reply: FastifyReply) { reply.header("Set-Cookie", buildSessionCookie(this.cookieName, "", { maxAgeSeconds: 0 })) } + clearSessionCookieWithOptions(reply: FastifyReply, options?: { secure?: boolean }) { + reply.header("Set-Cookie", buildSessionCookie(this.cookieName, "", { maxAgeSeconds: 0, ...options })) + } + private requireAuthStore(): AuthStore { if (!this.authStore) { throw new Error("Auth store is unavailable") @@ -143,8 +151,11 @@ function resolvePath(filePath: string) { return path.resolve(filePath) } -function buildSessionCookie(name: string, value: string, options?: { maxAgeSeconds?: number }) { +function buildSessionCookie(name: string, value: string, options?: { maxAgeSeconds?: number; secure?: boolean }) { const parts = [`${name}=${encodeURIComponent(value)}`, "HttpOnly", "Path=/", "SameSite=Lax"] + if (options?.secure) { + parts.push("Secure") + } if (options?.maxAgeSeconds !== undefined) { parts.push(`Max-Age=${Math.max(0, Math.floor(options.maxAgeSeconds))}`) } diff --git a/packages/server/src/config/location.ts b/packages/server/src/config/location.ts new file mode 100644 index 00000000..b8d150f2 --- /dev/null +++ b/packages/server/src/config/location.ts @@ -0,0 +1,78 @@ +import os from "os" +import path from "path" + +export interface ConfigLocation { + /** Resolved absolute base directory containing all persisted server data. */ + baseDir: string + /** Canonical YAML config file path (may be custom when input points to a YAML file). */ + configYamlPath: string + /** Canonical YAML state file path (always in baseDir). */ + stateYamlPath: string + /** Legacy JSON config file path used for migration (always in baseDir, or explicit JSON input). */ + legacyJsonPath: string + /** Directory for per-instance persisted data (chat history etc.). */ + instancesDir: string +} + +function resolvePath(inputPath: string): string { + if (inputPath.startsWith("~/")) { + return path.join(os.homedir(), inputPath.slice(2)) + } + return path.resolve(inputPath) +} + +function isYamlPath(filePath: string): boolean { + const lower = filePath.toLowerCase() + return lower.endsWith(".yaml") || lower.endsWith(".yml") +} + +function isJsonPath(filePath: string): boolean { + return filePath.toLowerCase().endsWith(".json") +} + +/** + * Resolve CodeNomad's config location into a stable base directory + derived file paths. + * + * Supported inputs: + * - Directory: "~/.config/codenomad" + * - YAML file: "~/.config/codenomad/config.yaml" (or any *.yml/*.yaml) + * - Legacy JSON file: "~/.config/codenomad/config.json" + */ +export function resolveConfigLocation(raw: string): ConfigLocation { + const trimmed = (raw ?? "").trim() + const fallback = "~/.config/codenomad/config.json" + const input = trimmed.length > 0 ? trimmed : fallback + + const resolvedInput = resolvePath(input) + + if (isYamlPath(resolvedInput)) { + const baseDir = path.dirname(resolvedInput) + return { + baseDir, + configYamlPath: resolvedInput, + stateYamlPath: path.join(baseDir, "state.yaml"), + legacyJsonPath: path.join(baseDir, "config.json"), + instancesDir: path.join(baseDir, "instances"), + } + } + + if (isJsonPath(resolvedInput)) { + const baseDir = path.dirname(resolvedInput) + return { + baseDir, + configYamlPath: path.join(baseDir, "config.yaml"), + stateYamlPath: path.join(baseDir, "state.yaml"), + legacyJsonPath: resolvedInput, + instancesDir: path.join(baseDir, "instances"), + } + } + + const baseDir = resolvedInput + return { + baseDir, + configYamlPath: path.join(baseDir, "config.yaml"), + stateYamlPath: path.join(baseDir, "state.yaml"), + legacyJsonPath: path.join(baseDir, "config.json"), + instancesDir: path.join(baseDir, "instances"), + } +} diff --git a/packages/server/src/config/schema.ts b/packages/server/src/config/schema.ts index 10b6b325..5b5779dc 100644 --- a/packages/server/src/config/schema.ts +++ b/packages/server/src/config/schema.ts @@ -8,10 +8,12 @@ const ModelPreferenceSchema = z.object({ const AgentModelSelectionSchema = z.record(z.string(), ModelPreferenceSchema) const AgentModelSelectionsSchema = z.record(z.string(), AgentModelSelectionSchema) -const PreferencesSchema = z.object({ +const PreferencesSchema = z + .object({ showThinkingBlocks: z.boolean().default(false), thinkingBlocksExpansion: z.enum(["expanded", "collapsed"]).default("expanded"), showTimelineTools: z.boolean().default(true), + promptSubmitOnEnter: z.boolean().default(false), lastUsedBinary: z.string().optional(), locale: z.string().optional(), environmentVariables: z.record(z.string()).default({}), @@ -24,7 +26,16 @@ const PreferencesSchema = z.object({ showUsageMetrics: z.boolean().default(true), autoCleanupBlankSessions: z.boolean().default(true), listeningMode: z.enum(["local", "all"]).default("local"), -}) + askUserTimeout: z.number().default(300000), + + // OS notifications + osNotificationsEnabled: z.boolean().default(false), + osNotificationsAllowWhenVisible: z.boolean().default(false), + notifyOnNeedsInput: z.boolean().default(true), + notifyOnIdle: z.boolean().default(true), + }) + // Preserve unknown preference keys so newer configs survive older binaries. + .passthrough() const RecentFolderSchema = z.object({ path: z.string(), @@ -38,14 +49,35 @@ const OpenCodeBinarySchema = z.object({ label: z.string().optional(), }) -const ConfigFileSchema = z.object({ - preferences: PreferencesSchema.default({}), - recentFolders: z.array(RecentFolderSchema).default([]), - opencodeBinaries: z.array(OpenCodeBinarySchema).default([]), - theme: z.enum(["light", "dark", "system"]).optional(), -}) +const ConfigFileSchema = z + .object({ + preferences: PreferencesSchema.default({}), + recentFolders: z.array(RecentFolderSchema).default([]), + opencodeBinaries: z.array(OpenCodeBinarySchema).default([]), + theme: z.enum(["light", "dark", "system"]).optional(), + }) + // Preserve unknown top-level keys so optional future features survive downgrades. + .passthrough() + +// On-disk config.yaml only stores stable configuration (not volatile state like recent folders). +const ConfigYamlSchema = z + .object({ + preferences: PreferencesSchema.default({}), + opencodeBinaries: z.array(OpenCodeBinarySchema).default([]), + theme: z.enum(["light", "dark", "system"]).optional(), + }) + .passthrough() + +// On-disk state.yaml stores server-scoped mutable state (per-server, not per-client). +const StateFileSchema = z + .object({ + recentFolders: z.array(RecentFolderSchema).default([]), + }) + .passthrough() const DEFAULT_CONFIG = ConfigFileSchema.parse({}) +const DEFAULT_CONFIG_YAML = ConfigYamlSchema.parse({}) +const DEFAULT_STATE = StateFileSchema.parse({}) export { ModelPreferenceSchema, @@ -55,7 +87,11 @@ export { RecentFolderSchema, OpenCodeBinarySchema, ConfigFileSchema, + ConfigYamlSchema, + StateFileSchema, DEFAULT_CONFIG, + DEFAULT_CONFIG_YAML, + DEFAULT_STATE, } export type ModelPreference = z.infer @@ -65,3 +101,5 @@ export type Preferences = z.infer export type RecentFolder = z.infer export type OpenCodeBinary = z.infer export type ConfigFile = z.infer +export type ConfigYamlFile = z.infer +export type StateFile = z.infer diff --git a/packages/server/src/config/store.ts b/packages/server/src/config/store.ts index dda49e40..5d736f9c 100644 --- a/packages/server/src/config/store.ts +++ b/packages/server/src/config/store.ts @@ -1,15 +1,27 @@ import fs from "fs" import path from "path" +import { parse as parseYaml, stringify as stringifyYaml } from "yaml" import { EventBus } from "../events/bus" import { Logger } from "../logger" -import { ConfigFile, ConfigFileSchema, DEFAULT_CONFIG } from "./schema" +import { + ConfigFile, + ConfigFileSchema, + ConfigYamlSchema, + DEFAULT_CONFIG, + DEFAULT_CONFIG_YAML, + DEFAULT_STATE, + StateFile, + StateFileSchema, +} from "./schema" +import type { ConfigLocation } from "./location" export class ConfigStore { private cache: ConfigFile = DEFAULT_CONFIG + private state: StateFile = DEFAULT_STATE private loaded = false constructor( - private readonly configPath: string, + private readonly location: ConfigLocation, private readonly eventBus: EventBus | undefined, private readonly logger: Logger, ) {} @@ -20,19 +32,37 @@ export class ConfigStore { } try { - const resolved = this.resolvePath(this.configPath) - if (fs.existsSync(resolved)) { - const content = fs.readFileSync(resolved, "utf-8") - const parsed = JSON.parse(content) - this.cache = ConfigFileSchema.parse(parsed) - this.logger.debug({ resolved }, "Loaded existing config file") + const configYamlPath = this.location.configYamlPath + const stateYamlPath = this.location.stateYamlPath + const legacyJsonPath = this.location.legacyJsonPath + + if (fs.existsSync(configYamlPath)) { + const configDoc = this.readYamlFile(configYamlPath, DEFAULT_CONFIG_YAML, ConfigYamlSchema, "config") + const stateDoc = fs.existsSync(stateYamlPath) + ? this.readYamlFile(stateYamlPath, DEFAULT_STATE, StateFileSchema, "state") + : DEFAULT_STATE + + this.state = stateDoc + this.cache = this.mergeDocs(configDoc, stateDoc) + this.logger.debug({ configYamlPath, stateYamlPath }, "Loaded existing YAML config/state") + } else if (fs.existsSync(legacyJsonPath)) { + const migrated = this.migrateFromLegacyJson(legacyJsonPath) + this.state = migrated.state + this.cache = migrated.config } else { - this.cache = DEFAULT_CONFIG - this.logger.debug({ resolved }, "No config file found, using defaults") + // Fresh install: write defaults. + this.state = DEFAULT_STATE + this.cache = this.mergeDocs(DEFAULT_CONFIG_YAML, DEFAULT_STATE) + this.persist() + this.logger.debug( + { configYamlPath, stateYamlPath }, + "No config files found, created default YAML config/state", + ) } } catch (error) { - this.logger.warn({ err: error }, "Failed to load config, using defaults") - this.cache = DEFAULT_CONFIG + this.logger.warn({ err: error }, "Failed to load config/state, using defaults") + this.state = DEFAULT_STATE + this.cache = this.mergeDocs(DEFAULT_CONFIG_YAML, DEFAULT_STATE) } this.loaded = true @@ -48,9 +78,30 @@ export class ConfigStore { this.commit(validated) } + /** + * Apply a merge-patch update to the current config. + * - Missing keys are preserved. + * - Object values are merged recursively. + * - Explicit `null` deletes keys. + * - Arrays are replaced. + */ + mergePatch(patch: unknown) { + if (!patch || typeof patch !== "object" || Array.isArray(patch)) { + throw new Error("Config patch must be a JSON object") + } + const current = this.get() + const next = applyMergePatch(current as any, patch as any) + const validated = ConfigFileSchema.parse(next) + this.commit(validated) + } + private commit(next: ConfigFile) { this.cache = next this.loaded = true + this.state = { + ...this.state, + recentFolders: next.recentFolders, + } this.persist() const published = Boolean(this.eventBus) this.eventBus?.publish({ type: "config.appChanged", config: this.cache }) @@ -60,19 +111,134 @@ export class ConfigStore { private persist() { try { - const resolved = this.resolvePath(this.configPath) - fs.mkdirSync(path.dirname(resolved), { recursive: true }) - fs.writeFileSync(resolved, JSON.stringify(this.cache, null, 2), "utf-8") - this.logger.debug({ resolved }, "Persisted config file") + const configYamlPath = this.location.configYamlPath + const stateYamlPath = this.location.stateYamlPath + + fs.mkdirSync(this.location.baseDir, { recursive: true }) + fs.mkdirSync(path.dirname(configYamlPath), { recursive: true }) + + const configYaml = stringifyYaml(stripRecentFolders(this.cache) as any) + const stateYaml = stringifyYaml(this.state as any) + + fs.writeFileSync(configYamlPath, ensureTrailingNewline(configYaml), "utf-8") + fs.writeFileSync(stateYamlPath, ensureTrailingNewline(stateYaml), "utf-8") + + this.logger.debug({ configYamlPath, stateYamlPath }, "Persisted YAML config/state") } catch (error) { this.logger.warn({ err: error }, "Failed to persist config") } } - private resolvePath(filePath: string) { - if (filePath.startsWith("~/")) { - return path.join(process.env.HOME ?? "", filePath.slice(2)) + private mergeDocs(configDoc: unknown, stateDoc: StateFile): ConfigFile { + const merged = { + ...(configDoc as any), + // State wins for recent folders. + recentFolders: stateDoc.recentFolders ?? [], } - return path.resolve(filePath) + + return ConfigFileSchema.parse(merged) + } + + private readYamlFile( + filePath: string, + fallback: T, + schema: { parse: (value: unknown) => T }, + label: string, + ): T { + try { + const content = fs.readFileSync(filePath, "utf-8") + const parsed = parseYaml(content) + return schema.parse(parsed ?? {}) + } catch (error) { + this.logger.warn({ err: error, filePath, label }, "Failed to read YAML file, using defaults") + return fallback + } + } + + private migrateFromLegacyJson(legacyJsonPath: string): { config: ConfigFile; state: StateFile } { + const configYamlPath = this.location.configYamlPath + const stateYamlPath = this.location.stateYamlPath + + const content = fs.readFileSync(legacyJsonPath, "utf-8") + const parsed = JSON.parse(content) + const legacy = ConfigFileSchema.parse(parsed) + + const state: StateFile = StateFileSchema.parse({ + ...DEFAULT_STATE, + recentFolders: legacy.recentFolders ?? [], + }) + + const merged = this.mergeDocs(stripRecentFolders(legacy), state) + + // Persist YAML docs first, then move legacy aside. + try { + fs.mkdirSync(this.location.baseDir, { recursive: true }) + fs.writeFileSync(configYamlPath, ensureTrailingNewline(stringifyYaml(stripRecentFolders(merged) as any)), "utf-8") + fs.writeFileSync(stateYamlPath, ensureTrailingNewline(stringifyYaml(state as any)), "utf-8") + this.logger.info({ legacyJsonPath, configYamlPath, stateYamlPath }, "Migrated config.json -> YAML") + } catch (error) { + this.logger.warn({ err: error }, "Failed to persist migrated YAML config/state") + } + + try { + const bakPath = pickBackupPath(legacyJsonPath) + fs.renameSync(legacyJsonPath, bakPath) + this.logger.info({ legacyJsonPath, bakPath }, "Moved legacy config.json to backup") + } catch (error) { + this.logger.warn({ err: error, legacyJsonPath }, "Failed to rename legacy config.json to backup") + } + + return { config: merged, state } + } +} + +function ensureTrailingNewline(content: string): string { + if (!content) return "\n" + return content.endsWith("\n") ? content : `${content}\n` +} + +function stripRecentFolders(config: ConfigFile): Omit & Record { + const clone: Record = { ...(config as any) } + delete clone.recentFolders + return clone as any +} + +function isPlainObject(value: unknown): value is Record { + if (!value || typeof value !== "object") return false + if (Array.isArray(value)) return false + const proto = Object.getPrototypeOf(value) + return proto === Object.prototype || proto === null +} + +function applyMergePatch(current: any, patch: any): any { + // RFC 7396-ish merge patch with explicit null deletes. + if (!isPlainObject(patch)) { + return patch + } + + const base = isPlainObject(current) ? { ...current } : {} + for (const [key, value] of Object.entries(patch)) { + if (value === null) { + delete base[key] + continue + } + + if (isPlainObject(value) && isPlainObject(base[key])) { + base[key] = applyMergePatch(base[key], value) + continue + } + + // Arrays and scalars replace. + base[key] = value + } + return base +} + +function pickBackupPath(legacyJsonPath: string): string { + const base = legacyJsonPath.endsWith(".json") ? legacyJsonPath.slice(0, -".json".length) : legacyJsonPath + const preferred = `${base}.json.bak` + if (!fs.existsSync(preferred)) { + return preferred } + return `${base}.json.bak.${Date.now()}` } diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 9adffec4..05a4c18e 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -9,6 +9,7 @@ import { createRequire } from "module" import { createHttpServer } from "./server/http-server" import { WorkspaceManager } from "./workspaces/manager" import { ConfigStore } from "./config/store" +import { resolveConfigLocation } from "./config/location" import { BinaryRegistry } from "./config/binaries" import { FileSystemBrowser } from "./filesystem/browser" import { EventBus } from "./events/bus" @@ -19,6 +20,9 @@ import { createLogger } from "./logger" import { launchInBrowser } from "./launcher" import { resolveUi } from "./ui/remote-ui" import { AuthManager, BOOTSTRAP_TOKEN_STDOUT_PREFIX, DEFAULT_AUTH_USERNAME } from "./auth/manager" +import { resolveHttpsOptions } from "./server/tls" +import { resolveNetworkAddresses } from "./server/network-addresses" +import { startDevReleaseMonitor } from "./releases/dev-release-monitor" const require = createRequire(import.meta.url) @@ -28,8 +32,15 @@ const __dirname = path.dirname(__filename) const DEFAULT_UI_STATIC_DIR = path.resolve(__dirname, "../public") interface CliOptions { - port: number host: string + https: boolean + http: boolean + httpsPort: number + httpPort: number + tlsKeyPath?: string + tlsCertPath?: string + tlsCaPath?: string + tlsSANs?: string rootDir: string configPath: string unrestrictedRoot: boolean @@ -47,9 +58,10 @@ interface CliOptions { dangerouslySkipAuth: boolean } -const DEFAULT_PORT = 9898 const DEFAULT_HOST = "127.0.0.1" const DEFAULT_CONFIG_PATH = "~/.config/codenomad/config.json" +const DEFAULT_HTTPS_PORT = 9898 +const DEFAULT_HTTP_PORT = 9899 function parseCliOptions(argv: string[]): CliOptions { const program = new Command() @@ -57,7 +69,14 @@ function parseCliOptions(argv: string[]): CliOptions { .description("CodeNomad CLI server") .version(packageJson.version, "-v, --version", "Show the CLI version") .addOption(new Option("--host ", "Host interface to bind").env("CLI_HOST").default(DEFAULT_HOST)) - .addOption(new Option("--port ", "Port for the HTTP server").env("CLI_PORT").default(DEFAULT_PORT).argParser(parsePort)) + .addOption(new Option("--https ", "Enable HTTPS listener (true|false)").env("CLI_HTTPS").default("true")) + .addOption(new Option("--http ", "Enable HTTP listener (true|false)").env("CLI_HTTP").default("false")) + .addOption(new Option("--https-port ", "HTTPS port (0 for auto)").env("CLI_HTTPS_PORT").default(DEFAULT_HTTPS_PORT).argParser(parsePort)) + .addOption(new Option("--http-port ", "HTTP port (0 for auto)").env("CLI_HTTP_PORT").default(DEFAULT_HTTP_PORT).argParser(parsePort)) + .addOption(new Option("--tls-key ", "TLS private key (PEM)").env("CLI_TLS_KEY")) + .addOption(new Option("--tls-cert ", "TLS certificate (PEM)").env("CLI_TLS_CERT")) + .addOption(new Option("--tls-ca ", "TLS CA chain (PEM)").env("CLI_TLS_CA")) + .addOption(new Option("--tlsSANs ", "Additional TLS SANs (comma-separated)").env("CLI_TLS_SANS")) .addOption( new Option("--workspace-root ", "Workspace root directory").env("CLI_WORKSPACE_ROOT").default(process.cwd()), ) @@ -97,7 +116,14 @@ function parseCliOptions(argv: string[]): CliOptions { program.parse(argv, { from: "user" }) const parsed = program.opts<{ host: string - port: number + https?: string + http?: string + httpsPort: number + httpPort: number + tlsKey?: string + tlsCert?: string + tlsCa?: string + tlsSANs?: string workspaceRoot?: string root?: string unrestrictedRoot?: boolean @@ -128,9 +154,23 @@ function parseCliOptions(argv: string[]): CliOptions { const autoUpdateString = (parsed.uiAutoUpdate ?? "true").trim().toLowerCase() const uiAutoUpdate = autoUpdateString === "1" || autoUpdateString === "true" || autoUpdateString === "yes" + const httpsEnabled = parseBooleanEnv(parsed.https) + const httpEnabled = parseBooleanEnv(parsed.http) + + if (!httpsEnabled && !httpEnabled) { + throw new InvalidArgumentError("At least one listener must be enabled (--https or --http)") + } + return { - port: parsed.port, host: normalizedHost, + https: httpsEnabled, + http: httpEnabled, + httpsPort: parsed.httpsPort, + httpPort: parsed.httpPort, + tlsKeyPath: parsed.tlsKey, + tlsCertPath: parsed.tlsCert, + tlsCaPath: parsed.tlsCa, + tlsSANs: parsed.tlsSANs, rootDir: resolvedRoot, configPath: parsed.config, unrestrictedRoot: Boolean(parsed.unrestrictedRoot), @@ -200,12 +240,21 @@ async function main() { const isLoopbackHost = (host: string) => host === "127.0.0.1" || host === "::1" || host.startsWith("127.") + const configLocation = resolveConfigLocation(options.configPath) + const configDir = configLocation.baseDir + + if ((options.tlsKeyPath && !options.tlsCertPath) || (!options.tlsKeyPath && options.tlsCertPath)) { + throw new InvalidArgumentError("--tls-key and --tls-cert must be provided together") + } + const serverMeta: ServerMeta = { - httpBaseUrl: `http://${options.host}:${options.port}`, + localUrl: "http://localhost:0", + remoteUrl: undefined, eventsUrl: `/api/events`, host: options.host, listeningMode: isLoopbackHost(options.host) ? "local" : "all", - port: options.port, + localPort: 0, + remotePort: undefined, hostLabel: options.host, workspaceRoot: options.rootDir, addresses: [], @@ -213,7 +262,7 @@ async function main() { const authManager = new AuthManager( { - configPath: options.configPath, + configPath: configLocation.configYamlPath, username: options.authUsername, password: options.authPassword, generateToken: options.generateToken, @@ -229,7 +278,29 @@ async function main() { } } - const configStore = new ConfigStore(options.configPath, eventBus, configLogger) + const tlsResolution = resolveHttpsOptions({ + enabled: options.https, + configDir, + host: options.host, + tlsKeyPath: options.tlsKeyPath, + tlsCertPath: options.tlsCertPath, + tlsCaPath: options.tlsCaPath, + tlsSANs: options.tlsSANs, + logger: logger.child({ component: "tls" }), + }) + + const nodeExtraCaCertsPath = !options.http ? tlsResolution?.caCertPath : undefined + + const configStore = new ConfigStore(configLocation, eventBus, configLogger) + + // Eagerly load config at boot so migrations run immediately + // (instead of waiting for the first /api/config request). + try { + configStore.get() + } catch (error) { + configLogger.warn({ err: error }, "Failed to load config at boot; continuing with defaults") + } + const binaryRegistry = new BinaryRegistry(configStore, eventBus, configLogger) const workspaceManager = new WorkspaceManager({ rootDir: options.rootDir, @@ -237,10 +308,11 @@ async function main() { binaryRegistry, eventBus, logger: workspaceLogger, - getServerBaseUrl: () => serverMeta.httpBaseUrl, + getServerBaseUrl: () => serverMeta.localUrl, + nodeExtraCaCertsPath, }) const fileSystemBrowser = new FileSystemBrowser({ rootDir: options.rootDir, unrestricted: options.unrestrictedRoot }) - const instanceStore = new InstanceStore() + const instanceStore = new InstanceStore(configLocation.instancesDir) const instanceEventBridge = new InstanceEventBridge({ workspaceManager, eventBus, @@ -261,6 +333,7 @@ async function main() { overrideUiDir: uiDirOverride, uiDevServerUrl: options.uiDevServer, manifestUrl: options.uiManifestUrl, + packaged: Boolean(process.env.CODENOMAD_PACKAGED), logger: logger.child({ component: "ui" }), }) @@ -277,28 +350,140 @@ async function main() { minServerVersion: uiResolution.minServerVersion, } - const server = createHttpServer({ - host: options.host, - port: options.port, - workspaceManager, - configStore, - binaryRegistry, - fileSystemBrowser, - eventBus, - serverMeta, - instanceStore, - authManager, - uiStaticDir: uiResolution.uiStaticDir ?? DEFAULT_UI_STATIC_DIR, - uiDevServerUrl: uiResolution.uiDevServerUrl, - logger, - }) + const updateChannel = (process.env.CODENOMAD_UPDATE_CHANNEL ?? "").trim().toLowerCase() + const githubRepo = (process.env.CODENOMAD_GITHUB_REPO ?? "NeuralNomadsAI/CodeNomad").trim() + const isDevVersion = packageJson.version.includes("-dev.") || packageJson.version.includes("-dev-") + const enableDevUpdateChecks = updateChannel === "dev" || (updateChannel === "" && isDevVersion) + const devReleaseMonitor = enableDevUpdateChecks + ? startDevReleaseMonitor({ + currentVersion: packageJson.version, + repo: githubRepo, + logger: logger.child({ component: "updates" }), + onUpdate: (release) => { + serverMeta.update = release + }, + }) + : null + + if (uiResolution.uiDevServerUrl && options.https) { + throw new InvalidArgumentError("UI dev proxy is only supported with --https=false --http=true") + } - const startInfo = await server.start() - logger.info({ port: startInfo.port, host: options.host }, "HTTP server listening") - console.log(`CodeNomad Server is ready at ${startInfo.url}`) + const remoteAccessEnabled = options.host === "0.0.0.0" || !isLoopbackHost(options.host) + + const httpsPortExplicit = programHasArg(process.argv.slice(2), "--https-port") || Boolean(process.env.CLI_HTTPS_PORT) + const httpPortExplicit = programHasArg(process.argv.slice(2), "--http-port") || Boolean(process.env.CLI_HTTP_PORT) + + const httpsBindPort = httpsPortExplicit ? options.httpsPort : 0 + const httpBindPort = httpPortExplicit ? options.httpPort : 0 + + // Listener binding rules: + // - Remote access enabled: HTTP listens on loopback, HTTPS on all IPs (host=0.0.0.0 / LAN IP). + // - Remote access disabled: both listen on loopback. + // - HTTP-only mode: respect --host (used for dev/testing). + const httpsBindHost = remoteAccessEnabled ? options.host : "127.0.0.1" + const httpBindHost = options.http ? (options.https ? "127.0.0.1" : options.host) : "127.0.0.1" + + const servers: Array> = [] + + const httpServer = options.http + ? createHttpServer({ + bindHost: httpBindHost, + bindPort: httpBindPort, + defaultPort: options.httpPort, + protocol: "http", + workspaceManager, + configStore, + binaryRegistry, + fileSystemBrowser, + eventBus, + serverMeta, + instanceStore, + authManager, + uiStaticDir: uiResolution.uiStaticDir ?? DEFAULT_UI_STATIC_DIR, + uiDevServerUrl: uiResolution.uiDevServerUrl, + logger, + }) + : null + + const httpsServer = options.https + ? createHttpServer({ + bindHost: httpsBindHost, + bindPort: httpsBindPort, + defaultPort: options.httpsPort, + protocol: "https", + httpsOptions: tlsResolution?.httpsOptions, + workspaceManager, + configStore, + binaryRegistry, + fileSystemBrowser, + eventBus, + serverMeta, + instanceStore, + authManager, + uiStaticDir: uiResolution.uiStaticDir ?? DEFAULT_UI_STATIC_DIR, + uiDevServerUrl: undefined, + logger, + }) + : null + + if (httpServer) servers.push(httpServer) + if (httpsServer) servers.push(httpsServer) + + const [httpStart, httpsStart] = await Promise.all([ + httpServer ? httpServer.start() : Promise.resolve(null), + httpsServer ? httpsServer.start() : Promise.resolve(null), + ]) + + const localStart = httpStart ?? httpsStart + if (!localStart) { + throw new Error("No listeners started") + } + + const remoteStart = httpsStart ?? httpStart + const localProtocol: "http" | "https" = httpStart ? "http" : "https" + const remoteProtocol: "http" | "https" = httpsStart ? "https" : "http" + + // Use an explicit IPv4 loopback address for the "local" URL. + // On macOS, `localhost` often resolves to ::1 first, and it is possible to have + // another instance bound on IPv6 while this instance binds IPv4 (or vice versa), + // which can lead clients to talk to the wrong process. + const localUrl = `${localProtocol}://127.0.0.1:${localStart.port}` + let remoteUrl: string | undefined + if (remoteStart) { + const wantsAll = options.host === "0.0.0.0" || !isLoopbackHost(options.host) + let remoteHost = options.host + if (wantsAll) { + if (options.host === "0.0.0.0") { + const candidates = resolveNetworkAddresses({ host: options.host, protocol: remoteProtocol, port: remoteStart.port }) + remoteHost = candidates.find((addr) => addr.scope === "external")?.ip ?? "localhost" + } + } else { + remoteHost = "localhost" + } + remoteUrl = `${remoteProtocol}://${remoteHost}:${remoteStart.port}` + } + + serverMeta.localUrl = localUrl + serverMeta.localPort = localStart.port + serverMeta.remoteUrl = remoteUrl + serverMeta.remotePort = remoteStart?.port + serverMeta.host = options.host + serverMeta.listeningMode = options.host === "0.0.0.0" || !isLoopbackHost(options.host) ? "all" : "local" + + if (serverMeta.remotePort && remoteUrl) { + serverMeta.addresses = resolveNetworkAddresses({ host: options.host, protocol: remoteProtocol, port: serverMeta.remotePort }) + } else { + serverMeta.addresses = [] + } + + console.log(`Local Connection URL : ${serverMeta.localUrl}`) + if (serverMeta.remoteUrl) { + console.log(`Remote Connection URL : ${serverMeta.remoteUrl}`) + } if (options.launch) { - await launchInBrowser(startInfo.url, logger.child({ component: "launcher" })) + await launchInBrowser(serverMeta.localUrl, logger.child({ component: "launcher" })) } let shuttingDown = false @@ -328,8 +513,8 @@ async function main() { const shutdownHttp = (async () => { try { - await server.stop() - logger.info("HTTP server stopped") + await Promise.allSettled(servers.map((srv) => srv.stop())) + logger.info("HTTP server(s) stopped") } catch (error) { logger.error({ err: error }, "Failed to stop HTTP server") } @@ -339,6 +524,8 @@ async function main() { // no-op: remote UI manifest replaces GitHub release monitor + devReleaseMonitor?.stop() + logger.info("Exiting process") process.exit(0) } diff --git a/packages/server/src/releases/dev-release-monitor.ts b/packages/server/src/releases/dev-release-monitor.ts new file mode 100644 index 00000000..5fe405d8 --- /dev/null +++ b/packages/server/src/releases/dev-release-monitor.ts @@ -0,0 +1,118 @@ +import { fetch } from "undici" +import type { LatestReleaseInfo } from "../api-types" +import type { Logger } from "../logger" +import { compareVersionStrings, stripTagPrefix } from "./release-monitor" + +interface DevReleaseMonitorOptions { + /** Current running server version (from package.json). */ + currentVersion: string + /** GitHub repo in the form "owner/name". */ + repo: string + logger: Logger + onUpdate: (release: LatestReleaseInfo | null) => void + pollIntervalMs?: number +} + +interface GithubReleaseListItem { + tag_name?: string + name?: string + html_url?: string + body?: string + published_at?: string + created_at?: string + prerelease?: boolean + draft?: boolean +} + +export interface DevReleaseMonitor { + stop(): void +} + +const DEFAULT_POLL_INTERVAL_MS = 15 * 60 * 1000 + +export function startDevReleaseMonitor(options: DevReleaseMonitorOptions): DevReleaseMonitor { + let stopped = false + let timer: ReturnType | null = null + + const pollIntervalMs = + Number.isFinite(options.pollIntervalMs) && (options.pollIntervalMs ?? 0) > 0 + ? (options.pollIntervalMs as number) + : DEFAULT_POLL_INTERVAL_MS + + const refresh = async () => { + if (stopped) return + try { + const release = await fetchLatestPrerelease({ + repo: options.repo, + currentVersion: options.currentVersion, + }) + options.onUpdate(release) + } catch (error) { + options.logger.debug({ err: error }, "Failed to refresh dev prerelease information") + } + } + + void refresh() + timer = setInterval(() => void refresh(), pollIntervalMs) + + return { + stop() { + stopped = true + if (timer) { + clearInterval(timer) + timer = null + } + }, + } +} + +async function fetchLatestPrerelease(args: { + repo: string + currentVersion: string +}): Promise { + const normalizedRepo = args.repo.trim() + if (!/^[^/\s]+\/[^/\s]+$/.test(normalizedRepo)) { + throw new Error(`Invalid GitHub repo: ${args.repo}`) + } + + const apiUrl = `https://api.github.com/repos/${normalizedRepo}/releases?per_page=20` + const response = await fetch(apiUrl, { + headers: { + Accept: "application/vnd.github+json", + "User-Agent": "CodeNomad-CLI", + }, + }) + + if (!response.ok) { + throw new Error(`GitHub releases API responded with ${response.status}`) + } + + const list = (await response.json()) as GithubReleaseListItem[] + const latest = list.find((r) => r && r.prerelease === true && r.draft !== true) + if (!latest) { + return null + } + + const tag = latest.tag_name || latest.name + if (!tag) { + return null + } + + const normalizedVersion = stripTagPrefix(tag) + if (!normalizedVersion) { + return null + } + + if (compareVersionStrings(normalizedVersion, args.currentVersion) <= 0) { + return null + } + + return { + version: normalizedVersion, + tag, + url: latest.html_url ?? `https://github.com/${normalizedRepo}/releases/tag/${encodeURIComponent(tag)}`, + channel: "dev", + publishedAt: latest.published_at ?? latest.created_at, + notes: latest.body, + } +} diff --git a/packages/server/src/releases/release-monitor.ts b/packages/server/src/releases/release-monitor.ts index 2fd80c99..11f97d5c 100644 --- a/packages/server/src/releases/release-monitor.ts +++ b/packages/server/src/releases/release-monitor.ts @@ -52,6 +52,12 @@ export function startReleaseMonitor(options: ReleaseMonitorOptions): ReleaseMoni } } +export function compareVersionStrings(a: string, b: string): number { + const left = parseVersion(a) + const right = parseVersion(b) + return compareVersions(left, right) +} + async function fetchLatestRelease(options: ReleaseMonitorOptions): Promise { const response = await fetch(RELEASES_API_URL, { headers: { @@ -92,7 +98,7 @@ async function fetchLatestRelease(options: ReleaseMonitorOptions): Promise= 0 ? normalized.slice(0, dashIndex) : normalized + const prerelease = dashIndex >= 0 ? normalized.slice(dashIndex + 1) : null const [major = 0, minor = 0, patch = 0] = core.split(".").map((segment) => { const parsed = Number.parseInt(segment, 10) return Number.isFinite(parsed) ? parsed : 0 diff --git a/packages/server/src/server/http-server.ts b/packages/server/src/server/http-server.ts index 0da95d16..7f31f081 100644 --- a/packages/server/src/server/http-server.ts +++ b/packages/server/src/server/http-server.ts @@ -7,6 +7,7 @@ import path from "path" import { fetch } from "undici" import type { Logger } from "../logger" import { WorkspaceManager } from "../workspaces/manager" +import { isValidWorktreeSlug, listWorktrees, resolveRepoRoot } from "../workspaces/git-worktrees" import { ConfigStore } from "../config/store" import { BinaryRegistry } from "../config/binaries" @@ -20,6 +21,8 @@ import { registerEventRoutes } from "./routes/events" import { registerStorageRoutes } from "./routes/storage" import { registerPluginRoutes } from "./routes/plugin" import { registerBackgroundProcessRoutes } from "./routes/background-processes" +import { registerGitRoutes } from "./routes/git" +import { registerWorktreeRoutes } from "./routes/worktrees" import { ServerMeta } from "../api-types" import { InstanceStore } from "../storage/instance-store" import { BackgroundProcessManager } from "../background-processes/manager" @@ -28,8 +31,12 @@ import { registerAuthRoutes } from "./routes/auth" import { sendUnauthorized, wantsHtml } from "../auth/http-auth" interface HttpServerDeps { - host: string - port: number + bindHost: string + bindPort: number + /** When bindPort is 0, try this first. */ + defaultPort: number + protocol: "http" | "https" + httpsOptions?: { key: string | Buffer; cert: string | Buffer; ca?: string | Buffer } workspaceManager: WorkspaceManager configStore: ConfigStore binaryRegistry: BinaryRegistry @@ -49,10 +56,15 @@ interface HttpServerStartResult { displayHost: string } -const DEFAULT_HTTP_PORT = 9898 - export function createHttpServer(deps: HttpServerDeps) { - const app = Fastify({ logger: false }) + // Fastify's type-level RawServer inference gets noisy when toggling HTTP vs HTTPS. + // We keep the runtime behavior correct and cast the instance to a generic FastifyInstance. + const app = Fastify( + ({ + logger: false, + ...(deps.protocol === "https" && deps.httpsOptions ? { https: deps.httpsOptions } : {}), + } as unknown) as any, + ) as unknown as FastifyInstance const proxyLogger = deps.logger.child({ component: "proxy" }) const apiLogger = deps.logger.child({ component: "http" }) const sseLogger = deps.logger.child({ component: "sse" }) @@ -70,7 +82,7 @@ export function createHttpServer(deps: HttpServerDeps) { } app.addHook("onRequest", (request, _reply, done) => { - ;(request as FastifyRequest & { __logMeta?: { start: bigint } }).__logMeta = { + ; (request as FastifyRequest & { __logMeta?: { start: bigint } }).__logMeta = { start: process.hrtime.bigint(), } done() @@ -95,6 +107,27 @@ export function createHttpServer(deps: HttpServerDeps) { const allowedDevOrigins = new Set(["http://localhost:3000", "http://127.0.0.1:3000"]) const isLoopbackHost = (host: string) => host === "127.0.0.1" || host === "::1" || host.startsWith("127.") + const getSelfOrigins = (): Set => { + const origins = new Set() + const candidates: Array = [deps.serverMeta.localUrl, deps.serverMeta.remoteUrl] + for (const candidate of candidates) { + if (!candidate) continue + try { + origins.add(new URL(candidate).origin) + } catch { + // ignore + } + } + for (const addr of deps.serverMeta.addresses ?? []) { + try { + origins.add(new URL(addr.remoteUrl).origin) + } catch { + // ignore + } + } + return origins + } + app.register(cors, { origin: (origin, cb) => { if (!origin) { @@ -102,14 +135,8 @@ export function createHttpServer(deps: HttpServerDeps) { return } - let selfOrigin: string | null = null - try { - selfOrigin = new URL(deps.serverMeta.httpBaseUrl).origin - } catch { - selfOrigin = null - } - - if (selfOrigin && origin === selfOrigin) { + const selfOrigins = getSelfOrigins() + if (selfOrigins.has(origin)) { cb(null, true) return } @@ -120,7 +147,7 @@ export function createHttpServer(deps: HttpServerDeps) { } // When we bind to a non-loopback host (e.g., 0.0.0.0 or LAN IP), allow cross-origin UI access. - if (deps.host === "0.0.0.0" || !isLoopbackHost(deps.host)) { + if (deps.bindHost === "0.0.0.0" || !isLoopbackHost(deps.bindHost)) { cb(null, true) return } @@ -222,6 +249,7 @@ export function createHttpServer(deps: HttpServerDeps) { registerFilesystemRoutes(app, { fileSystemBrowser: deps.fileSystemBrowser }) registerMetaRoutes(app, { serverMeta: deps.serverMeta }) registerEventRoutes(app, { eventBus: deps.eventBus, registerClient: registerSseClient, logger: sseLogger }) + registerWorktreeRoutes(app, { workspaceManager: deps.workspaceManager }) registerStorageRoutes(app, { instanceStore: deps.instanceStore, eventBus: deps.eventBus, @@ -229,6 +257,7 @@ export function createHttpServer(deps: HttpServerDeps) { }) registerPluginRoutes(app, { workspaceManager: deps.workspaceManager, eventBus: deps.eventBus, logger: proxyLogger }) registerBackgroundProcessRoutes(app, { backgroundProcessManager }) + registerGitRoutes(app, { workspaceManager: deps.workspaceManager }) registerInstanceProxyRoutes(app, { workspaceManager: deps.workspaceManager, logger: proxyLogger }) @@ -242,12 +271,12 @@ export function createHttpServer(deps: HttpServerDeps) { instance: app, start: async (): Promise => { const attemptListen = async (requestedPort: number) => { - const addressInfo = await app.listen({ port: requestedPort, host: deps.host }) + const addressInfo = await app.listen({ port: requestedPort, host: deps.bindHost }) return { addressInfo, requestedPort } } - const autoPortRequested = deps.port === 0 - const primaryPort = autoPortRequested ? DEFAULT_HTTP_PORT : deps.port + const autoPortRequested = deps.bindPort === 0 + const primaryPort = autoPortRequested ? deps.defaultPort : deps.bindPort const shouldRetryWithEphemeral = (error: unknown) => { if (!autoPortRequested) return false @@ -283,15 +312,10 @@ export function createHttpServer(deps: HttpServerDeps) { } } - const displayHost = deps.host === "127.0.0.1" ? "localhost" : deps.host - const serverUrl = `http://${displayHost}:${actualPort}` + const displayHost = deps.bindHost === "127.0.0.1" ? "localhost" : deps.bindHost + const serverUrl = `${deps.protocol}://${displayHost}:${actualPort}` - deps.serverMeta.httpBaseUrl = serverUrl - deps.serverMeta.host = deps.host - deps.serverMeta.port = actualPort - deps.serverMeta.listeningMode = deps.host === "0.0.0.0" || !isLoopbackHost(deps.host) ? "all" : "local" - deps.logger.info({ port: actualPort, host: deps.host }, "HTTP server listening") - console.log(`CodeNomad Server is ready at ${serverUrl}`) + deps.logger.info({ port: actualPort, host: deps.bindHost, protocol: deps.protocol }, "HTTP server listening") return { port: actualPort, url: serverUrl, displayHost } }, @@ -312,31 +336,36 @@ function registerInstanceProxyRoutes(app: FastifyInstance, deps: InstanceProxyDe instance.removeAllContentTypeParsers() instance.addContentTypeParser("*", (req, body, done) => done(null, body)) - const proxyBaseHandler = async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => { + const proxyBaseHandler = async ( + request: FastifyRequest<{ Params: { id: string; slug: string } }>, + reply: FastifyReply, + ) => { await proxyWorkspaceRequest({ request, reply, workspaceManager: deps.workspaceManager, + worktreeSlug: request.params.slug, pathSuffix: "", logger: deps.logger, }) } const proxyWildcardHandler = async ( - request: FastifyRequest<{ Params: { id: string; "*": string } }>, + request: FastifyRequest<{ Params: { id: string; slug: string; "*": string } }>, reply: FastifyReply, ) => { await proxyWorkspaceRequest({ request, reply, workspaceManager: deps.workspaceManager, + worktreeSlug: request.params.slug, pathSuffix: request.params["*"] ?? "", logger: deps.logger, }) } - instance.all("/workspaces/:id/instance", proxyBaseHandler) - instance.all("/workspaces/:id/instance/*", proxyWildcardHandler) + instance.all("/workspaces/:id/worktrees/:slug/instance", proxyBaseHandler) + instance.all("/workspaces/:id/worktrees/:slug/instance/*", proxyWildcardHandler) }) } @@ -347,12 +376,75 @@ async function proxyWorkspaceRequest(args: { reply: FastifyReply workspaceManager: WorkspaceManager logger: Logger + worktreeSlug: string pathSuffix?: string }) { - const { request, reply, workspaceManager, logger } = args + const { request, reply, workspaceManager, logger, worktreeSlug } = args const workspaceId = (request.params as { id: string }).id const workspace = workspaceManager.get(workspaceId) + const bodyToJson = (body: unknown): unknown => { + if (body == null) return null + + const anyBody = body as any + if (anyBody && typeof anyBody.pipe === "function") { + // Don't consume streams (would break proxying). + // Best-effort: if the stream already has buffered chunks, parse those. + try { + const buffered = anyBody?._readableState?.buffer + if (Array.isArray(buffered) && buffered.length > 0) { + const chunks: Buffer[] = [] + for (const entry of buffered) { + if (!entry) continue + if (Buffer.isBuffer(entry)) { + chunks.push(entry) + continue + } + const data = (entry as any).data + if (Buffer.isBuffer(data)) { + chunks.push(data) + } + } + + if (chunks.length > 0) { + const text = Buffer.concat(chunks).toString("utf-8") + try { + return JSON.parse(text) + } catch { + return { __raw: text } + } + } + } + } catch { + // fall through + } + + return { __stream: true } + } + + const maybeParse = (input: string): unknown => { + try { + return JSON.parse(input) + } catch { + return { __raw: input } + } + } + + if (Buffer.isBuffer(body)) { + return maybeParse(body.toString("utf-8")) + } + + if (typeof body === "string") { + return maybeParse(body) + } + + if (typeof body === "object") { + return body + } + + return body + } + if (!workspace) { reply.code(404).send({ error: "Workspace not found" }) return @@ -364,6 +456,23 @@ async function proxyWorkspaceRequest(args: { return } + if (!isValidWorktreeSlug(worktreeSlug)) { + reply.code(400).send({ error: "Invalid worktree slug" }) + return + } + + const directory = await resolveWorktreeDirectory({ + workspaceId, + workspacePath: workspace.path, + worktreeSlug, + logger, + }) + + if (!directory) { + reply.code(404).send({ error: "Worktree not found" }) + return + } + const normalizedSuffix = normalizeInstanceSuffix(args.pathSuffix) const queryIndex = (request.raw.url ?? "").indexOf("?") const search = queryIndex >= 0 ? (request.raw.url ?? "").slice(queryIndex) : "" @@ -381,15 +490,42 @@ async function proxyWorkspaceRequest(args: { headers.authorization = instanceAuthHeader } - // Enforce per-workspace directory scoping for all proxied OpenCode requests. // OpenCode expects the *full* path; we send it via header to avoid query tampering. - const directory = workspace.path const isNonASCII = /[^\x00-\x7F]/.test(directory) const encodedDirectory = isNonASCII ? encodeURIComponent(directory) : directory // Overwrite any client-provided value (case-insensitive headers are normalized by Node). ;(headers as Record)["x-opencode-directory"] = encodedDirectory + if (logger.isLevelEnabled("trace")) { + const outgoing: Record = {} + for (const [key, value] of Object.entries(headers as Record)) { + outgoing[key] = value + } + + // Redact sensitive headers. + for (const key of Object.keys(outgoing)) { + const lower = key.toLowerCase() + if (lower === "authorization" || lower === "cookie" || lower === "set-cookie") { + outgoing[key] = "" + } + } + + logger.trace( + { + workspaceId, + method: request.method, + targetUrl, + worktreeSlug, + directory, + contentType: request.headers["content-type"], + body: bodyToJson(request.body), + headers: outgoing, + }, + "Proxy -> OpenCode request", + ) + } + return headers }, onError: (proxyReply, { error }) => { @@ -409,6 +545,52 @@ function normalizeInstanceSuffix(pathSuffix: string | undefined) { return trimmed.length === 0 ? "/" : `/${trimmed}` } +type WorktreeCacheEntry = { + expiresAt: number + repoRoot: string + worktrees: Array<{ slug: string; directory: string }> +} + +const WORKTREE_CACHE_TTL_MS = 2000 +const worktreeCache = new Map() + +async function getCachedWorktrees(params: { workspaceId: string; workspacePath: string; logger: Logger }) { + const cached = worktreeCache.get(params.workspaceId) + const now = Date.now() + if (cached && cached.expiresAt > now) { + return cached + } + + const { repoRoot } = await resolveRepoRoot(params.workspacePath, params.logger) + const worktrees = await listWorktrees({ repoRoot, workspaceFolder: params.workspacePath, logger: params.logger }) + const entry: WorktreeCacheEntry = { + expiresAt: now + WORKTREE_CACHE_TTL_MS, + repoRoot, + worktrees: worktrees.map((wt) => ({ slug: wt.slug, directory: wt.directory })), + } + worktreeCache.set(params.workspaceId, entry) + return entry +} + +async function resolveWorktreeDirectory(params: { + workspaceId: string + workspacePath: string + worktreeSlug: string + logger: Logger +}): Promise { + const { worktreeSlug } = params + const cached = await getCachedWorktrees({ workspaceId: params.workspaceId, workspacePath: params.workspacePath, logger: params.logger }) + const match = cached.worktrees.find((wt) => wt.slug === worktreeSlug) + if (match) { + return match.directory + } + + // If the slug is new (e.g., created moments ago), refresh once. + worktreeCache.delete(params.workspaceId) + const refreshed = await getCachedWorktrees({ workspaceId: params.workspaceId, workspacePath: params.workspacePath, logger: params.logger }) + return refreshed.worktrees.find((wt) => wt.slug === worktreeSlug)?.directory ?? null +} + function setupStaticUi(app: FastifyInstance, uiDir: string, authManager: AuthManager) { if (!uiDir) { app.log.warn("UI static directory not provided; API endpoints only") diff --git a/packages/server/src/server/network-addresses.ts b/packages/server/src/server/network-addresses.ts new file mode 100644 index 00000000..ffedd821 --- /dev/null +++ b/packages/server/src/server/network-addresses.ts @@ -0,0 +1,75 @@ +import os from "os" +import type { NetworkAddress } from "../api-types" + +export function resolveNetworkAddresses(args: { + host: string + protocol: "http" | "https" + port: number +}): NetworkAddress[] { + const { host, protocol, port } = args + const interfaces = os.networkInterfaces() + const seen = new Set() + const results: NetworkAddress[] = [] + + const addAddress = (ip: string, scope: NetworkAddress["scope"]) => { + if (!ip || ip === "0.0.0.0") return + const key = `ipv4-${ip}` + if (seen.has(key)) return + seen.add(key) + results.push({ ip, family: "ipv4", scope, remoteUrl: `${protocol}://${ip}:${port}` }) + } + + const normalizeFamily = (value: string | number) => { + if (typeof value === "string") { + const lowered = value.toLowerCase() + if (lowered === "ipv4") { + return "ipv4" as const + } + } + if (value === 4) return "ipv4" as const + return null + } + + if (host === "0.0.0.0") { + // Enumerate system interfaces (IPv4 only) + for (const entries of Object.values(interfaces)) { + if (!entries) continue + for (const entry of entries) { + const family = normalizeFamily(entry.family) + if (!family) continue + if (!entry.address || entry.address === "0.0.0.0") continue + const scope: NetworkAddress["scope"] = entry.internal ? "loopback" : "external" + addAddress(entry.address, scope) + } + } + } + + // Always include loopback address + addAddress("127.0.0.1", "loopback") + + // Include explicitly configured host if it was IPv4 + if (isIPv4Address(host) && host !== "0.0.0.0") { + const isLoopback = host.startsWith("127.") + addAddress(host, isLoopback ? "loopback" : "external") + } + + const scopeWeight: Record = { external: 0, internal: 1, loopback: 2 } + + return results.sort((a, b) => { + const scopeDelta = scopeWeight[a.scope] - scopeWeight[b.scope] + if (scopeDelta !== 0) return scopeDelta + return a.ip.localeCompare(b.ip) + }) +} + +function isIPv4Address(value: string | undefined): value is string { + if (!value) return false + const parts = value.split(".") + if (parts.length !== 4) return false + return parts.every((part) => { + if (part.length === 0 || part.length > 3) return false + if (!/^[0-9]+$/.test(part)) return false + const num = Number(part) + return Number.isInteger(num) && num >= 0 && num <= 255 + }) +} diff --git a/packages/server/src/server/routes/auth.ts b/packages/server/src/server/routes/auth.ts index 13401f23..e47da74a 100644 --- a/packages/server/src/server/routes/auth.ts +++ b/packages/server/src/server/routes/auth.ts @@ -88,7 +88,7 @@ export function registerAuthRoutes(app: FastifyInstance, deps: RouteDeps) { } const session = deps.authManager.createSession(body.username) - deps.authManager.setSessionCookie(reply, session.id) + deps.authManager.setSessionCookieWithOptions(reply, session.id, { secure: isSecureRequest(request) }) reply.send({ ok: true }) }) @@ -112,12 +112,12 @@ export function registerAuthRoutes(app: FastifyInstance, deps: RouteDeps) { const username = deps.authManager.getStatus().username const session = deps.authManager.createSession(username) - deps.authManager.setSessionCookie(reply, session.id) + deps.authManager.setSessionCookieWithOptions(reply, session.id, { secure: isSecureRequest(request) }) reply.send({ ok: true }) }) - app.post("/api/auth/logout", async (_request, reply) => { - deps.authManager.clearSessionCookie(reply) + app.post("/api/auth/logout", async (request, reply) => { + deps.authManager.clearSessionCookieWithOptions(reply, { secure: isSecureRequest(request) }) reply.send({ ok: true }) }) @@ -139,6 +139,13 @@ export function registerAuthRoutes(app: FastifyInstance, deps: RouteDeps) { }) } +function isSecureRequest(request: any) { + if (request.protocol === "https") { + return true + } + return Boolean(request.raw?.socket && request.raw.socket.encrypted) +} + function escapeHtml(value: string) { return value.replace(/[&<>"]/g, (char) => { switch (char) { diff --git a/packages/server/src/server/routes/config.ts b/packages/server/src/server/routes/config.ts index fed364af..ea4e03c5 100644 --- a/packages/server/src/server/routes/config.ts +++ b/packages/server/src/server/routes/config.ts @@ -2,7 +2,6 @@ import { FastifyInstance } from "fastify" import { z } from "zod" import { ConfigStore } from "../../config/store" import { BinaryRegistry } from "../../config/binaries" -import { ConfigFileSchema } from "../../config/schema" interface RouteDeps { configStore: ConfigStore @@ -27,10 +26,25 @@ const BinaryValidateSchema = z.object({ export function registerConfigRoutes(app: FastifyInstance, deps: RouteDeps) { app.get("/api/config/app", async () => deps.configStore.get()) - app.put("/api/config/app", async (request) => { - const body = ConfigFileSchema.parse(request.body ?? {}) - deps.configStore.replace(body) - return deps.configStore.get() + app.put("/api/config/app", async (request, reply) => { + // Backwards compatible: treat PUT as a merge-patch update. + try { + deps.configStore.mergePatch(request.body ?? {}) + return deps.configStore.get() + } catch (error) { + reply.code(400) + return { error: error instanceof Error ? error.message : "Invalid config patch" } + } + }) + + app.patch("/api/config/app", async (request, reply) => { + try { + deps.configStore.mergePatch(request.body ?? {}) + return deps.configStore.get() + } catch (error) { + reply.code(400) + return { error: error instanceof Error ? error.message : "Invalid config patch" } + } }) app.get("/api/config/binaries", async () => { diff --git a/packages/server/src/server/routes/git.ts b/packages/server/src/server/routes/git.ts new file mode 100644 index 00000000..3b7a5fdc --- /dev/null +++ b/packages/server/src/server/routes/git.ts @@ -0,0 +1,721 @@ +import type { FastifyInstance } from "fastify" +import { exec } from "child_process" +import { promisify } from "util" +import path from "path" +import { promises as fs } from "fs" +import type { WorkspaceManager } from "../../workspaces/manager" +import type { + GitStatus, + GitFileChange, + GitFileStatus, + GitBranch, + GitBranchListResponse, + GitDiffResponse, + GitCommitRequest, + GitCommitResponse, + GitCheckoutRequest, + GitStageRequest, + GitPushResponse, +} from "../../api-types" + +const execAsync = promisify(exec) + +interface GitRoutesDeps { + workspaceManager: WorkspaceManager +} + +async function runGitCommand(cwd: string, args: string): Promise { + try { + const { stdout } = await execAsync(`git ${args}`, { + cwd, + maxBuffer: 10 * 1024 * 1024, // 10MB buffer for large diffs + }) + // Only trim trailing whitespace to preserve leading spaces in porcelain format + return stdout.trimEnd() + } catch (error) { + const execError = error as { stderr?: string; message?: string } + throw new Error(execError.stderr || execError.message || "Git command failed") + } +} + +async function isGitRepository(cwd: string): Promise { + try { + await runGitCommand(cwd, "rev-parse --git-dir") + return true + } catch { + return false + } +} + +/** + * Check if a file is likely binary by examining its extension + * Returns true for common binary file extensions + */ +function isBinaryFile(filePath: string): boolean { + const ext = path.extname(filePath).toLowerCase() + const binaryExtensions = [ + '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico', '.svg', '.webp', + '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', + '.zip', '.tar', '.gz', '.bz2', '.7z', '.rar', + '.exe', '.dll', '.so', '.dylib', '.a', '.lib', + '.mp3', '.mp4', '.avi', '.mov', '.wav', '.flac', + '.ttf', '.otf', '.woff', '.woff2', '.eot', + '.bin', '.dat', '.db', '.sqlite', '.sqlite3', + '.class', '.jar', '.war', '.ear', + '.o', '.obj', '.pyc', '.pyo', + ] + return binaryExtensions.includes(ext) +} + +/** + * Check if file content is binary by examining bytes + * Returns true if file contains null bytes or high ratio of non-text bytes + */ +async function isBinaryContent(fullPath: string): Promise { + try { + const buffer = await fs.readFile(fullPath) + const chunkSize = Math.min(buffer.length, 8192) // Read first 8KB + + // Check for null bytes (strong indicator of binary) + for (let i = 0; i < chunkSize; i++) { + if (buffer[i] === 0) { + return true + } + } + + // Check for high ratio of non-text bytes (bytes > 127) + let nonTextCount = 0 + for (let i = 0; i < chunkSize; i++) { + if (buffer[i] > 127) { + nonTextCount++ + } + } + + // If more than 30% of bytes are non-text, consider it binary + const ratio = nonTextCount / chunkSize + return ratio > 0.3 + } catch { + // If we can't read the file, assume it's not binary to avoid blocking access + return false + } +} + +function parseStatusLine(line: string): GitFileChange[] { + if (line.length < 3) return [] + + const indexStatus = line[0] + const worktreeStatus = line[1] + const filePath = line.slice(3) + + // Handle renames (format: "R old -> new") + let actualPath = filePath + let originalPath: string | undefined + if (filePath.includes(" -> ")) { + const parts = filePath.split(" -> ") + originalPath = parts[0] + actualPath = parts[1] + } + + const changes: GitFileChange[] = [] + + // Handle untracked files + if (indexStatus === "?" && worktreeStatus === "?") { + changes.push({ + path: actualPath, + status: "untracked", + staged: false, + }) + return changes + } + + // Handle ignored files + if (indexStatus === "!" && worktreeStatus === "!") { + changes.push({ + path: actualPath, + status: "ignored", + staged: false, + }) + return changes + } + + // Handle staged changes (index status is not space or question mark) + if (indexStatus !== " " && indexStatus !== "?") { + let status: GitFileStatus + switch (indexStatus) { + case "M": + status = "modified" + break + case "A": + status = "added" + break + case "D": + status = "deleted" + break + case "R": + status = "renamed" + break + case "C": + status = "copied" + break + default: + status = "modified" + } + + changes.push({ + path: actualPath, + status, + staged: true, + originalPath, + }) + } + + // Handle unstaged changes (worktree status is not space or question mark) + if (worktreeStatus !== " " && worktreeStatus !== "?") { + let status: GitFileStatus + switch (worktreeStatus) { + case "M": + status = "modified" + break + case "D": + status = "deleted" + break + default: + status = "modified" + } + + changes.push({ + path: actualPath, + status, + staged: false, + }) + } + + return changes +} + +async function getGitStatus(cwd: string): Promise { + // Check if there are any commits + let hasCommits = true + try { + await runGitCommand(cwd, "rev-parse HEAD") + } catch { + hasCommits = false + } + + // Get current branch + let branch = "HEAD" + try { + branch = await runGitCommand(cwd, "symbolic-ref --short HEAD") + } catch { + // Detached HEAD state + try { + branch = (await runGitCommand(cwd, "rev-parse --short HEAD")).slice(0, 7) + } catch { + branch = "HEAD" + } + } + + // Get ahead/behind counts + let ahead = 0 + let behind = 0 + try { + const tracking = await runGitCommand(cwd, "rev-parse --abbrev-ref @{upstream}") + if (tracking) { + const counts = await runGitCommand(cwd, `rev-list --left-right --count HEAD...@{upstream}`) + const [aheadStr, behindStr] = counts.split("\t") + ahead = parseInt(aheadStr, 10) || 0 + behind = parseInt(behindStr, 10) || 0 + } + } catch { + // No upstream tracking + // Fallback: count commits not pushed to any remote + try { + const count = await runGitCommand(cwd, "rev-list --count HEAD --not --remotes") + ahead = parseInt(count, 10) || 0 + } catch { + // Ignore error + } + } + + // Get file status + const statusOutput = await runGitCommand(cwd, "status --porcelain=v1") + const changes: GitFileChange[] = [] + + if (statusOutput) { + for (const line of statusOutput.split("\n")) { + const lineChanges = parseStatusLine(line) + changes.push(...lineChanges) + } + } + + return { + branch, + changes, + hasCommits, + ahead, + behind, + } +} + +async function getBranches(cwd: string): Promise { + const branches: GitBranch[] = [] + let current = "" + + // Get local branches + try { + const localOutput = await runGitCommand(cwd, "branch --format='%(refname:short)|%(upstream:short)|%(HEAD)'") + for (const line of localOutput.split("\n")) { + if (!line.trim()) continue + const cleanLine = line.replace(/'/g, "") + const [name, upstream, head] = cleanLine.split("|") + const isCurrent = head === "*" + if (isCurrent) current = name + branches.push({ + name, + current: isCurrent, + remote: false, + upstream: upstream || undefined, + }) + } + } catch { + // No branches yet + } + + // Get remote branches + try { + const remoteOutput = await runGitCommand(cwd, "branch -r --format='%(refname:short)'") + for (const line of remoteOutput.split("\n")) { + if (!line.trim()) continue + const name = line.replace(/'/g, "").trim() + // Skip HEAD references + if (name.includes("/HEAD")) continue + branches.push({ + name, + current: false, + remote: true, + }) + } + } catch { + // No remote branches + } + + return { branches, current } +} + +export function registerGitRoutes(app: FastifyInstance, deps: GitRoutesDeps) { + const { workspaceManager } = deps + + // Helper to get workspace path + const getWorkspacePath = (id: string): string | null => { + const workspace = workspaceManager.get(id) + return workspace?.path ?? null + } + + // GET /api/workspaces/:id/git/status + app.get<{ Params: { id: string } }>("/api/workspaces/:id/git/status", async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + if (!(await isGitRepository(workspacePath))) { + return reply.status(400).send({ error: "Not a git repository" }) + } + + try { + const status = await getGitStatus(workspacePath) + return status + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to get git status" + return reply.status(500).send({ error: message }) + } + }) + + // GET /api/workspaces/:id/git/branches + app.get<{ Params: { id: string } }>("/api/workspaces/:id/git/branches", async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + if (!(await isGitRepository(workspacePath))) { + return reply.status(400).send({ error: "Not a git repository" }) + } + + try { + const branches = await getBranches(workspacePath) + return branches + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to get branches" + return reply.status(500).send({ error: message }) + } + }) + + // POST /api/workspaces/:id/git/checkout + app.post<{ Params: { id: string }; Body: GitCheckoutRequest }>( + "/api/workspaces/:id/git/checkout", + async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + if (!(await isGitRepository(workspacePath))) { + return reply.status(400).send({ error: "Not a git repository" }) + } + + const { branch, create } = request.body + if (!branch) { + return reply.status(400).send({ error: "Branch name is required" }) + } + + try { + const args = create ? `checkout -b ${branch}` : `checkout ${branch}` + await runGitCommand(workspacePath, args) + return { success: true, branch } + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to checkout branch" + return reply.status(500).send({ error: message }) + } + }, + ) + + // GET /api/workspaces/:id/git/diff + app.get<{ Params: { id: string }; Querystring: { path?: string; staged?: string } }>( + "/api/workspaces/:id/git/diff", + async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + if (!(await isGitRepository(workspacePath))) { + return reply.status(400).send({ error: "Not a git repository" }) + } + + const filePath = request.query.path + const staged = request.query.staged === "true" + + try { + let args = staged ? "diff --cached" : "diff" + if (filePath) { + args += ` -- ${filePath}` + } + + const diff = await runGitCommand(workspacePath, args) + + // Check if file is binary + const isBinary = diff.includes("Binary files") || diff.includes("GIT binary patch") + + const response: GitDiffResponse = { + path: filePath || "", + diff, + isBinary, + } + return response + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to get diff" + return reply.status(500).send({ error: message }) + } + }, + ) + + // GET /api/workspaces/:id/git/file-content + app.get<{ Params: { id: string }; Querystring: { path: string } }>( + "/api/workspaces/:id/git/file-content", + async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + const filePath = request.query.path + if (!filePath) { + return reply.status(400).send({ error: "File path is required" }) + } + + try { + const fullPath = path.join(workspacePath, filePath) + // Security check: ensure the path is within workspace + const normalizedPath = path.normalize(fullPath) + const normalizedWorkspace = path.normalize(workspacePath) + if (!normalizedPath.startsWith(normalizedWorkspace)) { + return reply.status(403).send({ error: "Access denied" }) + } + + // Check if file is binary by extension first (fast path) + if (isBinaryFile(filePath)) { + return reply.status(400).send({ + error: "Cannot preview binary files", + message: "Binary files (images, executables, archives, etc.) cannot be previewed. Please use an external viewer." + }) + } + + // Fallback: check file content for binary patterns + // This catches files without extensions or with uncommon extensions + if (await isBinaryContent(fullPath)) { + return reply.status(400).send({ + error: "Cannot preview binary files", + message: "Binary files (images, executables, archives, etc.) cannot be previewed. Please use an external viewer." + }) + } + + const content = await fs.readFile(fullPath, "utf-8") + return { path: filePath, content } + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to read file" + return reply.status(500).send({ error: message }) + } + }, + ) + + // GET /api/workspaces/:id/git/file-original + // Gets the original version of a file (staged for unstaged changes, HEAD for staged changes) + app.get<{ Params: { id: string }; Querystring: { path: string; staged?: string } }>( + "/api/workspaces/:id/git/file-original", + async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + if (!(await isGitRepository(workspacePath))) { + return reply.status(400).send({ error: "Not a git repository" }) + } + + const filePath = request.query.path + if (!filePath) { + return reply.status(400).send({ error: "File path is required" }) + } + + const staged = request.query.staged === "true" + + try { + // For staged changes, get HEAD version + // For unstaged changes, get staged version (if staged) or HEAD version + let content: string + try { + if (staged) { + // Get HEAD version for staged changes + content = await runGitCommand(workspacePath, `show HEAD:"${filePath}"`) + } else { + // Try to get staged version first + try { + content = await runGitCommand(workspacePath, `show :"${filePath}"`) + } catch { + // If no staged version, get HEAD version + content = await runGitCommand(workspacePath, `show HEAD:"${filePath}"`) + } + } + } catch { + // File might be new (not in HEAD or staged), return empty string + content = "" + } + + return { path: filePath, content } + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to get original file content" + return reply.status(500).send({ error: message }) + } + }, + ) + + // POST /api/workspaces/:id/git/stage + app.post<{ Params: { id: string }; Body: GitStageRequest }>( + "/api/workspaces/:id/git/stage", + async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + if (!(await isGitRepository(workspacePath))) { + return reply.status(400).send({ error: "Not a git repository" }) + } + + const { paths } = request.body + if (!paths || paths.length === 0) { + return reply.status(400).send({ error: "Paths are required" }) + } + + try { + const quotedPaths = paths.map((p) => `"${p}"`).join(" ") + await runGitCommand(workspacePath, `add ${quotedPaths}`) + return { success: true } + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to stage files" + return reply.status(500).send({ error: message }) + } + }, + ) + + // POST /api/workspaces/:id/git/unstage + app.post<{ Params: { id: string }; Body: GitStageRequest }>( + "/api/workspaces/:id/git/unstage", + async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + if (!(await isGitRepository(workspacePath))) { + return reply.status(400).send({ error: "Not a git repository" }) + } + + const { paths } = request.body + if (!paths || paths.length === 0) { + return reply.status(400).send({ error: "Paths are required" }) + } + + try { + const quotedPaths = paths.map((p) => `"${p}"`).join(" ") + await runGitCommand(workspacePath, `reset HEAD -- ${quotedPaths}`) + return { success: true } + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to unstage files" + return reply.status(500).send({ error: message }) + } + }, + ) + + // POST /api/workspaces/:id/git/discard + app.post<{ Params: { id: string }; Body: GitStageRequest }>( + "/api/workspaces/:id/git/discard", + async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + if (!(await isGitRepository(workspacePath))) { + return reply.status(400).send({ error: "Not a git repository" }) + } + + const { paths } = request.body + if (!paths || paths.length === 0) { + return reply.status(400).send({ error: "Paths are required" }) + } + + try { + const quotedPaths = paths.map((p) => `"${p}"`).join(" ") + await runGitCommand(workspacePath, `checkout -- ${quotedPaths}`) + return { success: true } + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to discard changes" + return reply.status(500).send({ error: message }) + } + }, + ) + + // POST /api/workspaces/:id/git/delete + app.post<{ Params: { id: string }; Body: GitStageRequest }>( + "/api/workspaces/:id/git/delete", + async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + const { paths } = request.body + if (!paths || paths.length === 0) { + return reply.status(400).send({ error: "Paths are required" }) + } + + try { + for (const fileOrDir of paths) { + const fullPath = path.join(workspacePath, fileOrDir) + const stats = await fs.stat(fullPath) + + if (stats.isDirectory()) { + await fs.rm(fullPath, { recursive: true, force: true }) + } else { + await fs.unlink(fullPath) + } + } + return { success: true } + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to delete files" + return reply.status(500).send({ error: message }) + } + }, + ) + + // POST /api/workspaces/:id/git/commit + app.post<{ Params: { id: string }; Body: GitCommitRequest }>( + "/api/workspaces/:id/git/commit", + async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + if (!(await isGitRepository(workspacePath))) { + return reply.status(400).send({ error: "Not a git repository" }) + } + + const { message } = request.body + if (!message || !message.trim()) { + return reply.status(400).send({ error: "Commit message is required" }) + } + + try { + // Escape quotes in message + const escapedMessage = message.replace(/"/g, '\\"') + await runGitCommand(workspacePath, `commit -m "${escapedMessage}"`) + + // Get the commit hash + const hash = await runGitCommand(workspacePath, "rev-parse --short HEAD") + + const response: GitCommitResponse = { + hash, + message: message.trim(), + } + return response + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to commit" + return reply.status(500).send({ error: message }) + } + }, + ) + + // POST /api/workspaces/:id/git/push + app.post<{ Params: { id: string }; Body: { publish?: boolean } }>("/api/workspaces/:id/git/push", async (request, reply) => { + const workspacePath = getWorkspacePath(request.params.id) + if (!workspacePath) { + return reply.status(404).send({ error: "Workspace not found" }) + } + + if (!(await isGitRepository(workspacePath))) { + return reply.status(400).send({ error: "Not a git repository" }) + } + + const { publish } = request.body || {} + + try { + if (publish) { + // Get current branch + const currentBranch = await runGitCommand(workspacePath, "branch --show-current") + if (!currentBranch) { + throw new Error("Could not determine current branch") + } + await runGitCommand(workspacePath, `push -u origin ${currentBranch}`) + } else { + await runGitCommand(workspacePath, "push") + } + const response: GitPushResponse = { + success: true, + pushed: true, + message: "Pushed successfully", + } + return response + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to push" + const response: GitPushResponse = { + success: false, + pushed: false, + message, + } + return reply.status(500).send(response) + } + }) +} diff --git a/packages/server/src/server/routes/meta.ts b/packages/server/src/server/routes/meta.ts index 40782181..ef01c4cb 100644 --- a/packages/server/src/server/routes/meta.ts +++ b/packages/server/src/server/routes/meta.ts @@ -1,6 +1,6 @@ import { FastifyInstance } from "fastify" -import os from "os" -import { NetworkAddress, ServerMeta } from "../../api-types" +import { ServerMeta } from "../../api-types" +import { resolveNetworkAddresses } from "../network-addresses" interface RouteDeps { serverMeta: ServerMeta @@ -11,23 +11,25 @@ export function registerMetaRoutes(app: FastifyInstance, deps: RouteDeps) { } function buildMetaResponse(meta: ServerMeta): ServerMeta { - const port = resolvePort(meta) - const addresses = port > 0 ? resolveAddresses(port, meta.host) : [] + const localPort = resolveLocalPort(meta) + const remote = resolveRemote(meta) + const addresses = remote && remote.port > 0 ? resolveNetworkAddresses({ host: meta.host, protocol: remote.protocol, port: remote.port }) : [] return { ...meta, - port, + localPort, + remotePort: remote?.port, listeningMode: meta.host === "0.0.0.0" || !isLoopbackHost(meta.host) ? "all" : "local", addresses, } } -function resolvePort(meta: ServerMeta): number { - if (Number.isInteger(meta.port) && meta.port > 0) { - return meta.port +function resolveLocalPort(meta: ServerMeta): number { + if (Number.isInteger(meta.localPort) && meta.localPort > 0) { + return meta.localPort } try { - const parsed = new URL(meta.httpBaseUrl) + const parsed = new URL(meta.localUrl) const port = Number(parsed.port) return Number.isInteger(port) && port > 0 ? port : 0 } catch { @@ -35,74 +37,22 @@ function resolvePort(meta: ServerMeta): number { } } -function isLoopbackHost(host: string): boolean { - return host === "127.0.0.1" || host === "::1" || host.startsWith("127.") -} - -function resolveAddresses(port: number, host: string): NetworkAddress[] { - const interfaces = os.networkInterfaces() - const seen = new Set() - const results: NetworkAddress[] = [] - - const addAddress = (ip: string, scope: NetworkAddress["scope"]) => { - if (!ip || ip === "0.0.0.0") return - const key = `ipv4-${ip}` - if (seen.has(key)) return - seen.add(key) - results.push({ ip, family: "ipv4", scope, url: `http://${ip}:${port}` }) - } - - const normalizeFamily = (value: string | number) => { - if (typeof value === "string") { - const lowered = value.toLowerCase() - if (lowered === "ipv4") { - return "ipv4" as const - } - } - if (value === 4) return "ipv4" as const +function resolveRemote(meta: ServerMeta): { protocol: "http" | "https"; port: number } | null { + if (!meta.remoteUrl) { return null } - - if (host === "0.0.0.0") { - // Enumerate system interfaces (IPv4 only) - for (const entries of Object.values(interfaces)) { - if (!entries) continue - for (const entry of entries) { - const family = normalizeFamily(entry.family) - if (!family) continue - if (!entry.address || entry.address === "0.0.0.0") continue - const scope: NetworkAddress["scope"] = entry.internal ? "loopback" : "external" - addAddress(entry.address, scope) - } - } - } - - // Always include loopback address - addAddress("127.0.0.1", "loopback") - - // Include explicitly configured host if it was IPv4 - if (isIPv4Address(host) && host !== "0.0.0.0") { - const isLoopback = host.startsWith("127.") - addAddress(host, isLoopback ? "loopback" : "external") + try { + const parsed = new URL(meta.remoteUrl) + const protocol = parsed.protocol === "https:" ? "https" : "http" + const port = Number(parsed.port) + return { protocol, port: Number.isInteger(port) && port > 0 ? port : 0 } + } catch { + return null } - - const scopeWeight: Record = { external: 0, internal: 1, loopback: 2 } - - return results.sort((a, b) => { - const scopeDelta = scopeWeight[a.scope] - scopeWeight[b.scope] - if (scopeDelta !== 0) return scopeDelta - return a.ip.localeCompare(b.ip) - }) } -function isIPv4Address(value: string | undefined): value is string { - if (!value) return false - const parts = value.split(".") - if (parts.length !== 4) return false - return parts.every((part) => { - if (part.length === 0 || part.length > 3) return false - if (!/^[0-9]+$/.test(part)) return false - const num = Number(part) - return Number.isInteger(num) && num >= 0 && num <= 255 - }) +function isLoopbackHost(host: string): boolean { + return host === "127.0.0.1" || host === "::1" || host.startsWith("127.") } + +// NetworkAddress shape is resolved in ../network-addresses diff --git a/packages/server/src/server/routes/worktrees.ts b/packages/server/src/server/routes/worktrees.ts new file mode 100644 index 00000000..9e76319b --- /dev/null +++ b/packages/server/src/server/routes/worktrees.ts @@ -0,0 +1,195 @@ +import type { FastifyInstance, FastifyReply } from "fastify" +import { z } from "zod" +import { WorkspaceManager } from "../../workspaces/manager" +import { + resolveRepoRoot, + listWorktrees, + isValidWorktreeSlug, + createManagedWorktree, + removeWorktree, +} from "../../workspaces/git-worktrees" +import type { WorktreeListResponse, WorktreeMap } from "../../api-types" +import { ensureCodenomadGitExclude, readWorktreeMap, writeWorktreeMap } from "../../workspaces/worktree-map" + +interface RouteDeps { + workspaceManager: WorkspaceManager +} + +const WorktreeMapSchema = z.object({ + version: z.literal(1), + defaultWorktreeSlug: z.string().min(1).default("root"), + parentSessionWorktreeSlug: z.record(z.string(), z.string()).default({}), +}) + +const WorktreeCreateSchema = z.object({ + slug: z.string().trim().min(1), + branch: z.string().trim().min(1).optional(), +}) + +export function registerWorktreeRoutes(app: FastifyInstance, deps: RouteDeps) { + app.get<{ Params: { id: string } }>("/api/workspaces/:id/worktrees", async (request, reply) => { + const workspace = deps.workspaceManager.get(request.params.id) + if (!workspace) { + reply.code(404) + return { error: "Workspace not found" } + } + + const { repoRoot, isGitRepo } = await resolveRepoRoot(workspace.path, request.log) + const worktrees = await listWorktrees({ repoRoot, workspaceFolder: workspace.path, logger: request.log }) + const response: WorktreeListResponse = { worktrees, isGitRepo } + return response + }) + + app.post<{ Params: { id: string } }>("/api/workspaces/:id/worktrees", async (request, reply) => { + const workspace = deps.workspaceManager.get(request.params.id) + if (!workspace) { + reply.code(404) + return { error: "Workspace not found" } + } + + try { + const body = WorktreeCreateSchema.parse(request.body ?? {}) + const slug = body.slug + if (!isValidWorktreeSlug(slug) || slug === "root") { + reply.code(400) + return { error: "Invalid worktree slug" } + } + if (body.branch) { + if (!isValidWorktreeSlug(body.branch) || body.branch === "root") { + reply.code(400) + return { error: "Invalid worktree branch" } + } + if (body.branch !== slug) { + reply.code(400) + return { error: "Branch must match slug" } + } + } + + const { repoRoot, isGitRepo } = await resolveRepoRoot(workspace.path, request.log) + if (!isGitRepo) { + reply.code(400) + return { error: "Workspace is not a Git repository" } + } + + await ensureCodenomadGitExclude(workspace.path, request.log).catch(() => undefined) + + const created = await createManagedWorktree({ + repoRoot, + workspaceFolder: workspace.path, + slug, + logger: request.log, + }) + + reply.code(201) + return created + } catch (error) { + return handleError(error, reply) + } + }) + + app.delete<{ Params: { id: string; slug: string }; Querystring: { force?: string } }>( + "/api/workspaces/:id/worktrees/:slug", + async (request, reply) => { + const workspace = deps.workspaceManager.get(request.params.id) + if (!workspace) { + reply.code(404) + return { error: "Workspace not found" } + } + + const slug = (request.params.slug ?? "").trim() + if (!isValidWorktreeSlug(slug) || slug === "root") { + reply.code(400) + return { error: "Invalid worktree slug" } + } + + const { repoRoot, isGitRepo } = await resolveRepoRoot(workspace.path, request.log) + if (!isGitRepo) { + reply.code(400) + return { error: "Workspace is not a Git repository" } + } + + const force = (request.query?.force ?? "").toString().toLowerCase() === "true" + + try { + const worktrees = await listWorktrees({ repoRoot, workspaceFolder: workspace.path, logger: request.log }) + const match = worktrees.find((wt) => wt.slug === slug) + if (!match || match.kind === "root") { + reply.code(404) + return { error: "Worktree not found" } + } + + await removeWorktree({ workspaceFolder: workspace.path, directory: match.directory, force, logger: request.log }) + + // Best-effort: prune any mappings that point at the deleted worktree. + const current = await readWorktreeMap(workspace.path, request.log) + let changed = false + const nextMapping: Record = { ...(current.parentSessionWorktreeSlug ?? {}) } + for (const [sessionId, mapped] of Object.entries(nextMapping)) { + if (mapped === slug) { + delete nextMapping[sessionId] + changed = true + } + } + const nextDefault = current.defaultWorktreeSlug === slug ? "root" : current.defaultWorktreeSlug + if (nextDefault !== current.defaultWorktreeSlug) { + changed = true + } + if (changed) { + await writeWorktreeMap( + workspace.path, + { + version: 1, + defaultWorktreeSlug: nextDefault, + parentSessionWorktreeSlug: nextMapping, + }, + request.log, + ) + } + + reply.code(204) + } catch (error) { + return handleError(error, reply) + } + }, + ) + + app.get<{ Params: { id: string } }>("/api/workspaces/:id/worktrees/map", async (request, reply) => { + const workspace = deps.workspaceManager.get(request.params.id) + if (!workspace) { + reply.code(404) + return { error: "Workspace not found" } + } + return await readWorktreeMap(workspace.path, request.log) + }) + + app.put<{ Params: { id: string } }>("/api/workspaces/:id/worktrees/map", async (request, reply) => { + const workspace = deps.workspaceManager.get(request.params.id) + if (!workspace) { + reply.code(404) + return { error: "Workspace not found" } + } + + try { + const parsed = WorktreeMapSchema.parse(request.body ?? {}) as WorktreeMap + if (!isValidWorktreeSlug(parsed.defaultWorktreeSlug)) { + reply.code(400) + return { error: "Invalid defaultWorktreeSlug" } + } + for (const slug of Object.values(parsed.parentSessionWorktreeSlug ?? {})) { + if (!isValidWorktreeSlug(slug)) { + reply.code(400) + return { error: "Invalid worktree slug in mapping" } + } + } + await writeWorktreeMap(workspace.path, parsed, request.log) + reply.code(204) + } catch (error) { + return handleError(error, reply) + } + }) +} + +function handleError(error: unknown, reply: FastifyReply) { + reply.code(400) + return { error: error instanceof Error ? error.message : "Unable to fulfill request" } +} diff --git a/packages/server/src/server/tls.ts b/packages/server/src/server/tls.ts new file mode 100644 index 00000000..3a8661b0 --- /dev/null +++ b/packages/server/src/server/tls.ts @@ -0,0 +1,283 @@ +import crypto from "crypto" +import fs from "fs" +import path from "path" +import { createRequire } from "module" +import type { Logger } from "../logger" + +const require = createRequire(import.meta.url) + +type Forge = typeof import("node-forge") + +function loadForge(): Forge { + // node-forge is CJS in many installs; require keeps this compatible with our ESM output. + return require("node-forge") as Forge +} + +export interface ResolvedHttpsOptions { + httpsOptions: { key: string | Buffer; cert: string | Buffer; ca?: string | Buffer } + /** Path to CA certificate suitable for NODE_EXTRA_CA_CERTS. */ + caCertPath?: string + mode: "provided" | "generated" +} + +export interface ResolveHttpsOptionsArgs { + enabled: boolean + configDir: string + host: string + tlsKeyPath?: string + tlsCertPath?: string + tlsCaPath?: string + tlsSANs?: string + logger: Logger +} + +const LEAF_VALIDITY_DAYS = 30 +const ROTATE_IF_EXPIRES_WITHIN_DAYS = 3 + +const CA_VALIDITY_DAYS = 365 + +export function resolveHttpsOptions(args: ResolveHttpsOptionsArgs): ResolvedHttpsOptions | null { + if (!args.enabled) { + return null + } + + const hasProvided = Boolean(args.tlsKeyPath && args.tlsCertPath) + if (hasProvided) { + const key = fs.readFileSync(args.tlsKeyPath!, "utf-8") + const cert = fs.readFileSync(args.tlsCertPath!, "utf-8") + const ca = args.tlsCaPath ? fs.readFileSync(args.tlsCaPath, "utf-8") : undefined + return { + httpsOptions: { key, cert, ca }, + caCertPath: args.tlsCaPath, + mode: "provided", + } + } + + return ensureGeneratedTls(args) +} + +function ensureGeneratedTls(args: ResolveHttpsOptionsArgs): ResolvedHttpsOptions { + const tlsDir = path.join(args.configDir, "tls") + const caKeyPath = path.join(tlsDir, "ca-key.pem") + const caCertPath = path.join(tlsDir, "ca-cert.pem") + const keyPath = path.join(tlsDir, "server-key.pem") + const certPath = path.join(tlsDir, "server-cert.pem") + + fs.mkdirSync(tlsDir, { recursive: true }) + + const shouldRotateLeaf = () => { + try { + if (!fs.existsSync(certPath)) return true + const pem = fs.readFileSync(certPath, "utf-8") + const x509 = new crypto.X509Certificate(pem) + const validToMs = Date.parse(x509.validTo) + if (!Number.isFinite(validToMs)) return true + const rotateAt = validToMs - ROTATE_IF_EXPIRES_WITHIN_DAYS * 24 * 60 * 60 * 1000 + return Date.now() >= rotateAt + } catch { + return true + } + } + + const shouldRotateCa = () => { + try { + if (!fs.existsSync(caCertPath)) return true + const pem = fs.readFileSync(caCertPath, "utf-8") + const x509 = new crypto.X509Certificate(pem) + const validToMs = Date.parse(x509.validTo) + if (!Number.isFinite(validToMs)) return true + // CA rotates only when expired. + return Date.now() >= validToMs + } catch { + return true + } + } + + if (shouldRotateCa() || !fs.existsSync(caKeyPath)) { + const { caKeyPem, caCertPem } = generateCaCertificate() + writePemFile(caKeyPath, caKeyPem, 0o600) + writePemFile(caCertPath, caCertPem, 0o644) + args.logger.info({ caCertPath }, "Generated self-signed CodeNomad CA certificate") + } + + if (shouldRotateLeaf() || !fs.existsSync(keyPath)) { + const caKeyPem = fs.readFileSync(caKeyPath, "utf-8") + const caCertPem = fs.readFileSync(caCertPath, "utf-8") + + const { keyPem, certPem } = generateServerCertificate({ + host: args.host, + tlsSANs: args.tlsSANs, + caKeyPem, + caCertPem, + }) + + writePemFile(keyPath, keyPem, 0o600) + writePemFile(certPath, certPem, 0o644) + args.logger.info({ certPath }, "Generated CodeNomad HTTPS certificate") + } + + const key = fs.readFileSync(keyPath, "utf-8") + const cert = fs.readFileSync(certPath, "utf-8") + const ca = fs.readFileSync(caCertPath, "utf-8") + + // Present the CA as part of the chain. + const chainedCert = `${cert.trim()}\n${ca.trim()}\n` + + return { + httpsOptions: { + key, + cert: chainedCert, + }, + caCertPath, + mode: "generated", + } +} + +function writePemFile(filePath: string, content: string, mode: number) { + fs.writeFileSync(filePath, content, { encoding: "utf-8", mode }) + try { + fs.chmodSync(filePath, mode) + } catch { + // best effort on platforms that ignore chmod + } +} + +function generateCaCertificate(): { caKeyPem: string; caCertPem: string } { + const forge = loadForge() + + const keys = forge.pki.rsa.generateKeyPair(2048) + const cert = forge.pki.createCertificate() + cert.publicKey = keys.publicKey + cert.serialNumber = crypto.randomBytes(16).toString("hex") + + const now = new Date() + const notBefore = new Date(now.getTime() - 60_000) + const notAfter = new Date(now.getTime() + CA_VALIDITY_DAYS * 24 * 60 * 60 * 1000) + cert.validity.notBefore = notBefore + cert.validity.notAfter = notAfter + + const attrs = [{ name: "commonName", value: "CodeNomad Local CA" }] + cert.setSubject(attrs) + cert.setIssuer(attrs) + + cert.setExtensions([ + { name: "basicConstraints", cA: true }, + { name: "keyUsage", keyCertSign: true, cRLSign: true, digitalSignature: true }, + { name: "subjectKeyIdentifier" }, + ]) + + cert.sign(keys.privateKey, forge.md.sha256.create()) + + return { + caKeyPem: forge.pki.privateKeyToPem(keys.privateKey), + caCertPem: forge.pki.certificateToPem(cert), + } +} + +function generateServerCertificate(args: { + host: string + tlsSANs?: string + caKeyPem: string + caCertPem: string +}): { keyPem: string; certPem: string } { + const forge = loadForge() + + const caKey = forge.pki.privateKeyFromPem(args.caKeyPem) + const caCert = forge.pki.certificateFromPem(args.caCertPem) + + const keys = forge.pki.rsa.generateKeyPair(2048) + const cert = forge.pki.createCertificate() + cert.publicKey = keys.publicKey + cert.serialNumber = crypto.randomBytes(16).toString("hex") + + const now = new Date() + const notBefore = new Date(now.getTime() - 60_000) + const notAfter = new Date(now.getTime() + LEAF_VALIDITY_DAYS * 24 * 60 * 60 * 1000) + cert.validity.notBefore = notBefore + cert.validity.notAfter = notAfter + + const commonName = pickCommonName(args.host) + cert.setSubject([{ name: "commonName", value: commonName }]) + cert.setIssuer(caCert.subject.attributes) + + const san = buildSubjectAltNames(args.host, args.tlsSANs) + + cert.setExtensions([ + { name: "basicConstraints", cA: false }, + { name: "keyUsage", digitalSignature: true, keyEncipherment: true }, + { name: "extKeyUsage", serverAuth: true }, + { name: "subjectAltName", altNames: san }, + { name: "subjectKeyIdentifier" }, + ]) + + cert.sign(caKey, forge.md.sha256.create()) + + return { + keyPem: forge.pki.privateKeyToPem(keys.privateKey), + certPem: forge.pki.certificateToPem(cert), + } +} + +function pickCommonName(host: string): string { + if (!host || host === "0.0.0.0") { + return "localhost" + } + if (host === "127.0.0.1") { + return "localhost" + } + return host +} + +function buildSubjectAltNames(host: string, tlsSANs?: string): Array<{ type: number; value?: string; ip?: string }> { + const dns = new Set() + const ips = new Set() + + dns.add("localhost") + ips.add("127.0.0.1") + + if (host && host !== "0.0.0.0") { + if (isIPv4(host)) { + ips.add(host) + } else { + dns.add(host) + } + } + + for (const token of splitList(tlsSANs)) { + if (isIPv4(token)) { + ips.add(token) + } else if (token) { + dns.add(token) + } + } + + const altNames: Array<{ type: number; value?: string; ip?: string }> = [] + + // 2 = DNS, 7 = IP + for (const name of Array.from(dns)) { + altNames.push({ type: 2, value: name }) + } + for (const ip of Array.from(ips)) { + altNames.push({ type: 7, ip }) + } + + return altNames +} + +function splitList(input: string | undefined): string[] { + if (!input) return [] + return input + .split(",") + .map((part) => part.trim()) + .filter(Boolean) +} + +function isIPv4(value: string): boolean { + const parts = value.split(".") + if (parts.length !== 4) return false + return parts.every((part) => { + if (!/^[0-9]+$/.test(part)) return false + const num = Number(part) + return Number.isInteger(num) && num >= 0 && num <= 255 + }) +} diff --git a/packages/server/src/ui/remote-ui.ts b/packages/server/src/ui/remote-ui.ts index 1aff87df..242d433d 100644 --- a/packages/server/src/ui/remote-ui.ts +++ b/packages/server/src/ui/remote-ui.ts @@ -39,6 +39,7 @@ export interface RemoteUiOptions { uiDevServerUrl?: string manifestUrl?: string configDir?: string + packaged?: boolean logger: Logger } @@ -48,6 +49,16 @@ const MANIFEST_TIMEOUT_MS = 5_000 const ZIP_TIMEOUT_MS = 30_000 export async function resolveUi(options: RemoteUiOptions): Promise { + if (options.packaged) { + const resolved = await resolveStaticUiDir(options.bundledUiDir) + return { + uiStaticDir: resolved ?? options.bundledUiDir, + source: resolved ? "bundled" : "missing", + uiVersion: await readUiVersion(resolved ?? options.bundledUiDir), + supported: true, + } + } + const manifestUrl = options.manifestUrl ?? DEFAULT_MANIFEST_URL if (options.uiDevServerUrl) { diff --git a/packages/server/src/workspaces/git-worktrees.ts b/packages/server/src/workspaces/git-worktrees.ts new file mode 100644 index 00000000..f9b5998e --- /dev/null +++ b/packages/server/src/workspaces/git-worktrees.ts @@ -0,0 +1,241 @@ +import path from "path" +import { spawn } from "child_process" +import type { WorktreeDescriptor } from "../api-types" +import { promises as fsp } from "fs" + +export interface LogLike { + debug?: (obj: any, msg?: string) => void + warn?: (obj: any, msg?: string) => void +} + +type GitResult = { ok: true; stdout: string } | { ok: false; error: Error; stdout?: string; stderr?: string } + +function runGit(args: string[], cwd: string): Promise { + return new Promise((resolve) => { + const child = spawn("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"] }) + let stdout = "" + let stderr = "" + + child.stdout?.on("data", (chunk) => { + stdout += chunk.toString() + }) + child.stderr?.on("data", (chunk) => { + stderr += chunk.toString() + }) + child.once("error", (error) => { + resolve({ ok: false, error, stdout, stderr }) + }) + child.once("close", (code) => { + if (code === 0) { + resolve({ ok: true, stdout }) + } else { + const error = new Error(stderr.trim() || `git ${args.join(" ")} failed with code ${code}`) + resolve({ ok: false, error, stdout, stderr }) + } + }) + }) +} + +export async function resolveRepoRoot(folder: string, logger?: LogLike): Promise<{ repoRoot: string; isGitRepo: boolean }> { + const result = await runGit(["rev-parse", "--show-toplevel"], folder) + if (!result.ok) { + logger?.debug?.({ folder, err: result.error }, "Folder is not a Git repository; using workspace folder as root") + return { repoRoot: folder, isGitRepo: false } + } + const repoRoot = result.stdout.trim() + if (!repoRoot) { + return { repoRoot: folder, isGitRepo: false } + } + return { repoRoot, isGitRepo: true } +} + +function parseWorktreePorcelain(output: string): Array<{ worktree: string; branch?: string; head?: string; detached?: boolean }> { + const records: Array<{ worktree: string; branch?: string; head?: string; detached?: boolean }> = [] + const lines = output.split(/\r?\n/) + let current: { worktree?: string; branch?: string; head?: string; detached?: boolean } = {} + + const flush = () => { + if (current.worktree) { + records.push({ worktree: current.worktree, branch: current.branch }) + } + current = {} + } + + for (const line of lines) { + const trimmed = line.trim() + if (!trimmed) { + flush() + continue + } + const [key, ...rest] = trimmed.split(" ") + const value = rest.join(" ").trim() + if (key === "worktree") { + current.worktree = value + } else if (key === "branch") { + // branch is like refs/heads/foo + current.branch = value.replace(/^refs\/heads\//, "") + } else if (key === "HEAD") { + current.head = value + } else if (key === "detached") { + current.detached = true + } + } + flush() + return records +} + +export async function listWorktrees(params: { + repoRoot: string + workspaceFolder: string + logger?: LogLike +}): Promise { + const { repoRoot, workspaceFolder, logger } = params + const rootDescriptor: WorktreeDescriptor = { slug: "root", directory: repoRoot, kind: "root" } + + const result = await runGit(["worktree", "list", "--porcelain"], workspaceFolder) + if (!result.ok) { + logger?.debug?.({ repoRoot, err: result.error }, "Failed to list git worktrees; returning root only") + return [rootDescriptor] + } + + const records = parseWorktreePorcelain(result.stdout) + + const worktrees: WorktreeDescriptor[] = [rootDescriptor] + const seen = new Set(["root"]) + + const normalizeSlug = (record: { branch?: string; head?: string; detached?: boolean; worktree: string }): string => { + const branch = (record.branch ?? "").trim() + if (branch) { + return branch + } + const head = (record.head ?? "").trim() + if (head && /^[0-9a-f]{7,40}$/i.test(head)) { + return `detached-${head.slice(0, 7)}` + } + // Fallback: stable-ish identifier derived from directory basename. + const base = path.basename(record.worktree || "") + return base ? `worktree-${base}` : "worktree" + } + + + for (const record of records) { + const abs = record.worktree + if (!abs || typeof abs !== "string") continue + + // Skip the root record (we always expose it as slug="root"). + if (path.resolve(abs) === path.resolve(repoRoot)) { + continue + } + + const slug = normalizeSlug(record) + if (!slug || slug === "root") { + continue + } + if (seen.has(slug)) { + continue + } + seen.add(slug) + worktrees.push({ slug, directory: abs, kind: "worktree", branch: record.branch }) + } + + return worktrees +} + +export function isValidWorktreeSlug(slug: string): boolean { + if (!slug) return false + const trimmed = slug.trim() + if (!trimmed) return false + if (trimmed.length > 200) return false + // Disallow control characters; allow branch-like slugs including '/'. + if (/[\x00-\x1F\x7F]/.test(trimmed)) return false + return true +} + +export async function createManagedWorktree(params: { + repoRoot: string + workspaceFolder: string + slug: string + logger?: LogLike +}): Promise<{ slug: string; directory: string; branch?: string }> { + const { repoRoot, workspaceFolder, logger } = params + const branch = params.slug.trim() + + if (!branch || branch === "root" || !isValidWorktreeSlug(branch)) { + throw new Error("Invalid worktree slug") + } + + const sanitizeDirName = (input: string): string => { + const normalized = input + .trim() + .replace(/[\\/]+/g, "-") + .replace(/\s+/g, "-") + .replace(/[^a-zA-Z0-9_.-]+/g, "-") + .replace(/-{2,}/g, "-") + .replace(/^-+|-+$/g, "") + return normalized || "worktree" + } + + const worktreesDir = path.join(repoRoot, ".codenomad", "worktrees") + const targetDir = path.join(worktreesDir, sanitizeDirName(branch)) + await fsp.mkdir(worktreesDir, { recursive: true }) + + try { + const stat = await fsp.stat(targetDir) + if (stat.isDirectory()) { + throw new Error("Worktree directory already exists") + } + } catch (error) { + const code = (error as NodeJS.ErrnoException).code + if (code !== "ENOENT") { + throw error + } + } + + logger?.debug?.({ slug: branch, branch, targetDir }, "Creating managed git worktree") + + // Prefer creating a new branch from HEAD. + const first = await runGit(["worktree", "add", "-b", branch, targetDir, "HEAD"], workspaceFolder) + if (first.ok) { + return { slug: branch, directory: targetDir, branch } + } + + const message = first.stderr?.toLowerCase() ?? first.error.message.toLowerCase() + if (message.includes("already exists")) { + // If the branch already exists, add worktree for that branch. + const second = await runGit(["worktree", "add", targetDir, branch], workspaceFolder) + if (second.ok) { + return { slug: branch, directory: targetDir, branch } + } + throw second.error + } + + throw first.error +} + +export async function removeWorktree(params: { + workspaceFolder: string + directory: string + force?: boolean + logger?: LogLike +}): Promise { + const { workspaceFolder, logger } = params + const directory = (params.directory ?? "").trim() + if (!directory) { + throw new Error("Invalid worktree directory") + } + logger?.debug?.({ directory, force: Boolean(params.force) }, "Removing git worktree") + + const args = ["worktree", "remove"] + if (params.force) { + args.push("--force") + } + args.push(directory) + + const result = await runGit(args, workspaceFolder) + if (!result.ok) { + throw result.error + } + + // Best-effort cleanup of stale metadata. + await runGit(["worktree", "prune"], workspaceFolder).catch(() => undefined) +} diff --git a/packages/server/src/workspaces/instance-events.ts b/packages/server/src/workspaces/instance-events.ts index aeda2fc3..1876564e 100644 --- a/packages/server/src/workspaces/instance-events.ts +++ b/packages/server/src/workspaces/instance-events.ts @@ -20,8 +20,17 @@ interface ActiveStream { task: Promise } +interface SessionCacheEntry { + parentID: string | null + parentIdKnown: boolean + verified: boolean +} + export class InstanceEventBridge { private readonly streams = new Map() + private readonly sessionCache = new Map>() + private readonly sessionFetches = new Map>() + private readonly eventQueues = new Map>() constructor(private readonly options: InstanceEventBridgeOptions) { const bus = this.options.eventBus @@ -36,6 +45,10 @@ export class InstanceEventBridge { this.publishStatus(id, "disconnected") } this.streams.clear() + // Clean up session cache and event queues to prevent memory leaks + this.sessionCache.clear() + this.sessionFetches.clear() + this.eventQueues.clear() } private startStream(workspaceId: string) { @@ -68,6 +81,15 @@ export class InstanceEventBridge { } active.controller.abort() this.streams.delete(workspaceId) + // Clean up workspace-specific cache and queues to prevent memory leaks + this.sessionCache.delete(workspaceId) + // Clean up session fetches for this workspace + for (const [key] of this.sessionFetches) { + if (key.startsWith(`${workspaceId}:`)) { + this.sessionFetches.delete(key) + } + } + this.eventQueues.delete(workspaceId) this.publishStatus(workspaceId, "disconnected", reason) } @@ -95,7 +117,7 @@ export class InstanceEventBridge { } private async consumeStream(workspaceId: string, port: number, signal: AbortSignal) { - const url = `http://${INSTANCE_HOST}:${port}/event` + const url = `http://${INSTANCE_HOST}:${port}/global/event` const headers: Record = { Accept: "text/event-stream" } const authHeader = this.options.workspaceManager.getInstanceAuthorizationHeader(workspaceId) @@ -165,17 +187,160 @@ export class InstanceEventBridge { } try { - const event = JSON.parse(payload) as InstanceStreamEvent - this.options.logger.debug({ workspaceId, eventType: event.type }, "Instance SSE event received") + const parsed = JSON.parse(payload) as any + if (!parsed || typeof parsed !== "object") { + this.options.logger.warn({ workspaceId, chunk: payload }, "Dropped malformed instance event") + return + } + + // OpenCode SSE payload shapes vary across versions. + // Common variants: + // - { type, properties, ... } + // - { payload: { type, properties, ... }, directory: "/abs/path" } + // - { payload: { type, properties, ... } } + const base = parsed.payload && typeof parsed.payload === "object" ? parsed.payload : parsed + + const event: InstanceStreamEvent | null = base && typeof base === "object" ? ({ ...base } as any) : null + + // Attach directory when available (don't overwrite if already present). + if (event && !(event as any).directory && typeof (parsed as any).directory === "string") { + ;(event as any).directory = (parsed as any).directory + } + + if (!event || typeof (event as any).type !== "string") { + this.options.logger.warn({ workspaceId, chunk: payload }, "Dropped malformed instance event") + return + } + + this.options.logger.debug({ workspaceId, eventType: (event as any).type }, "Instance SSE event received") if (this.options.logger.isLevelEnabled("trace")) { this.options.logger.trace({ workspaceId, event }, "Instance SSE event payload") } - this.options.eventBus.publish({ type: "instance.event", instanceId: workspaceId, event }) + this.enqueueEvent(workspaceId, event) } catch (error) { this.options.logger.warn({ workspaceId, chunk: payload, err: error }, "Failed to parse instance SSE payload") } } + private enqueueEvent(workspaceId: string, event: InstanceStreamEvent) { + const previous = this.eventQueues.get(workspaceId) ?? Promise.resolve() + const next = previous + .then(() => this.handleInstanceEvent(workspaceId, event)) + .catch((error) => { + this.options.logger.warn({ workspaceId, err: error, eventType: event.type }, "Failed to handle instance event") + }) + this.eventQueues.set(workspaceId, next) + } + + private getSessionCache(workspaceId: string): Map { + const existing = this.sessionCache.get(workspaceId) + if (existing) return existing + const created = new Map() + this.sessionCache.set(workspaceId, created) + return created + } + + private mergeCachedParentId( + cache: Map, + sessionId: string, + parentID: string | null, + parentIdKnown: boolean, + verified: boolean, + ) { + const existing = cache.get(sessionId) + // If the incoming payload doesn't actually include parentID, treat it as "unknown" and + // avoid overwriting a previously-known value. + const nextKnown = parentIdKnown || existing?.parentIdKnown || false + const nextVerified = verified || existing?.verified || false + const nextParentID = parentIdKnown ? parentID : (existing?.parentID ?? parentID) + cache.set(sessionId, { parentID: nextParentID ?? null, parentIdKnown: nextKnown, verified: nextVerified }) + } + + private async handleInstanceEvent(workspaceId: string, event: InstanceStreamEvent) { + if (event.type === "session.updated") { + const info = (event as any)?.properties?.info + const sessionId = info?.id + if (typeof sessionId === "string") { + const hasParentIdField = info && typeof info === "object" && Object.prototype.hasOwnProperty.call(info, "parentID") + const parentID = typeof info?.parentID === "string" ? info.parentID : null + const verified = hasParentIdField && parentID !== null + const cache = this.getSessionCache(workspaceId) + this.mergeCachedParentId(cache, sessionId, parentID, hasParentIdField, verified) + } + this.options.eventBus.publish({ type: "instance.event", instanceId: workspaceId, event }) + return + } + + if (event.type === "message.updated") { + const info = (event as any)?.properties?.info + const sessionId = info?.sessionID + if (typeof sessionId === "string") { + const cache = this.getSessionCache(workspaceId) + const cached = cache.get(sessionId) + // If we've never seen this session OR we have not verified the session via the + // session endpoint yet, fetch it once and emit a synthetic session.updated BEFORE + // publishing message.updated. + if (!cached || !cached.verified) { + const sessionInfo = await this.getSessionInfo(workspaceId, sessionId) + if (sessionInfo && typeof sessionInfo.id === "string") { + const syntheticEvent = { + type: "session.updated", + properties: { + info: sessionInfo, + }, + } + // Update cache from the source-of-truth payload, then process synchronously to + // preserve ordering (session.updated before message.updated). + const hasParentIdField = sessionInfo && typeof sessionInfo === "object" && Object.prototype.hasOwnProperty.call(sessionInfo, "parentID") + const parentID = typeof sessionInfo.parentID === "string" ? sessionInfo.parentID : null + this.mergeCachedParentId(cache, sessionInfo.id, parentID, hasParentIdField, true) + await this.handleInstanceEvent(workspaceId, syntheticEvent as any) + } + } + } + this.options.eventBus.publish({ type: "instance.event", instanceId: workspaceId, event }) + return + } + + this.options.eventBus.publish({ type: "instance.event", instanceId: workspaceId, event }) + } + + private async getSessionInfo(workspaceId: string, sessionId: string): Promise { + const key = `${workspaceId}:${sessionId}` + const existing = this.sessionFetches.get(key) + if (existing) { + return existing + } + + const task = (async () => { + const port = this.options.workspaceManager.getInstancePort(workspaceId) + if (!port) return null + + const url = `http://${INSTANCE_HOST}:${port}/session/${sessionId}` + const headers: Record = {} + const authHeader = this.options.workspaceManager.getInstanceAuthorizationHeader(workspaceId) + if (authHeader) { + headers["Authorization"] = authHeader + } + + try { + const response = await fetch(url, { headers }) + if (!response.ok) { + this.options.logger.debug({ workspaceId, sessionId, status: response.status }, "Failed to fetch session info") + return null + } + return (await response.json()) as any + } catch (error) { + this.options.logger.debug({ workspaceId, sessionId, err: error }, "Failed to fetch session info") + return null + } + })() + + this.sessionFetches.set(key, task) + task.finally(() => this.sessionFetches.delete(key)).catch(() => {}) + return task + } + private publishStatus(instanceId: string, status: InstanceStreamStatus, reason?: string) { this.options.logger.debug({ instanceId, status, reason }, "Instance SSE status updated") this.options.eventBus.publish({ type: "instance.eventStatus", instanceId, status, reason }) diff --git a/packages/server/src/workspaces/manager.ts b/packages/server/src/workspaces/manager.ts index 623667b7..15e69f6a 100644 --- a/packages/server/src/workspaces/manager.ts +++ b/packages/server/src/workspaces/manager.ts @@ -28,6 +28,8 @@ interface WorkspaceManagerOptions { eventBus: EventBus logger: Logger getServerBaseUrl: () => string + /** Optional CA bundle path to trust CodeNomad HTTPS certs. */ + nodeExtraCaCertsPath?: string } interface WorkspaceRecord extends WorkspaceDescriptor {} @@ -91,7 +93,7 @@ export class WorkspaceManager { this.options.logger.info({ workspaceId: id, folder: workspacePath, binary: resolvedBinaryPath }, "Creating workspace") - const proxyPath = `/workspaces/${id}/instance` + const proxyPath = `/workspaces/${id}/worktrees/root/instance` const descriptor: WorkspaceRecord = { @@ -127,15 +129,20 @@ export class WorkspaceManager { } this.opencodeAuth.set(id, { username: opencodeUsername, password: opencodePassword, authorization }) - const environment = { + const environment: Record = { ...userEnvironment, OPENCODE_CONFIG_DIR: this.opencodeConfigDir, CODENOMAD_INSTANCE_ID: id, CODENOMAD_BASE_URL: this.options.getServerBaseUrl(), + ...(this.options.nodeExtraCaCertsPath ? { NODE_EXTRA_CA_CERTS: this.options.nodeExtraCaCertsPath } : {}), [OPENCODE_SERVER_USERNAME_ENV]: opencodeUsername, [OPENCODE_SERVER_PASSWORD_ENV]: opencodePassword, } + if (process.env.OPENCODE_CONFIG_CONTENT) { + environment.OPENCODE_CONFIG_CONTENT = process.env.OPENCODE_CONFIG_CONTENT + } + try { const { pid, port, exitPromise, getLastOutput } = await this.runtime.launch({ workspaceId: id, diff --git a/packages/server/src/workspaces/runtime.ts b/packages/server/src/workspaces/runtime.ts index 06b6813b..a7196d60 100644 --- a/packages/server/src/workspaces/runtime.ts +++ b/packages/server/src/workspaces/runtime.ts @@ -116,12 +116,26 @@ export class WorkspaceRuntime { folder: options.folder, binary: options.binaryPath, spawnCommand: spec.command, - spawnArgs: spec.args, commandLine, - env: redactEnvironment(env), }, "Launching OpenCode process", ) + + this.logger.debug( + { + workspaceId: options.workspaceId, + spawnArgs: spec.args, + }, + "OpenCode spawn args", + ) + + this.logger.trace( + { + workspaceId: options.workspaceId, + env: redactEnvironment(env), + }, + "OpenCode spawn environment", + ) const detached = process.platform !== "win32" const child = spawn(spec.command, spec.args, { cwd: options.folder, diff --git a/packages/server/src/workspaces/worktree-map.ts b/packages/server/src/workspaces/worktree-map.ts new file mode 100644 index 00000000..07a289f0 --- /dev/null +++ b/packages/server/src/workspaces/worktree-map.ts @@ -0,0 +1,129 @@ +import fs from "fs" +import { promises as fsp } from "fs" +import path from "path" +import type { WorktreeMap } from "../api-types" +import { resolveRepoRoot } from "./git-worktrees" +import type { LogLike } from "./git-worktrees" + +const DEFAULT_MAP: WorktreeMap = { + version: 1, + defaultWorktreeSlug: "root", + parentSessionWorktreeSlug: {}, +} + +function getMapPath(repoRoot: string): string { + return path.join(repoRoot, ".codenomad", "worktreeMap.json") +} + +function getGitExcludePath(repoRoot: string): string { + return path.join(repoRoot, ".git", "info", "exclude") +} + +async function ensureGitExclude(repoRoot: string, logger?: LogLike): Promise { + const excludePath = getGitExcludePath(repoRoot) + try { + await fsp.mkdir(path.dirname(excludePath), { recursive: true }) + } catch { + return + } + + const entries = [ + ".codenomad/worktrees/", + ".codenomad/worktreeMap.json", + ] + + let existing = "" + try { + existing = await fsp.readFile(excludePath, "utf-8") + } catch (error) { + const code = (error as NodeJS.ErrnoException).code + if (code !== "ENOENT") { + logger?.debug?.({ err: error, excludePath }, "Failed to read .git/info/exclude") + return + } + existing = "" + } + + const lines = new Set(existing.split(/\r?\n/).map((l) => l.trim()).filter(Boolean)) + const missing = entries.filter((e) => !lines.has(e)) + if (missing.length === 0) { + return + } + + const header = existing.includes("# codenomad") ? "" : (existing.trim() ? "\n" : "") + "# codenomad\n" + const suffix = missing.map((e) => `${e}\n`).join("") + await fsp.writeFile(excludePath, `${existing}${header}${suffix}`, "utf-8") +} + +export async function ensureCodenomadGitExclude(workspaceFolder: string, logger?: LogLike): Promise { + const { repoRoot, isGitRepo } = await resolveRepoRoot(workspaceFolder, logger) + if (!isGitRepo) { + return + } + await ensureGitExclude(repoRoot, logger) +} + +export async function readWorktreeMap(workspaceFolder: string, logger?: LogLike): Promise { + const { repoRoot, isGitRepo } = await resolveRepoRoot(workspaceFolder, logger) + const filePath = getMapPath(repoRoot) + try { + const raw = await fsp.readFile(filePath, "utf-8") + const parsed = JSON.parse(raw) + if (!parsed || typeof parsed !== "object") { + return DEFAULT_MAP + } + const version = (parsed as any).version + if (version !== 1) { + return DEFAULT_MAP + } + const defaultWorktreeSlug = typeof (parsed as any).defaultWorktreeSlug === "string" ? (parsed as any).defaultWorktreeSlug : "root" + const parentSessionWorktreeSlug = (parsed as any).parentSessionWorktreeSlug + const mapping = parentSessionWorktreeSlug && typeof parentSessionWorktreeSlug === "object" ? parentSessionWorktreeSlug : {} + return { + version: 1, + defaultWorktreeSlug, + parentSessionWorktreeSlug: { ...mapping }, + } + } catch (error) { + const code = (error as NodeJS.ErrnoException).code + if (code === "ENOENT") { + if (isGitRepo) { + // Best-effort ignore setup on first use. + await ensureGitExclude(repoRoot, logger).catch(() => undefined) + } + return DEFAULT_MAP + } + logger?.warn?.({ err: error, filePath }, "Failed to read worktree map") + return DEFAULT_MAP + } +} + +export async function writeWorktreeMap(workspaceFolder: string, next: WorktreeMap, logger?: LogLike): Promise { + const { repoRoot, isGitRepo } = await resolveRepoRoot(workspaceFolder, logger) + const filePath = getMapPath(repoRoot) + await fsp.mkdir(path.dirname(filePath), { recursive: true }) + + // Ensure ignore rules are present (local-only). + if (isGitRepo) { + await ensureGitExclude(repoRoot, logger).catch(() => undefined) + } + + const payload: WorktreeMap = { + version: 1, + defaultWorktreeSlug: next.defaultWorktreeSlug || "root", + parentSessionWorktreeSlug: next.parentSessionWorktreeSlug ?? {}, + } + + // Write atomically. + const tmpPath = `${filePath}.${process.pid}.tmp` + await fsp.writeFile(tmpPath, JSON.stringify(payload, null, 2), "utf-8") + await fsp.rename(tmpPath, filePath) +} + +export function worktreeMapExists(repoRoot: string): boolean { + try { + return fs.existsSync(getMapPath(repoRoot)) + } catch { + return false + } +} diff --git a/packages/tauri-app/Cargo.lock b/packages/tauri-app/Cargo.lock index abffbd40..e388ea42 100644 --- a/packages/tauri-app/Cargo.lock +++ b/packages/tauri-app/Cargo.lock @@ -47,6 +47,43 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "apple-bindgen" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f109ee76f68b4767848cb5dc93bfcc7c425deca849c4c81fa11cdce525e3d2" +dependencies = [ + "apple-sdk", + "bindgen", + "derive_more", + "regex", + "serde", + "thiserror 1.0.69", + "toml 0.6.0", +] + +[[package]] +name = "apple-sdk" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a04f192a700686ee70008ff4e4eb76fe7d11814ab93b7ee9d48c36b9a9f0bd2a" +dependencies = [ + "plist", + "serde", + "serde_json", +] + +[[package]] +name = "apple-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b3a1c3342678cd72676d0c1644fde496c1f65ea41f51465f54a89cad3bdf34" +dependencies = [ + "apple-bindgen", + "apple-sdk", + "objc", +] + [[package]] name = "ashpd" version = "0.11.0" @@ -65,7 +102,17 @@ dependencies = [ "wayland-backend", "wayland-client", "wayland-protocols", - "zbus", + "zbus 5.12.0", +] + +[[package]] +name = "async-broadcast" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +dependencies = [ + "event-listener 2.5.3", + "futures-core", ] [[package]] @@ -74,7 +121,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ - "event-listener", + "event-listener 5.4.1", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -100,12 +147,44 @@ checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ "async-task", "concurrent-queue", - "fastrand", - "futures-lite", + "fastrand 2.3.0", + "futures-lite 2.6.1", "pin-project-lite", "slab", ] +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "blocking", + "futures-lite 1.13.0", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.28", + "slab", + "socket2 0.4.10", + "waker-fn", +] + [[package]] name = "async-io" version = "2.6.0" @@ -116,25 +195,51 @@ dependencies = [ "cfg-if", "concurrent-queue", "futures-io", - "futures-lite", + "futures-lite 2.6.1", "parking", - "polling", + "polling 3.11.0", "rustix 1.1.2", "slab", "windows-sys 0.61.2", ] +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + [[package]] name = "async-lock" version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ - "event-listener", + "event-listener 5.4.1", "event-listener-strategy", "pin-project-lite", ] +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.44", + "windows-sys 0.48.0", +] + [[package]] name = "async-process" version = "2.5.0" @@ -142,14 +247,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ "async-channel", - "async-io", - "async-lock", + "async-io 2.6.0", + "async-lock 3.4.1", "async-signal", "async-task", "blocking", "cfg-if", - "event-listener", - "futures-lite", + "event-listener 5.4.1", + "futures-lite 2.6.1", "rustix 1.1.2", ] @@ -170,8 +275,8 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" dependencies = [ - "async-io", - "async-lock", + "async-io 2.6.0", + "async-lock 3.4.1", "atomic-waker", "cfg-if", "futures-core", @@ -246,6 +351,28 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bindgen" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 1.0.109", + "which", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -297,7 +424,7 @@ dependencies = [ "async-channel", "async-task", "futures-io", - "futures-lite", + "futures-lite 2.6.1", "piper", ] @@ -432,6 +559,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfb" version = "0.7.3" @@ -477,6 +613,17 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading 0.8.9", +] + [[package]] name = "codenomad-tauri" version = "0.1.0" @@ -489,9 +636,12 @@ dependencies = [ "regex", "serde", "serde_json", + "serde_yaml", "tauri", "tauri-build", "tauri-plugin-dialog", + "tauri-plugin-keepawake", + "tauri-plugin-notification", "tauri-plugin-opener", "thiserror 1.0.69", "url", @@ -533,6 +683,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -556,7 +716,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" dependencies = [ "bitflags 2.10.0", - "core-foundation", + "core-foundation 0.10.1", "core-graphics-types", "foreign-types", "libc", @@ -569,7 +729,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ "bitflags 2.10.0", - "core-foundation", + "core-foundation 0.10.1", "libc", ] @@ -653,14 +813,38 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core 0.14.4", + "darling_macro 0.14.4", +] + [[package]] name = "darling" version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", ] [[package]] @@ -673,17 +857,28 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.11.1", "syn 2.0.110", ] +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core 0.14.4", + "quote", + "syn 1.0.109", +] + [[package]] name = "darling_macro" version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ - "darling_core", + "darling_core 0.21.3", "quote", "syn 2.0.110", ] @@ -698,6 +893,48 @@ dependencies = [ "serde_core", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f59169f400d8087f238c5c0c7db6a28af18681717f3b623227d92f397e938c7" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4ec317cc3e7ef0928b0ca6e4a634a4d6c001672ae210438cf114a83e56b018d" +dependencies = [ + "darling 0.14.4", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870368c3fb35b8031abb378861d4460f573b92238ec2152c927a21f77e3e0127" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + [[package]] name = "derive_more" version = "0.99.20" @@ -798,7 +1035,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading", + "libloading 0.8.9", ] [[package]] @@ -946,6 +1183,23 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + [[package]] name = "event-listener" version = "5.4.1" @@ -963,10 +1217,19 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "event-listener", + "event-listener 5.4.1", "pin-project-lite", ] +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -988,7 +1251,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" dependencies = [ - "memoffset", + "memoffset 0.9.1", "rustc_version", ] @@ -1092,13 +1355,28 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-lite" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ - "fastrand", + "fastrand 2.3.0", "futures-core", "futures-io", "parking", @@ -1469,6 +1747,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hermit-abi" version = "0.5.2" @@ -1581,7 +1865,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.1", "tokio", "tower-service", "tracing", @@ -1761,6 +2045,26 @@ dependencies = [ "cfb", ] +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "ipnet" version = "2.11.0" @@ -1879,6 +2183,21 @@ dependencies = [ "serde_json", ] +[[package]] +name = "keepawake" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1e324a09aa048770b565b4ab2970bb9d1a7dac1038c68c2d243d8f7b6b1c90" +dependencies = [ + "apple-sys", + "cfg-if", + "core-foundation 0.9.4", + "derive_builder", + "thiserror 1.0.69", + "windows 0.52.0", + "zbus 3.15.2", +] + [[package]] name = "keyboard-types" version = "0.7.0" @@ -1908,6 +2227,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libappindicator" version = "0.9.0" @@ -1928,7 +2253,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" dependencies = [ "gtk-sys", - "libloading", + "libloading 0.7.4", "once_cell", ] @@ -1948,6 +2273,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link 0.2.1", +] + [[package]] name = "libredox" version = "0.1.10" @@ -1958,6 +2293,12 @@ dependencies = [ "libc", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -1997,6 +2338,27 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +[[package]] +name = "mac-notification-sys" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fd3f75411f4725061682ed91f131946e912859d0044d39c4ec0aac818d7621" +dependencies = [ + "cc", + "objc2 0.6.3", + "objc2-foundation 0.3.2", + "time", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "markup5ever" version = "0.14.1" @@ -2034,6 +2396,15 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -2049,6 +2420,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2127,6 +2504,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", +] + [[package]] name = "nix" version = "0.30.1" @@ -2137,7 +2526,7 @@ dependencies = [ "cfg-if", "cfg_aliases", "libc", - "memoffset", + "memoffset 0.9.1", ] [[package]] @@ -2146,6 +2535,39 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom8" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" +dependencies = [ + "memchr", +] + +[[package]] +name = "notify-rust" +version = "4.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21af20a1b50be5ac5861f74af1a863da53a11c38684d9818d82f1c42f7fdc6c2" +dependencies = [ + "futures-lite 2.6.1", + "log", + "mac-notification-sys", + "serde", + "tauri-winrt-notification", + "zbus 5.12.0", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -2183,6 +2605,15 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + [[package]] name = "objc-sys" version = "0.3.5" @@ -2541,6 +2972,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "percent-encoding" version = "2.3.2" @@ -2700,7 +3137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand", + "fastrand 2.3.0", "futures-io", ] @@ -2736,6 +3173,22 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + [[package]] name = "polling" version = "3.11.0" @@ -2744,7 +3197,7 @@ checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi", + "hermit-abi 0.5.2", "pin-project-lite", "rustix 1.1.2", "windows-sys 0.61.2", @@ -3137,6 +3590,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.4.1" @@ -3146,6 +3605,20 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.37.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "519165d378b97752ca44bbe15047d5d3409e875f39327546b42ac81d7e18c1b6" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + [[package]] name = "rustix" version = "0.38.44" @@ -3416,12 +3889,25 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08a72d8216842fdd57820dc78d840bef99248e35fb2554ff923319e60f2d686b" dependencies = [ - "darling", + "darling 0.21.3", "proc-macro2", "quote", "syn 2.0.110", ] +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.12.1", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "serialize-to-javascript" version = "0.1.2" @@ -3454,6 +3940,17 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha2" version = "0.10.9" @@ -3510,6 +4007,16 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "socket2" version = "0.6.1" @@ -3605,6 +4112,12 @@ dependencies = [ "quote", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" @@ -3685,7 +4198,7 @@ checksum = "f3a753bdc39c07b192151523a3f77cd0394aa75413802c883a0f6f6a0e5ee2e7" dependencies = [ "bitflags 2.10.0", "block2 0.6.2", - "core-foundation", + "core-foundation 0.10.1", "core-graphics", "crossbeam-channel", "dispatch", @@ -3711,7 +4224,7 @@ dependencies = [ "tao-macros", "unicode-segmentation", "url", - "windows", + "windows 0.61.3", "windows-core 0.61.2", "windows-version", "x11-dl", @@ -3782,7 +4295,7 @@ dependencies = [ "webkit2gtk", "webview2-com", "window-vibrancy", - "windows", + "windows 0.61.3", ] [[package]] @@ -3905,6 +4418,38 @@ dependencies = [ "url", ] +[[package]] +name = "tauri-plugin-keepawake" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19695262819df92661139c607c5b5449b21ef5fa9429b8cb556e6c55bf34e5cb" +dependencies = [ + "keepawake", + "serde", + "tauri", + "tauri-plugin", + "thiserror 2.0.17", +] + +[[package]] +name = "tauri-plugin-notification" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01fc2c5ff41105bd1f7242d8201fdf3efd70749b82fa013a17f2126357d194cc" +dependencies = [ + "log", + "notify-rust", + "rand 0.9.2", + "serde", + "serde_json", + "serde_repr", + "tauri", + "tauri-plugin", + "thiserror 2.0.17", + "time", + "url", +] + [[package]] name = "tauri-plugin-opener" version = "2.5.2" @@ -3923,8 +4468,8 @@ dependencies = [ "tauri-plugin", "thiserror 2.0.17", "url", - "windows", - "zbus", + "windows 0.61.3", + "zbus 5.12.0", ] [[package]] @@ -3949,7 +4494,7 @@ dependencies = [ "url", "webkit2gtk", "webview2-com", - "windows", + "windows 0.61.3", ] [[package]] @@ -3975,7 +4520,7 @@ dependencies = [ "url", "webkit2gtk", "webview2-com", - "windows", + "windows 0.61.3", "wry", ] @@ -4028,13 +4573,25 @@ dependencies = [ "toml 0.9.8", ] +[[package]] +name = "tauri-winrt-notification" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9" +dependencies = [ + "quick-xml 0.37.5", + "thiserror 2.0.17", + "windows 0.61.3", + "windows-version", +] + [[package]] name = "tempfile" version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ - "fastrand", + "fastrand 2.3.0", "getrandom 0.3.4", "once_cell", "rustix 1.1.2", @@ -4144,7 +4701,7 @@ dependencies = [ "mio", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.6.1", "tracing", "windows-sys 0.61.2", ] @@ -4162,6 +4719,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb9d890e4dc9298b70f740f615f2e05b9db37dce531f6b24fb77ac993f9f217" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.5.1", + "toml_edit 0.18.1", +] + [[package]] name = "toml" version = "0.8.2" @@ -4189,6 +4758,15 @@ dependencies = [ "winnow 0.7.13", ] +[[package]] +name = "toml_datetime" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" +dependencies = [ + "serde", +] + [[package]] name = "toml_datetime" version = "0.6.3" @@ -4207,6 +4785,19 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_edit" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" +dependencies = [ + "indexmap 1.9.3", + "nom8", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.5.1", +] + [[package]] name = "toml_edit" version = "0.19.15" @@ -4380,7 +4971,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ - "memoffset", + "memoffset 0.9.1", "tempfile", "winapi", ] @@ -4438,6 +5029,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "url" version = "2.5.7" @@ -4518,6 +5115,12 @@ dependencies = [ "libc", ] +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + [[package]] name = "walkdir" version = "2.5.0" @@ -4751,7 +5354,7 @@ checksum = "d4ba622a989277ef3886dd5afb3e280e3dd6d974b766118950a08f8f678ad6a4" dependencies = [ "webview2-com-macros", "webview2-com-sys", - "windows", + "windows 0.61.3", "windows-core 0.61.2", "windows-implement", "windows-interface", @@ -4775,7 +5378,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36695906a1b53a3bf5c4289621efedac12b73eeb0b89e7e1a89b517302d5d75c" dependencies = [ "thiserror 2.0.17", - "windows", + "windows 0.61.3", "windows-core 0.61.2", ] @@ -4837,6 +5440,16 @@ dependencies = [ "windows-version", ] +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows" version = "0.61.3" @@ -4859,6 +5472,15 @@ dependencies = [ "windows-core 0.61.2", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.61.2" @@ -5361,7 +5983,7 @@ dependencies = [ "webkit2gtk", "webkit2gtk-sys", "webview2-com", - "windows", + "windows 0.61.3", "windows-core 0.61.2", "windows-version", "x11-dl", @@ -5388,6 +6010,16 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "xdg-home" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "yoke" version = "0.8.1" @@ -5411,27 +6043,68 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zbus" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" +dependencies = [ + "async-broadcast 0.5.1", + "async-executor", + "async-fs", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-process 1.8.1", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "byteorder", + "derivative", + "enumflags2", + "event-listener 2.5.3", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix 0.26.4", + "once_cell", + "ordered-stream", + "rand 0.8.5", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "winapi", + "xdg-home", + "zbus_macros 3.15.2", + "zbus_names 2.6.1", + "zvariant 3.15.2", +] + [[package]] name = "zbus" version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b622b18155f7a93d1cd2dc8c01d2d6a44e08fb9ebb7b3f9e6ed101488bad6c91" dependencies = [ - "async-broadcast", + "async-broadcast 0.7.2", "async-executor", - "async-io", - "async-lock", - "async-process", + "async-io 2.6.0", + "async-lock 3.4.1", + "async-process 2.5.0", "async-recursion", "async-task", "async-trait", "blocking", "enumflags2", - "event-listener", + "event-listener 5.4.1", "futures-core", - "futures-lite", + "futures-lite 2.6.1", "hex", - "nix", + "nix 0.30.1", "ordered-stream", "serde", "serde_repr", @@ -5441,9 +6114,23 @@ dependencies = [ "uuid", "windows-sys 0.61.2", "winnow 0.7.13", - "zbus_macros", - "zbus_names", - "zvariant", + "zbus_macros 5.12.0", + "zbus_names 4.2.0", + "zvariant 5.8.0", +] + +[[package]] +name = "zbus_macros" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "zvariant_utils 1.0.1", ] [[package]] @@ -5456,9 +6143,20 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.110", - "zbus_names", - "zvariant", - "zvariant_utils", + "zbus_names 4.2.0", + "zvariant 5.8.0", + "zvariant_utils 3.2.1", +] + +[[package]] +name = "zbus_names" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" +dependencies = [ + "serde", + "static_assertions", + "zvariant 3.15.2", ] [[package]] @@ -5470,7 +6168,7 @@ dependencies = [ "serde", "static_assertions", "winnow 0.7.13", - "zvariant", + "zvariant 5.8.0", ] [[package]] @@ -5547,6 +6245,20 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "zvariant" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "zvariant_derive 3.15.2", +] + [[package]] name = "zvariant" version = "5.8.0" @@ -5558,8 +6270,21 @@ dependencies = [ "serde", "url", "winnow 0.7.13", - "zvariant_derive", - "zvariant_utils", + "zvariant_derive 5.8.0", + "zvariant_utils 3.2.1", +] + +[[package]] +name = "zvariant_derive" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "zvariant_utils 1.0.1", ] [[package]] @@ -5572,7 +6297,18 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.110", - "zvariant_utils", + "zvariant_utils 3.2.1", +] + +[[package]] +name = "zvariant_utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] diff --git a/packages/tauri-app/package.json b/packages/tauri-app/package.json index 243b35bf..86b42d54 100644 --- a/packages/tauri-app/package.json +++ b/packages/tauri-app/package.json @@ -1,6 +1,6 @@ { "name": "@codenomad/tauri-app", - "version": "0.9.5", + "version": "0.10.3", "private": true, "license": "MIT", "scripts": { diff --git a/packages/tauri-app/scripts/dev-prep.js b/packages/tauri-app/scripts/dev-prep.js index abbb4c64..52980401 100644 --- a/packages/tauri-app/scripts/dev-prep.js +++ b/packages/tauri-app/scripts/dev-prep.js @@ -3,6 +3,7 @@ const fs = require("fs") const path = require("path") const { execSync } = require("child_process") +const { pathToFileURL } = require("url") const root = path.resolve(__dirname, "..") const workspaceRoot = path.resolve(root, "..", "..") @@ -10,6 +11,20 @@ const uiRoot = path.resolve(root, "..", "ui") const uiDist = path.resolve(uiRoot, "src", "renderer", "dist") const uiLoadingDest = path.resolve(root, "src-tauri", "resources", "ui-loading") +async function ensureMonacoAssets() { + const helperPath = path.join(uiRoot, "scripts", "monaco-public-assets.js") + const helperUrl = pathToFileURL(helperPath).href + const { copyMonacoPublicAssets } = await import(helperUrl) + copyMonacoPublicAssets({ + uiRendererRoot: path.join(uiRoot, "src", "renderer"), + warn: (msg) => console.warn(`[dev-prep] ${msg}`), + sourceRoots: [ + path.resolve(workspaceRoot, "node_modules", "monaco-editor", "min", "vs"), + path.resolve(uiRoot, "node_modules", "monaco-editor", "min", "vs"), + ], + }) +} + function ensureUiBuild() { const loadingHtml = path.join(uiDist, "loading.html") if (fs.existsSync(loadingHtml)) { @@ -42,5 +57,11 @@ function copyUiLoadingAssets() { console.log(`[dev-prep] copied loader bundle from ${uiDist}`) } -ensureUiBuild() -copyUiLoadingAssets() +;(async () => { + await ensureMonacoAssets() + ensureUiBuild() + copyUiLoadingAssets() +})().catch((err) => { + console.error("[dev-prep] failed:", err) + process.exit(1) +}) diff --git a/packages/tauri-app/scripts/prebuild.js b/packages/tauri-app/scripts/prebuild.js index f4daf3b3..fbf0a4a1 100644 --- a/packages/tauri-app/scripts/prebuild.js +++ b/packages/tauri-app/scripts/prebuild.js @@ -2,6 +2,7 @@ const fs = require("fs") const path = require("path") const { execSync } = require("child_process") +const { pathToFileURL } = require("url") const root = path.resolve(__dirname, "..") const workspaceRoot = path.resolve(root, "..", "..") @@ -37,6 +38,20 @@ const braceExpansionPath = path.join( const viteBinPath = path.join(uiRoot, "node_modules", ".bin", "vite") +async function ensureMonacoAssets() { + const helperPath = path.join(uiRoot, "scripts", "monaco-public-assets.js") + const helperUrl = pathToFileURL(helperPath).href + const { copyMonacoPublicAssets } = await import(helperUrl) + copyMonacoPublicAssets({ + uiRendererRoot: path.join(uiRoot, "src", "renderer"), + warn: (msg) => console.warn(`[prebuild] ${msg}`), + sourceRoots: [ + path.resolve(workspaceRoot, "node_modules", "monaco-editor", "min", "vs"), + path.resolve(uiRoot, "node_modules", "monaco-editor", "min", "vs"), + ], + }) +} + function ensureServerBuild() { const distPath = path.join(serverRoot, "dist") const publicPath = path.join(serverRoot, "public") @@ -223,12 +238,18 @@ function copyUiLoadingAssets() { console.log(`[prebuild] prepared UI loading assets from ${uiDist}`) } -ensureServerDevDependencies() -ensureUiDevDependencies() -ensureRollupPlatformBinary() -ensureServerDependencies() -ensureServerBuild() -ensureUiBuild() -copyServerArtifacts() -stripNodeModuleBins() -copyUiLoadingAssets() +;(async () => { + ensureServerDevDependencies() + ensureUiDevDependencies() + await ensureMonacoAssets() + ensureRollupPlatformBinary() + ensureServerDependencies() + ensureServerBuild() + ensureUiBuild() + copyServerArtifacts() + stripNodeModuleBins() + copyUiLoadingAssets() +})().catch((err) => { + console.error("[prebuild] failed:", err) + process.exit(1) +}) diff --git a/packages/tauri-app/src-tauri/Cargo.toml b/packages/tauri-app/src-tauri/Cargo.toml index 69626ad9..f119c846 100644 --- a/packages/tauri-app/src-tauri/Cargo.toml +++ b/packages/tauri-app/src-tauri/Cargo.toml @@ -11,6 +11,7 @@ tauri-build = { version = "2.5.2", features = [] } tauri = { version = "2.5.2", features = [ "devtools"] } serde = { version = "1", features = ["derive"] } serde_json = "1" +serde_yaml = "0.9" regex = "1" once_cell = "1" parking_lot = "0.12" @@ -22,3 +23,5 @@ tauri-plugin-dialog = "2" dirs = "5" tauri-plugin-opener = "2" url = "2" +tauri-plugin-keepawake = "0.1.1" +tauri-plugin-notification = "2" diff --git a/packages/tauri-app/src-tauri/capabilities/main-window.json b/packages/tauri-app/src-tauri/capabilities/main-window.json index 14cb2d7f..7480caa3 100644 --- a/packages/tauri-app/src-tauri/capabilities/main-window.json +++ b/packages/tauri-app/src-tauri/capabilities/main-window.json @@ -11,6 +11,10 @@ "core:menu:default", "dialog:allow-open", "opener:allow-default-urls", + "notification:allow-is-permission-granted", + "notification:allow-request-permission", + "notification:allow-notify", + "notification:allow-show", "core:webview:allow-set-webview-zoom" ] } diff --git a/packages/tauri-app/src-tauri/gen/schemas/acl-manifests.json b/packages/tauri-app/src-tauri/gen/schemas/acl-manifests.json index 60e4f04e..d66d7b22 100644 --- a/packages/tauri-app/src-tauri/gen/schemas/acl-manifests.json +++ b/packages/tauri-app/src-tauri/gen/schemas/acl-manifests.json @@ -1 +1 @@ -{"core":{"default_permission":{"identifier":"default","description":"Default core plugins set.","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version","allow-identifier","allow-bundle-type","allow-register-listener","allow-remove-listener"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-bundle-type":{"identifier":"allow-bundle-type","description":"Enables the bundle_type command without any pre-configured scope.","commands":{"allow":["bundle_type"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-fetch-data-store-identifiers":{"identifier":"allow-fetch-data-store-identifiers","description":"Enables the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":["fetch_data_store_identifiers"],"deny":[]}},"allow-identifier":{"identifier":"allow-identifier","description":"Enables the identifier command without any pre-configured scope.","commands":{"allow":["identifier"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-data-store":{"identifier":"allow-remove-data-store","description":"Enables the remove_data_store command without any pre-configured scope.","commands":{"allow":["remove_data_store"],"deny":[]}},"allow-remove-listener":{"identifier":"allow-remove-listener","description":"Enables the remove_listener command without any pre-configured scope.","commands":{"allow":["remove_listener"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-set-dock-visibility":{"identifier":"allow-set-dock-visibility","description":"Enables the set_dock_visibility command without any pre-configured scope.","commands":{"allow":["set_dock_visibility"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-bundle-type":{"identifier":"deny-bundle-type","description":"Denies the bundle_type command without any pre-configured scope.","commands":{"allow":[],"deny":["bundle_type"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-fetch-data-store-identifiers":{"identifier":"deny-fetch-data-store-identifiers","description":"Denies the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_data_store_identifiers"]}},"deny-identifier":{"identifier":"deny-identifier","description":"Denies the identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["identifier"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-data-store":{"identifier":"deny-remove-data-store","description":"Denies the remove_data_store command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_data_store"]}},"deny-remove-listener":{"identifier":"deny-remove-listener","description":"Denies the remove_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_listener"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-set-dock-visibility":{"identifier":"deny-set-dock-visibility","description":"Denies the set_dock_visibility command without any pre-configured scope.","commands":{"allow":[],"deny":["set_dock_visibility"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-auto-resize":{"identifier":"allow-set-webview-auto-resize","description":"Enables the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":["set_webview_auto_resize"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-auto-resize":{"identifier":"deny-set-webview-auto-resize","description":"Denies the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_auto_resize"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-is-always-on-top","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-always-on-top":{"identifier":"allow-is-always-on-top","description":"Enables the is_always_on_top command without any pre-configured scope.","commands":{"allow":["is_always_on_top"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-focusable":{"identifier":"allow-set-focusable","description":"Enables the set_focusable command without any pre-configured scope.","commands":{"allow":["set_focusable"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-simple-fullscreen":{"identifier":"allow-set-simple-fullscreen","description":"Enables the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":["set_simple_fullscreen"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-always-on-top":{"identifier":"deny-is-always-on-top","description":"Denies the is_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["is_always_on_top"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-focusable":{"identifier":"deny-set-focusable","description":"Denies the set_focusable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focusable"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-simple-fullscreen":{"identifier":"deny-set-simple-fullscreen","description":"Denies the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_simple_fullscreen"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-ask","allow-confirm","allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope.","commands":{"allow":["ask"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope.","commands":{"allow":["confirm"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope.","commands":{"allow":[],"deny":["ask"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope.","commands":{"allow":[],"deny":["confirm"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"opener":{"default_permission":{"identifier":"default","description":"This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer","permissions":["allow-open-url","allow-reveal-item-in-dir","allow-default-urls"]},"permissions":{"allow-default-urls":{"identifier":"allow-default-urls","description":"This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"url":"mailto:*"},{"url":"tel:*"},{"url":"http://*"},{"url":"https://*"}]}},"allow-open-path":{"identifier":"allow-open-path","description":"Enables the open_path command without any pre-configured scope.","commands":{"allow":["open_path"],"deny":[]}},"allow-open-url":{"identifier":"allow-open-url","description":"Enables the open_url command without any pre-configured scope.","commands":{"allow":["open_url"],"deny":[]}},"allow-reveal-item-in-dir":{"identifier":"allow-reveal-item-in-dir","description":"Enables the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":["reveal_item_in_dir"],"deny":[]}},"deny-open-path":{"identifier":"deny-open-path","description":"Denies the open_path command without any pre-configured scope.","commands":{"allow":[],"deny":["open_path"]}},"deny-open-url":{"identifier":"deny-open-url","description":"Denies the open_url command without any pre-configured scope.","commands":{"allow":[],"deny":["open_url"]}},"deny-reveal-item-in-dir":{"identifier":"deny-reveal-item-in-dir","description":"Denies the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["reveal_item_in_dir"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this url with, for example: firefox."},"url":{"description":"A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"","type":"string"}},"required":["url"],"type":"object"},{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this path with, for example: xdg-open."},"path":{"description":"A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"definitions":{"Application":{"anyOf":[{"description":"Open in default application.","type":"null"},{"description":"If true, allow open with any application.","type":"boolean"},{"description":"Allow specific application to open with.","type":"string"}],"description":"Opener scope application."}},"description":"Opener scope entry.","title":"OpenerScopeEntry"}}} \ No newline at end of file +{"core":{"default_permission":{"identifier":"default","description":"Default core plugins set.","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version","allow-identifier","allow-bundle-type","allow-register-listener","allow-remove-listener"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-bundle-type":{"identifier":"allow-bundle-type","description":"Enables the bundle_type command without any pre-configured scope.","commands":{"allow":["bundle_type"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-fetch-data-store-identifiers":{"identifier":"allow-fetch-data-store-identifiers","description":"Enables the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":["fetch_data_store_identifiers"],"deny":[]}},"allow-identifier":{"identifier":"allow-identifier","description":"Enables the identifier command without any pre-configured scope.","commands":{"allow":["identifier"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-data-store":{"identifier":"allow-remove-data-store","description":"Enables the remove_data_store command without any pre-configured scope.","commands":{"allow":["remove_data_store"],"deny":[]}},"allow-remove-listener":{"identifier":"allow-remove-listener","description":"Enables the remove_listener command without any pre-configured scope.","commands":{"allow":["remove_listener"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-set-dock-visibility":{"identifier":"allow-set-dock-visibility","description":"Enables the set_dock_visibility command without any pre-configured scope.","commands":{"allow":["set_dock_visibility"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-bundle-type":{"identifier":"deny-bundle-type","description":"Denies the bundle_type command without any pre-configured scope.","commands":{"allow":[],"deny":["bundle_type"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-fetch-data-store-identifiers":{"identifier":"deny-fetch-data-store-identifiers","description":"Denies the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_data_store_identifiers"]}},"deny-identifier":{"identifier":"deny-identifier","description":"Denies the identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["identifier"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-data-store":{"identifier":"deny-remove-data-store","description":"Denies the remove_data_store command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_data_store"]}},"deny-remove-listener":{"identifier":"deny-remove-listener","description":"Denies the remove_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_listener"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-set-dock-visibility":{"identifier":"deny-set-dock-visibility","description":"Denies the set_dock_visibility command without any pre-configured scope.","commands":{"allow":[],"deny":["set_dock_visibility"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-auto-resize":{"identifier":"allow-set-webview-auto-resize","description":"Enables the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":["set_webview_auto_resize"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-auto-resize":{"identifier":"deny-set-webview-auto-resize","description":"Denies the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_auto_resize"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-is-always-on-top","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-always-on-top":{"identifier":"allow-is-always-on-top","description":"Enables the is_always_on_top command without any pre-configured scope.","commands":{"allow":["is_always_on_top"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-focusable":{"identifier":"allow-set-focusable","description":"Enables the set_focusable command without any pre-configured scope.","commands":{"allow":["set_focusable"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-simple-fullscreen":{"identifier":"allow-set-simple-fullscreen","description":"Enables the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":["set_simple_fullscreen"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-always-on-top":{"identifier":"deny-is-always-on-top","description":"Denies the is_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["is_always_on_top"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-focusable":{"identifier":"deny-set-focusable","description":"Denies the set_focusable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focusable"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-simple-fullscreen":{"identifier":"deny-set-simple-fullscreen","description":"Denies the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_simple_fullscreen"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-ask","allow-confirm","allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope.","commands":{"allow":["ask"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope.","commands":{"allow":["confirm"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope.","commands":{"allow":[],"deny":["ask"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope.","commands":{"allow":[],"deny":["confirm"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"keepawake":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-start","allow-stop"]},"permissions":{"allow-start":{"identifier":"allow-start","description":"Enables the start command without any pre-configured scope.","commands":{"allow":["start"],"deny":[]}},"allow-stop":{"identifier":"allow-stop","description":"Enables the stop command without any pre-configured scope.","commands":{"allow":["stop"],"deny":[]}},"deny-start":{"identifier":"deny-start","description":"Denies the start command without any pre-configured scope.","commands":{"allow":[],"deny":["start"]}},"deny-stop":{"identifier":"deny-stop","description":"Denies the stop command without any pre-configured scope.","commands":{"allow":[],"deny":["stop"]}}},"permission_sets":{},"global_scope_schema":null},"notification":{"default_permission":{"identifier":"default","description":"This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n","permissions":["allow-is-permission-granted","allow-request-permission","allow-notify","allow-register-action-types","allow-register-listener","allow-cancel","allow-get-pending","allow-remove-active","allow-get-active","allow-check-permissions","allow-show","allow-batch","allow-list-channels","allow-delete-channel","allow-create-channel","allow-permission-state"]},"permissions":{"allow-batch":{"identifier":"allow-batch","description":"Enables the batch command without any pre-configured scope.","commands":{"allow":["batch"],"deny":[]}},"allow-cancel":{"identifier":"allow-cancel","description":"Enables the cancel command without any pre-configured scope.","commands":{"allow":["cancel"],"deny":[]}},"allow-check-permissions":{"identifier":"allow-check-permissions","description":"Enables the check_permissions command without any pre-configured scope.","commands":{"allow":["check_permissions"],"deny":[]}},"allow-create-channel":{"identifier":"allow-create-channel","description":"Enables the create_channel command without any pre-configured scope.","commands":{"allow":["create_channel"],"deny":[]}},"allow-delete-channel":{"identifier":"allow-delete-channel","description":"Enables the delete_channel command without any pre-configured scope.","commands":{"allow":["delete_channel"],"deny":[]}},"allow-get-active":{"identifier":"allow-get-active","description":"Enables the get_active command without any pre-configured scope.","commands":{"allow":["get_active"],"deny":[]}},"allow-get-pending":{"identifier":"allow-get-pending","description":"Enables the get_pending command without any pre-configured scope.","commands":{"allow":["get_pending"],"deny":[]}},"allow-is-permission-granted":{"identifier":"allow-is-permission-granted","description":"Enables the is_permission_granted command without any pre-configured scope.","commands":{"allow":["is_permission_granted"],"deny":[]}},"allow-list-channels":{"identifier":"allow-list-channels","description":"Enables the list_channels command without any pre-configured scope.","commands":{"allow":["list_channels"],"deny":[]}},"allow-notify":{"identifier":"allow-notify","description":"Enables the notify command without any pre-configured scope.","commands":{"allow":["notify"],"deny":[]}},"allow-permission-state":{"identifier":"allow-permission-state","description":"Enables the permission_state command without any pre-configured scope.","commands":{"allow":["permission_state"],"deny":[]}},"allow-register-action-types":{"identifier":"allow-register-action-types","description":"Enables the register_action_types command without any pre-configured scope.","commands":{"allow":["register_action_types"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-active":{"identifier":"allow-remove-active","description":"Enables the remove_active command without any pre-configured scope.","commands":{"allow":["remove_active"],"deny":[]}},"allow-request-permission":{"identifier":"allow-request-permission","description":"Enables the request_permission command without any pre-configured scope.","commands":{"allow":["request_permission"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"deny-batch":{"identifier":"deny-batch","description":"Denies the batch command without any pre-configured scope.","commands":{"allow":[],"deny":["batch"]}},"deny-cancel":{"identifier":"deny-cancel","description":"Denies the cancel command without any pre-configured scope.","commands":{"allow":[],"deny":["cancel"]}},"deny-check-permissions":{"identifier":"deny-check-permissions","description":"Denies the check_permissions command without any pre-configured scope.","commands":{"allow":[],"deny":["check_permissions"]}},"deny-create-channel":{"identifier":"deny-create-channel","description":"Denies the create_channel command without any pre-configured scope.","commands":{"allow":[],"deny":["create_channel"]}},"deny-delete-channel":{"identifier":"deny-delete-channel","description":"Denies the delete_channel command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_channel"]}},"deny-get-active":{"identifier":"deny-get-active","description":"Denies the get_active command without any pre-configured scope.","commands":{"allow":[],"deny":["get_active"]}},"deny-get-pending":{"identifier":"deny-get-pending","description":"Denies the get_pending command without any pre-configured scope.","commands":{"allow":[],"deny":["get_pending"]}},"deny-is-permission-granted":{"identifier":"deny-is-permission-granted","description":"Denies the is_permission_granted command without any pre-configured scope.","commands":{"allow":[],"deny":["is_permission_granted"]}},"deny-list-channels":{"identifier":"deny-list-channels","description":"Denies the list_channels command without any pre-configured scope.","commands":{"allow":[],"deny":["list_channels"]}},"deny-notify":{"identifier":"deny-notify","description":"Denies the notify command without any pre-configured scope.","commands":{"allow":[],"deny":["notify"]}},"deny-permission-state":{"identifier":"deny-permission-state","description":"Denies the permission_state command without any pre-configured scope.","commands":{"allow":[],"deny":["permission_state"]}},"deny-register-action-types":{"identifier":"deny-register-action-types","description":"Denies the register_action_types command without any pre-configured scope.","commands":{"allow":[],"deny":["register_action_types"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-active":{"identifier":"deny-remove-active","description":"Denies the remove_active command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_active"]}},"deny-request-permission":{"identifier":"deny-request-permission","description":"Denies the request_permission command without any pre-configured scope.","commands":{"allow":[],"deny":["request_permission"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}}},"permission_sets":{},"global_scope_schema":null},"opener":{"default_permission":{"identifier":"default","description":"This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer","permissions":["allow-open-url","allow-reveal-item-in-dir","allow-default-urls"]},"permissions":{"allow-default-urls":{"identifier":"allow-default-urls","description":"This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"url":"mailto:*"},{"url":"tel:*"},{"url":"http://*"},{"url":"https://*"}]}},"allow-open-path":{"identifier":"allow-open-path","description":"Enables the open_path command without any pre-configured scope.","commands":{"allow":["open_path"],"deny":[]}},"allow-open-url":{"identifier":"allow-open-url","description":"Enables the open_url command without any pre-configured scope.","commands":{"allow":["open_url"],"deny":[]}},"allow-reveal-item-in-dir":{"identifier":"allow-reveal-item-in-dir","description":"Enables the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":["reveal_item_in_dir"],"deny":[]}},"deny-open-path":{"identifier":"deny-open-path","description":"Denies the open_path command without any pre-configured scope.","commands":{"allow":[],"deny":["open_path"]}},"deny-open-url":{"identifier":"deny-open-url","description":"Denies the open_url command without any pre-configured scope.","commands":{"allow":[],"deny":["open_url"]}},"deny-reveal-item-in-dir":{"identifier":"deny-reveal-item-in-dir","description":"Denies the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["reveal_item_in_dir"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this url with, for example: firefox."},"url":{"description":"A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"","type":"string"}},"required":["url"],"type":"object"},{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this path with, for example: xdg-open."},"path":{"description":"A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"definitions":{"Application":{"anyOf":[{"description":"Open in default application.","type":"null"},{"description":"If true, allow open with any application.","type":"boolean"},{"description":"Allow specific application to open with.","type":"string"}],"description":"Opener scope application."}},"description":"Opener scope entry.","title":"OpenerScopeEntry"}}} \ No newline at end of file diff --git a/packages/tauri-app/src-tauri/gen/schemas/capabilities.json b/packages/tauri-app/src-tauri/gen/schemas/capabilities.json index 1e38e0c9..7a9624eb 100644 --- a/packages/tauri-app/src-tauri/gen/schemas/capabilities.json +++ b/packages/tauri-app/src-tauri/gen/schemas/capabilities.json @@ -1 +1 @@ -{"main-window-native-dialogs":{"identifier":"main-window-native-dialogs","description":"Grant the main window access to required core features and native dialog commands.","remote":{"urls":["http://127.0.0.1:*","http://localhost:*","http://tauri.localhost/*","https://tauri.localhost/*"]},"local":true,"windows":["main"],"permissions":["core:default","core:menu:default","dialog:allow-open","opener:allow-default-urls","core:webview:allow-set-webview-zoom"]}} \ No newline at end of file +{"main-window-native-dialogs":{"identifier":"main-window-native-dialogs","description":"Grant the main window access to required core features and native dialog commands.","remote":{"urls":["http://127.0.0.1:*","http://localhost:*","http://tauri.localhost/*","https://tauri.localhost/*"]},"local":true,"windows":["main"],"permissions":["core:default","core:menu:default","dialog:allow-open","opener:allow-default-urls","notification:allow-is-permission-granted","notification:allow-request-permission","notification:allow-notify","notification:allow-show","core:webview:allow-set-webview-zoom"]}} \ No newline at end of file diff --git a/packages/tauri-app/src-tauri/gen/schemas/desktop-schema.json b/packages/tauri-app/src-tauri/gen/schemas/desktop-schema.json index 344faff7..12530aa5 100644 --- a/packages/tauri-app/src-tauri/gen/schemas/desktop-schema.json +++ b/packages/tauri-app/src-tauri/gen/schemas/desktop-schema.json @@ -2378,6 +2378,234 @@ "const": "dialog:deny-save", "markdownDescription": "Denies the save command without any pre-configured scope." }, + { + "description": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-start`\n- `allow-stop`", + "type": "string", + "const": "keepawake:default", + "markdownDescription": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-start`\n- `allow-stop`" + }, + { + "description": "Enables the start command without any pre-configured scope.", + "type": "string", + "const": "keepawake:allow-start", + "markdownDescription": "Enables the start command without any pre-configured scope." + }, + { + "description": "Enables the stop command without any pre-configured scope.", + "type": "string", + "const": "keepawake:allow-stop", + "markdownDescription": "Enables the stop command without any pre-configured scope." + }, + { + "description": "Denies the start command without any pre-configured scope.", + "type": "string", + "const": "keepawake:deny-start", + "markdownDescription": "Denies the start command without any pre-configured scope." + }, + { + "description": "Denies the stop command without any pre-configured scope.", + "type": "string", + "const": "keepawake:deny-stop", + "markdownDescription": "Denies the stop command without any pre-configured scope." + }, + { + "description": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n\n#### This default permission set includes:\n\n- `allow-is-permission-granted`\n- `allow-request-permission`\n- `allow-notify`\n- `allow-register-action-types`\n- `allow-register-listener`\n- `allow-cancel`\n- `allow-get-pending`\n- `allow-remove-active`\n- `allow-get-active`\n- `allow-check-permissions`\n- `allow-show`\n- `allow-batch`\n- `allow-list-channels`\n- `allow-delete-channel`\n- `allow-create-channel`\n- `allow-permission-state`", + "type": "string", + "const": "notification:default", + "markdownDescription": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n\n#### This default permission set includes:\n\n- `allow-is-permission-granted`\n- `allow-request-permission`\n- `allow-notify`\n- `allow-register-action-types`\n- `allow-register-listener`\n- `allow-cancel`\n- `allow-get-pending`\n- `allow-remove-active`\n- `allow-get-active`\n- `allow-check-permissions`\n- `allow-show`\n- `allow-batch`\n- `allow-list-channels`\n- `allow-delete-channel`\n- `allow-create-channel`\n- `allow-permission-state`" + }, + { + "description": "Enables the batch command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-batch", + "markdownDescription": "Enables the batch command without any pre-configured scope." + }, + { + "description": "Enables the cancel command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-cancel", + "markdownDescription": "Enables the cancel command without any pre-configured scope." + }, + { + "description": "Enables the check_permissions command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-check-permissions", + "markdownDescription": "Enables the check_permissions command without any pre-configured scope." + }, + { + "description": "Enables the create_channel command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-create-channel", + "markdownDescription": "Enables the create_channel command without any pre-configured scope." + }, + { + "description": "Enables the delete_channel command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-delete-channel", + "markdownDescription": "Enables the delete_channel command without any pre-configured scope." + }, + { + "description": "Enables the get_active command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-get-active", + "markdownDescription": "Enables the get_active command without any pre-configured scope." + }, + { + "description": "Enables the get_pending command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-get-pending", + "markdownDescription": "Enables the get_pending command without any pre-configured scope." + }, + { + "description": "Enables the is_permission_granted command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-is-permission-granted", + "markdownDescription": "Enables the is_permission_granted command without any pre-configured scope." + }, + { + "description": "Enables the list_channels command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-list-channels", + "markdownDescription": "Enables the list_channels command without any pre-configured scope." + }, + { + "description": "Enables the notify command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-notify", + "markdownDescription": "Enables the notify command without any pre-configured scope." + }, + { + "description": "Enables the permission_state command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-permission-state", + "markdownDescription": "Enables the permission_state command without any pre-configured scope." + }, + { + "description": "Enables the register_action_types command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-register-action-types", + "markdownDescription": "Enables the register_action_types command without any pre-configured scope." + }, + { + "description": "Enables the register_listener command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-register-listener", + "markdownDescription": "Enables the register_listener command without any pre-configured scope." + }, + { + "description": "Enables the remove_active command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-remove-active", + "markdownDescription": "Enables the remove_active command without any pre-configured scope." + }, + { + "description": "Enables the request_permission command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-request-permission", + "markdownDescription": "Enables the request_permission command without any pre-configured scope." + }, + { + "description": "Enables the show command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-show", + "markdownDescription": "Enables the show command without any pre-configured scope." + }, + { + "description": "Denies the batch command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-batch", + "markdownDescription": "Denies the batch command without any pre-configured scope." + }, + { + "description": "Denies the cancel command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-cancel", + "markdownDescription": "Denies the cancel command without any pre-configured scope." + }, + { + "description": "Denies the check_permissions command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-check-permissions", + "markdownDescription": "Denies the check_permissions command without any pre-configured scope." + }, + { + "description": "Denies the create_channel command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-create-channel", + "markdownDescription": "Denies the create_channel command without any pre-configured scope." + }, + { + "description": "Denies the delete_channel command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-delete-channel", + "markdownDescription": "Denies the delete_channel command without any pre-configured scope." + }, + { + "description": "Denies the get_active command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-get-active", + "markdownDescription": "Denies the get_active command without any pre-configured scope." + }, + { + "description": "Denies the get_pending command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-get-pending", + "markdownDescription": "Denies the get_pending command without any pre-configured scope." + }, + { + "description": "Denies the is_permission_granted command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-is-permission-granted", + "markdownDescription": "Denies the is_permission_granted command without any pre-configured scope." + }, + { + "description": "Denies the list_channels command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-list-channels", + "markdownDescription": "Denies the list_channels command without any pre-configured scope." + }, + { + "description": "Denies the notify command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-notify", + "markdownDescription": "Denies the notify command without any pre-configured scope." + }, + { + "description": "Denies the permission_state command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-permission-state", + "markdownDescription": "Denies the permission_state command without any pre-configured scope." + }, + { + "description": "Denies the register_action_types command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-register-action-types", + "markdownDescription": "Denies the register_action_types command without any pre-configured scope." + }, + { + "description": "Denies the register_listener command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-register-listener", + "markdownDescription": "Denies the register_listener command without any pre-configured scope." + }, + { + "description": "Denies the remove_active command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-remove-active", + "markdownDescription": "Denies the remove_active command without any pre-configured scope." + }, + { + "description": "Denies the request_permission command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-request-permission", + "markdownDescription": "Denies the request_permission command without any pre-configured scope." + }, + { + "description": "Denies the show command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-show", + "markdownDescription": "Denies the show command without any pre-configured scope." + }, { "description": "This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer\n#### This default permission set includes:\n\n- `allow-open-url`\n- `allow-reveal-item-in-dir`\n- `allow-default-urls`", "type": "string", diff --git a/packages/tauri-app/src-tauri/gen/schemas/macOS-schema.json b/packages/tauri-app/src-tauri/gen/schemas/macOS-schema.json index 344faff7..12530aa5 100644 --- a/packages/tauri-app/src-tauri/gen/schemas/macOS-schema.json +++ b/packages/tauri-app/src-tauri/gen/schemas/macOS-schema.json @@ -2378,6 +2378,234 @@ "const": "dialog:deny-save", "markdownDescription": "Denies the save command without any pre-configured scope." }, + { + "description": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-start`\n- `allow-stop`", + "type": "string", + "const": "keepawake:default", + "markdownDescription": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-start`\n- `allow-stop`" + }, + { + "description": "Enables the start command without any pre-configured scope.", + "type": "string", + "const": "keepawake:allow-start", + "markdownDescription": "Enables the start command without any pre-configured scope." + }, + { + "description": "Enables the stop command without any pre-configured scope.", + "type": "string", + "const": "keepawake:allow-stop", + "markdownDescription": "Enables the stop command without any pre-configured scope." + }, + { + "description": "Denies the start command without any pre-configured scope.", + "type": "string", + "const": "keepawake:deny-start", + "markdownDescription": "Denies the start command without any pre-configured scope." + }, + { + "description": "Denies the stop command without any pre-configured scope.", + "type": "string", + "const": "keepawake:deny-stop", + "markdownDescription": "Denies the stop command without any pre-configured scope." + }, + { + "description": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n\n#### This default permission set includes:\n\n- `allow-is-permission-granted`\n- `allow-request-permission`\n- `allow-notify`\n- `allow-register-action-types`\n- `allow-register-listener`\n- `allow-cancel`\n- `allow-get-pending`\n- `allow-remove-active`\n- `allow-get-active`\n- `allow-check-permissions`\n- `allow-show`\n- `allow-batch`\n- `allow-list-channels`\n- `allow-delete-channel`\n- `allow-create-channel`\n- `allow-permission-state`", + "type": "string", + "const": "notification:default", + "markdownDescription": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n\n#### This default permission set includes:\n\n- `allow-is-permission-granted`\n- `allow-request-permission`\n- `allow-notify`\n- `allow-register-action-types`\n- `allow-register-listener`\n- `allow-cancel`\n- `allow-get-pending`\n- `allow-remove-active`\n- `allow-get-active`\n- `allow-check-permissions`\n- `allow-show`\n- `allow-batch`\n- `allow-list-channels`\n- `allow-delete-channel`\n- `allow-create-channel`\n- `allow-permission-state`" + }, + { + "description": "Enables the batch command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-batch", + "markdownDescription": "Enables the batch command without any pre-configured scope." + }, + { + "description": "Enables the cancel command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-cancel", + "markdownDescription": "Enables the cancel command without any pre-configured scope." + }, + { + "description": "Enables the check_permissions command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-check-permissions", + "markdownDescription": "Enables the check_permissions command without any pre-configured scope." + }, + { + "description": "Enables the create_channel command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-create-channel", + "markdownDescription": "Enables the create_channel command without any pre-configured scope." + }, + { + "description": "Enables the delete_channel command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-delete-channel", + "markdownDescription": "Enables the delete_channel command without any pre-configured scope." + }, + { + "description": "Enables the get_active command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-get-active", + "markdownDescription": "Enables the get_active command without any pre-configured scope." + }, + { + "description": "Enables the get_pending command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-get-pending", + "markdownDescription": "Enables the get_pending command without any pre-configured scope." + }, + { + "description": "Enables the is_permission_granted command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-is-permission-granted", + "markdownDescription": "Enables the is_permission_granted command without any pre-configured scope." + }, + { + "description": "Enables the list_channels command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-list-channels", + "markdownDescription": "Enables the list_channels command without any pre-configured scope." + }, + { + "description": "Enables the notify command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-notify", + "markdownDescription": "Enables the notify command without any pre-configured scope." + }, + { + "description": "Enables the permission_state command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-permission-state", + "markdownDescription": "Enables the permission_state command without any pre-configured scope." + }, + { + "description": "Enables the register_action_types command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-register-action-types", + "markdownDescription": "Enables the register_action_types command without any pre-configured scope." + }, + { + "description": "Enables the register_listener command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-register-listener", + "markdownDescription": "Enables the register_listener command without any pre-configured scope." + }, + { + "description": "Enables the remove_active command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-remove-active", + "markdownDescription": "Enables the remove_active command without any pre-configured scope." + }, + { + "description": "Enables the request_permission command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-request-permission", + "markdownDescription": "Enables the request_permission command without any pre-configured scope." + }, + { + "description": "Enables the show command without any pre-configured scope.", + "type": "string", + "const": "notification:allow-show", + "markdownDescription": "Enables the show command without any pre-configured scope." + }, + { + "description": "Denies the batch command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-batch", + "markdownDescription": "Denies the batch command without any pre-configured scope." + }, + { + "description": "Denies the cancel command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-cancel", + "markdownDescription": "Denies the cancel command without any pre-configured scope." + }, + { + "description": "Denies the check_permissions command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-check-permissions", + "markdownDescription": "Denies the check_permissions command without any pre-configured scope." + }, + { + "description": "Denies the create_channel command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-create-channel", + "markdownDescription": "Denies the create_channel command without any pre-configured scope." + }, + { + "description": "Denies the delete_channel command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-delete-channel", + "markdownDescription": "Denies the delete_channel command without any pre-configured scope." + }, + { + "description": "Denies the get_active command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-get-active", + "markdownDescription": "Denies the get_active command without any pre-configured scope." + }, + { + "description": "Denies the get_pending command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-get-pending", + "markdownDescription": "Denies the get_pending command without any pre-configured scope." + }, + { + "description": "Denies the is_permission_granted command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-is-permission-granted", + "markdownDescription": "Denies the is_permission_granted command without any pre-configured scope." + }, + { + "description": "Denies the list_channels command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-list-channels", + "markdownDescription": "Denies the list_channels command without any pre-configured scope." + }, + { + "description": "Denies the notify command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-notify", + "markdownDescription": "Denies the notify command without any pre-configured scope." + }, + { + "description": "Denies the permission_state command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-permission-state", + "markdownDescription": "Denies the permission_state command without any pre-configured scope." + }, + { + "description": "Denies the register_action_types command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-register-action-types", + "markdownDescription": "Denies the register_action_types command without any pre-configured scope." + }, + { + "description": "Denies the register_listener command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-register-listener", + "markdownDescription": "Denies the register_listener command without any pre-configured scope." + }, + { + "description": "Denies the remove_active command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-remove-active", + "markdownDescription": "Denies the remove_active command without any pre-configured scope." + }, + { + "description": "Denies the request_permission command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-request-permission", + "markdownDescription": "Denies the request_permission command without any pre-configured scope." + }, + { + "description": "Denies the show command without any pre-configured scope.", + "type": "string", + "const": "notification:deny-show", + "markdownDescription": "Denies the show command without any pre-configured scope." + }, { "description": "This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer\n#### This default permission set includes:\n\n- `allow-open-url`\n- `allow-reveal-item-in-dir`\n- `allow-default-urls`", "type": "string", diff --git a/packages/tauri-app/src-tauri/src/cli_manager.rs b/packages/tauri-app/src-tauri/src/cli_manager.rs index 3656277c..ad0860f9 100644 --- a/packages/tauri-app/src-tauri/src/cli_manager.rs +++ b/packages/tauri-app/src-tauri/src/cli_manager.rs @@ -145,12 +145,33 @@ struct AppConfig { preferences: Option, } -fn resolve_config_path() -> PathBuf { +fn resolve_config_locations() -> (PathBuf, PathBuf) { let raw = env::var("CLI_CONFIG") .ok() .filter(|value| !value.trim().is_empty()) .unwrap_or_else(|| DEFAULT_CONFIG_PATH.to_string()); - expand_home(&raw) + + let expanded = expand_home(&raw); + let lower = raw.trim().to_lowercase(); + + if lower.ends_with(".yaml") || lower.ends_with(".yml") { + let base = expanded + .parent() + .map(|p| p.to_path_buf()) + .unwrap_or_else(|| expanded.clone()); + return (expanded, base.join("config.json")); + } + + if lower.ends_with(".json") { + let base = expanded + .parent() + .map(|p| p.to_path_buf()) + .unwrap_or_else(|| expanded.clone()); + return (base.join("config.yaml"), expanded); + } + + // Treat as directory. + (expanded.join("config.yaml"), expanded.join("config.json")) } fn expand_home(path: &str) -> PathBuf { @@ -163,8 +184,27 @@ fn expand_home(path: &str) -> PathBuf { } fn resolve_listening_mode() -> String { - let path = resolve_config_path(); - if let Ok(content) = fs::read_to_string(path) { + let (yaml_path, json_path) = resolve_config_locations(); + + if let Ok(content) = fs::read_to_string(&yaml_path) { + if let Ok(config) = serde_yaml::from_str::(&content) { + if let Some(mode) = config + .preferences + .as_ref() + .and_then(|prefs| prefs.listening_mode.as_ref()) + { + if mode == "local" { + return "local".to_string(); + } + if mode == "all" { + return "all".to_string(); + } + } + } + } + + // Legacy fallback. + if let Ok(content) = fs::read_to_string(&json_path) { if let Ok(config) = serde_json::from_str::(&content) { if let Some(mode) = config .preferences @@ -260,7 +300,14 @@ impl CliProcessManager { let ready_flag = self.ready.clone(); let token_arc = self.bootstrap_token.clone(); thread::spawn(move || { - if let Err(err) = Self::spawn_cli(app.clone(), status_arc.clone(), child_arc, ready_flag, token_arc, dev) { + if let Err(err) = Self::spawn_cli( + app.clone(), + status_arc.clone(), + child_arc, + ready_flag, + token_arc, + dev, + ) { log_line(&format!("cli spawn failed: {err}")); let mut locked = status_arc.lock(); locked.state = CliState::Error; @@ -369,7 +416,9 @@ impl CliProcessManager { if !supports_user_shell() { if which::which(&resolution.node_binary).is_err() { - return Err(anyhow::anyhow!("Node binary not found. Make sure Node.js is installed.")); + return Err(anyhow::anyhow!( + "Node binary not found. Make sure Node.js is installed." + )); } } @@ -420,7 +469,6 @@ impl CliProcessManager { let token_clone = bootstrap_token.clone(); thread::spawn(move || { - let stdout = child_clone .lock() .as_mut() @@ -433,10 +481,24 @@ impl CliProcessManager { .map(BufReader::new); if let Some(reader) = stdout { - Self::process_stream(reader, "stdout", &app_clone, &status_clone, &ready_clone, &token_clone); + Self::process_stream( + reader, + "stdout", + &app_clone, + &status_clone, + &ready_clone, + &token_clone, + ); } if let Some(reader) = stderr { - Self::process_stream(reader, "stderr", &app_clone, &status_clone, &ready_clone, &token_clone); + Self::process_stream( + reader, + "stderr", + &app_clone, + &status_clone, + &ready_clone, + &token_clone, + ); } }); @@ -509,8 +571,14 @@ impl CliProcessManager { if locked.error.is_none() { locked.error = err_msg.clone(); } - log_line(&format!("cli process exited before ready: {:?}", locked.error)); - let _ = app_clone.emit("cli:error", json!({"message": locked.error.clone().unwrap_or_default()})); + log_line(&format!( + "cli process exited before ready: {:?}", + locked.error + )); + let _ = app_clone.emit( + "cli:error", + json!({"message": locked.error.clone().unwrap_or_default()}), + ); } else { locked.state = CliState::Stopped; log_line("cli process stopped cleanly"); @@ -531,7 +599,7 @@ impl CliProcessManager { bootstrap_token: &Arc>>, ) { let mut buffer = String::new(); - let port_regex = Regex::new(r"CodeNomad Server is ready at http://[^:]+:(\d+)").ok(); + let local_url_regex = Regex::new(r"^Local\s+Connection\s+URL\s*:\s*(https?://\S+)").ok(); let http_regex = Regex::new(r":(\d{2,5})(?!.*:\d)").ok(); let token_prefix = "CODENOMAD_BOOTSTRAP_TOKEN:"; @@ -559,12 +627,12 @@ impl CliProcessManager { continue; } - if let Some(port) = port_regex + if let Some(url) = local_url_regex .as_ref() .and_then(|re| re.captures(line).and_then(|c| c.get(1))) - .and_then(|m| m.as_str().parse::().ok()) + .map(|m| m.as_str().to_string()) { - Self::mark_ready(app, status, ready, bootstrap_token, port); + Self::mark_ready(app, status, ready, bootstrap_token, url); continue; } @@ -574,13 +642,25 @@ impl CliProcessManager { .and_then(|re| re.captures(line).and_then(|c| c.get(1))) .and_then(|m| m.as_str().parse::().ok()) { - Self::mark_ready(app, status, ready, bootstrap_token, port); + Self::mark_ready( + app, + status, + ready, + bootstrap_token, + format!("http://localhost:{port}"), + ); continue; } if let Ok(value) = serde_json::from_str::(line) { if let Some(port) = value.get("port").and_then(|p| p.as_u64()) { - Self::mark_ready(app, status, ready, bootstrap_token, port as u16); + Self::mark_ready( + app, + status, + ready, + bootstrap_token, + format!("http://localhost:{}", port), + ); continue; } } @@ -597,12 +677,15 @@ impl CliProcessManager { status: &Arc>, ready: &Arc, bootstrap_token: &Arc>>, - port: u16, + base_url: String, ) { ready.store(true, Ordering::SeqCst); - let base_url = format!("http://127.0.0.1:{port}"); + let port = Url::parse(&base_url) + .ok() + .and_then(|u| u.port_or_known_default()) + .map(|p| p as u16); let mut locked = status.lock(); - locked.port = Some(port); + locked.port = port; locked.url = Some(base_url.clone()); locked.state = CliState::Ready; locked.error = None; @@ -611,22 +694,29 @@ impl CliProcessManager { let token = bootstrap_token.lock().take(); if let Some(token) = token { - match exchange_bootstrap_token(&base_url, &token) { - Ok(Some(session_id)) => { - if let Err(err) = set_session_cookie(app, &base_url, &session_id) { - log_line(&format!("failed to set session cookie: {err}")); + // Token exchange is only implemented for loopback HTTP. If localUrl is HTTPS, + // skip the exchange and let the user authenticate normally. + let scheme = Url::parse(&base_url).ok().map(|u| u.scheme().to_string()); + if scheme.as_deref() != Some("http") { + navigate_main(app, &base_url); + } else { + match exchange_bootstrap_token(&base_url, &token) { + Ok(Some(session_id)) => { + if let Err(err) = set_session_cookie(app, &base_url, &session_id) { + log_line(&format!("failed to set session cookie: {err}")); + navigate_main(app, &format!("{base_url}/login")); + } else { + navigate_main(app, &base_url); + } + } + Ok(None) => { + log_line("bootstrap token exchange failed (invalid token)"); + navigate_main(app, &format!("{base_url}/login")); + } + Err(err) => { + log_line(&format!("bootstrap token exchange failed: {err}")); navigate_main(app, &format!("{base_url}/login")); - } else { - navigate_main(app, &base_url); } - } - Ok(None) => { - log_line("bootstrap token exchange failed (invalid token)"); - navigate_main(app, &format!("{base_url}/login")); - } - Err(err) => { - log_line(&format!("bootstrap token exchange failed: {err}")); - navigate_main(app, &format!("{base_url}/login")); } } } else { @@ -713,15 +803,25 @@ impl CliEntry { "serve".to_string(), "--host".to_string(), host.to_string(), - "--port".to_string(), - "0".to_string(), "--generate-token".to_string(), ]; + if dev { + // Dev: plain HTTP + Vite dev server proxy. + args.push("--https".to_string()); + args.push("false".to_string()); + args.push("--http".to_string()); + args.push("true".to_string()); args.push("--ui-dev-server".to_string()); args.push("http://localhost:3000".to_string()); args.push("--log-level".to_string()); args.push("debug".to_string()); + } else { + // Prod desktop: always keep loopback HTTP enabled. + args.push("--https".to_string()); + args.push("true".to_string()); + args.push("--http".to_string()); + args.push("true".to_string()); } args } @@ -746,9 +846,10 @@ fn resolve_tsx(_app: &AppHandle) -> Option { std::env::current_dir() .ok() .map(|p| p.join("node_modules/tsx/dist/cli.js")), - std::env::current_exe() - .ok() - .and_then(|ex| ex.parent().map(|p| p.join("../node_modules/tsx/dist/cli.js"))), + std::env::current_exe().ok().and_then(|ex| { + ex.parent() + .map(|p| p.join("../node_modules/tsx/dist/cli.js")) + }), ]; first_existing(candidates) @@ -771,7 +872,8 @@ fn resolve_dist_entry(_app: &AppHandle) -> Option { let base = workspace_root(); let mut candidates: Vec> = vec![ base.as_ref().map(|p| p.join("packages/server/dist/bin.js")), - base.as_ref().map(|p| p.join("packages/server/dist/index.js")), + base.as_ref() + .map(|p| p.join("packages/server/dist/index.js")), base.as_ref().map(|p| p.join("server/dist/bin.js")), base.as_ref().map(|p| p.join("server/dist/index.js")), ]; @@ -786,7 +888,9 @@ fn resolve_dist_entry(_app: &AppHandle) -> Option { candidates.push(Some(resources.join("resources/server/dist/bin.js"))); candidates.push(Some(resources.join("resources/server/dist/index.js"))); candidates.push(Some(resources.join("resources/server/dist/server/bin.js"))); - candidates.push(Some(resources.join("resources/server/dist/server/index.js"))); + candidates.push(Some( + resources.join("resources/server/dist/server/index.js"), + )); let linux_resource_roots = [dir.join("../lib/CodeNomad"), dir.join("../lib/codenomad")]; for root in linux_resource_roots { @@ -805,8 +909,10 @@ fn resolve_dist_entry(_app: &AppHandle) -> Option { first_existing(candidates) } -fn build_shell_command_string(entry: &CliEntry, cli_args: &[String]) -> anyhow::Result { - +fn build_shell_command_string( + entry: &CliEntry, + cli_args: &[String], +) -> anyhow::Result { let shell = default_shell(); let mut quoted: Vec = Vec::new(); quoted.push(shell_escape(&entry.node_binary)); @@ -837,7 +943,7 @@ fn shell_escape(input: &str) -> String { "''".to_string() } else if !input .chars() - .any(|c| matches!(c, ' ' | '"' | '\'' | '$' | '`' | '!' )) + .any(|c| matches!(c, ' ' | '"' | '\'' | '$' | '`' | '!')) { input.to_string() } else { diff --git a/packages/tauri-app/src-tauri/src/main.rs b/packages/tauri-app/src-tauri/src/main.rs index 6cc35251..06505675 100644 --- a/packages/tauri-app/src-tauri/src/main.rs +++ b/packages/tauri-app/src-tauri/src/main.rs @@ -35,6 +35,7 @@ fn cli_restart(app: AppHandle, state: tauri::State) -> Result bool { cfg!(debug_assertions) || std::env::var("TAURI_DEV").is_ok() } @@ -73,6 +74,8 @@ fn main() { tauri::Builder::default() .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_opener::init()) + .plugin(tauri_plugin_keepawake::init()) + .plugin(tauri_plugin_notification::init()) .plugin(navigation_guard) .manage(AppState { manager: CliProcessManager::new(), diff --git a/packages/ui/.gitignore b/packages/ui/.gitignore index 1761634c..4e2f7f13 100644 --- a/packages/ui/.gitignore +++ b/packages/ui/.gitignore @@ -2,3 +2,4 @@ node_modules/ dist/ .vite/ src/renderer/public/logo.png +src/renderer/public/monaco/ diff --git a/packages/ui/package.json b/packages/ui/package.json index d09a3016..d171a4e6 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@codenomad/ui", - "version": "0.9.5", + "version": "0.10.3", "private": true, "license": "MIT", "type": "module", @@ -8,9 +8,13 @@ "dev": "vite dev", "build": "vite build", "preview": "vite preview", - "typecheck": "tsc --noEmit -p tsconfig.json" + "typecheck": "tsc --noEmit -p tsconfig.json", + "test": "vitest run", + "test:watch": "vitest", + "test:ui": "vitest --ui" }, "dependencies": { + "@fastify/reply-from": "12.5.0", "@git-diff-view/solid": "^0.0.8", "@kobalte/core": "0.13.11", "@opencode-ai/sdk": "1.1.11", @@ -18,25 +22,33 @@ "@suid/icons-material": "^0.9.0", "@suid/material": "^0.19.0", "@suid/system": "^0.14.0", + "@types/dompurify": "^3.0.5", "@tauri-apps/plugin-opener": "^2.5.3", + "@tauri-apps/plugin-notification": "^2.3.3", "ansi-sequence-parser": "^1.1.3", "debug": "^4.4.3", + "dompurify": "^3.3.1", "github-markdown-css": "^5.8.1", "lucide-solid": "^0.300.0", "marked": "^12.0.0", + "monaco-editor": "^0.52.2", "qrcode": "^1.5.3", "shiki": "^3.13.0", "solid-js": "^1.8.0", - "solid-toast": "^0.5.0" + "solid-toast": "^0.5.0", + "ts-node": "1.7.1", + "tauri-plugin-keepawake-api": "^0.1.0" }, "devDependencies": { "@vite-pwa/assets-generator": "^1.0.2", "autoprefixer": "10.4.21", + "jsdom": "^25.0.1", "postcss": "8.5.6", "tailwindcss": "3", "typescript": "^5.3.0", - "vite": "^5.0.0", + "vite": "^7.3.1", "vite-plugin-pwa": "^1.2.0", - "vite-plugin-solid": "^2.10.0" + "vite-plugin-solid": "^2.10.0", + "vitest": "^2.1.9" } } diff --git a/packages/ui/pnpm-lock.yaml b/packages/ui/pnpm-lock.yaml new file mode 100644 index 00000000..19afbdca --- /dev/null +++ b/packages/ui/pnpm-lock.yaml @@ -0,0 +1,2702 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@git-diff-view/solid': + specifier: ^0.0.8 + version: 0.0.8(react@19.2.3)(solid-js@1.9.10) + '@kobalte/core': + specifier: 0.13.11 + version: 0.13.11(solid-js@1.9.10) + '@opencode-ai/sdk': + specifier: 1.1.12 + version: 1.1.12 + '@solidjs/router': + specifier: ^0.13.0 + version: 0.13.6(solid-js@1.9.10) + '@suid/icons-material': + specifier: ^0.9.0 + version: 0.9.0(solid-js@1.9.10) + '@suid/material': + specifier: ^0.19.0 + version: 0.19.0(solid-js@1.9.10) + '@suid/system': + specifier: ^0.14.0 + version: 0.14.0(solid-js@1.9.10) + ansi-sequence-parser: + specifier: ^1.1.3 + version: 1.1.3 + debug: + specifier: ^4.4.3 + version: 4.4.3 + github-markdown-css: + specifier: ^5.8.1 + version: 5.8.1 + lucide-solid: + specifier: ^0.300.0 + version: 0.300.0(solid-js@1.9.10) + marked: + specifier: ^12.0.0 + version: 12.0.2 + qrcode: + specifier: ^1.5.3 + version: 1.5.4 + shiki: + specifier: ^3.13.0 + version: 3.21.0 + solid-js: + specifier: ^1.8.0 + version: 1.9.10 + solid-toast: + specifier: ^0.5.0 + version: 0.5.0(solid-js@1.9.10) + devDependencies: + autoprefixer: + specifier: 10.4.21 + version: 10.4.21(postcss@8.5.6) + postcss: + specifier: 8.5.6 + version: 8.5.6 + tailwindcss: + specifier: '3' + version: 3.4.19 + typescript: + specifier: ^5.3.0 + version: 5.9.3 + vite: + specifier: ^5.0.0 + version: 5.4.21 + vite-plugin-solid: + specifier: ^2.10.0 + version: 2.11.10(solid-js@1.9.10)(vite@5.4.21) + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.18.6': + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@corvu/utils@0.4.2': + resolution: {integrity: sha512-Ox2kYyxy7NoXdKWdHeDEjZxClwzO4SKM8plAaVwmAJPxHMqA0rLOoAsa+hBDwRLpctf+ZRnAd/ykguuJidnaTA==} + peerDependencies: + solid-js: ^1.8 + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + + '@git-diff-view/core@0.0.35': + resolution: {integrity: sha512-cdH3BopR6AWUW+6hP78zGyryKxR9JkPgryd1JN78i5k+F9Eo4x/4S23ZF1VZnrpPlGLrSuYfiAZ0ho5m+pTuKg==} + + '@git-diff-view/lowlight@0.0.35': + resolution: {integrity: sha512-MVpOxrNn1oHVOTOWUjxLbbf1W4OtVHjj6CHxwJbBRg9ZWZdShBINjuEgHVMSGB6vZuHKfwruRfXw8XxV3aF8zw==} + + '@git-diff-view/solid@0.0.8': + resolution: {integrity: sha512-MvZpyV5Gz0Axv2vvAlPpOmHtaJRUGBMoqXmvjIdZlUls0091QsglpE8bMbdRdEHuXodzxPDYyZrx3HCniMlGKw==} + peerDependencies: + solid-js: ^1.9.0 + + '@internationalized/date@3.10.1': + resolution: {integrity: sha512-oJrXtQiAXLvT9clCf1K4kxp3eKsQhIaZqxEyowkBcsvZDdZkbWrVmnGknxs5flTD0VGsxrxKgBCZty1EzoiMzA==} + + '@internationalized/number@3.6.5': + resolution: {integrity: sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@kobalte/core@0.13.11': + resolution: {integrity: sha512-hK7TYpdib/XDb/r/4XDBFaO9O+3ZHz4ZWryV4/3BfES+tSQVgg2IJupDnztKXB0BqbSRy/aWlHKw1SPtNPYCFQ==} + peerDependencies: + solid-js: ^1.8.15 + + '@kobalte/utils@0.9.1': + resolution: {integrity: sha512-eeU60A3kprIiBDAfv9gUJX1tXGLuZiKMajUfSQURAF2pk4ZoMYiqIzmrMBvzcxP39xnYttgTyQEVLwiTZnrV4w==} + peerDependencies: + solid-js: ^1.8.8 + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@opencode-ai/sdk@1.1.12': + resolution: {integrity: sha512-M1c+525865g2C03iKaMdx3aUVC7oZSNbBGaTDjUN2UTIakdxqKHog0Hd8IA9WL8M0aU1QJ8+CnpvRT2Jt9kRNw==} + + '@popperjs/core@2.11.8': + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + + '@rollup/rollup-android-arm-eabi@4.55.1': + resolution: {integrity: sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.55.1': + resolution: {integrity: sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.55.1': + resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.55.1': + resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.55.1': + resolution: {integrity: sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.55.1': + resolution: {integrity: sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.55.1': + resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.55.1': + resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.55.1': + resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.55.1': + resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.55.1': + resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.55.1': + resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.55.1': + resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.55.1': + resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.55.1': + resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.55.1': + resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.55.1': + resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.55.1': + resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.55.1': + resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.55.1': + resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.55.1': + resolution: {integrity: sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.55.1': + resolution: {integrity: sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.55.1': + resolution: {integrity: sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.55.1': + resolution: {integrity: sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.55.1': + resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==} + cpu: [x64] + os: [win32] + + '@shikijs/core@3.21.0': + resolution: {integrity: sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA==} + + '@shikijs/engine-javascript@3.21.0': + resolution: {integrity: sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ==} + + '@shikijs/engine-oniguruma@3.21.0': + resolution: {integrity: sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==} + + '@shikijs/langs@3.21.0': + resolution: {integrity: sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==} + + '@shikijs/themes@3.21.0': + resolution: {integrity: sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==} + + '@shikijs/types@3.21.0': + resolution: {integrity: sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@solid-primitives/event-listener@2.4.3': + resolution: {integrity: sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/keyed@1.5.2': + resolution: {integrity: sha512-BgoEdqPw48URnI+L5sZIHdF4ua4Las1eWEBBPaoSFs42kkhnHue+rwCBPL2Z9ebOyQ75sUhUfOETdJfmv0D6Kg==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/map@0.4.13': + resolution: {integrity: sha512-B1zyFbsiTQvqPr+cuPCXO72sRuczG9Swncqk5P74NCGw1VE8qa/Ry9GlfI1e/VdeQYHjan+XkbE3rO2GW/qKew==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/media@2.3.3': + resolution: {integrity: sha512-hQ4hLOGvfbugQi5Eu1BFWAIJGIAzztq9x0h02xgBGl2l0Jaa3h7tg6bz5tV1NSuNYVGio4rPoa7zVQQLkkx9dA==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/props@3.2.2': + resolution: {integrity: sha512-lZOTwFJajBrshSyg14nBMEP0h8MXzPowGO0s3OeiR3z6nXHTfj0FhzDtJMv+VYoRJKQHG2QRnJTgCzK6erARAw==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/refs@1.1.2': + resolution: {integrity: sha512-K7tf2thy7L+YJjdqXspXOg5xvNEOH8tgEWsp0+1mQk3obHBRD6hEjYZk7p7FlJphSZImS35je3UfmWuD7MhDfg==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/resize-observer@2.1.3': + resolution: {integrity: sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/rootless@1.5.2': + resolution: {integrity: sha512-9HULb0QAzL2r47CCad0M+NKFtQ+LrGGNHZfteX/ThdGvKIg2o2GYhBooZubTCd/RTu2l2+Nw4s+dEfiDGvdrrQ==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/static-store@0.1.2': + resolution: {integrity: sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/trigger@1.2.2': + resolution: {integrity: sha512-IWoptVc0SWYgmpBPpCMehS5b07+tpFcvw15tOQ3QbXedSYn6KP8zCjPkHNzMxcOvOicTneleeZDP7lqmz+PQ6g==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/utils@6.3.2': + resolution: {integrity: sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ==} + peerDependencies: + solid-js: ^1.6.12 + + '@solidjs/router@0.13.6': + resolution: {integrity: sha512-CdpFsBYoiJ/FQ4wZIamj3KEFRkmrYu5sVXM6PouNkmSENta1YJamsm9wa/VjaPmkw2RsnDnO0UvZ705v6EgOXQ==} + peerDependencies: + solid-js: ^1.8.6 + + '@suid/base@0.11.0': + resolution: {integrity: sha512-jNe+LlXuxfkSZo8/MP9koqYYWswucDWSCwc7ViqUhQ0Y/V7sP2RiQ/Bnms+ePSMBZsk5k1b9fAjvj7DtNbbHXw==} + peerDependencies: + solid-js: ^1.9.7 + + '@suid/css@0.4.1': + resolution: {integrity: sha512-Hsi4O3dBOm7rrlqKoWfNoTeRFAXm/7TPaeEmyxNx+wFaT3eROjMVdhadAIiagFT+PsHrq/6fDauUI5TkL+5Zvg==} + + '@suid/icons-material@0.9.0': + resolution: {integrity: sha512-2idgaT/JARd12dwDfocZBQizaiZVgR0ujRsVc61OlAuPZbeH+3TrSxUJkE3Z7+TPftw9+6p0A24GhJjJLvi6RQ==} + peerDependencies: + solid-js: ^1.9.7 + + '@suid/material@0.19.0': + resolution: {integrity: sha512-vfudxYpHdur5CWTjd3eBb7q1b6A9X/pDWTEf2twc0gXVTcErS9VtY/VPBLa65AzO2SPJsdjAE+BCdVZiXASBbA==} + peerDependencies: + solid-js: ^1.9.7 + + '@suid/styled-engine@0.9.0': + resolution: {integrity: sha512-IfNHjQ3Im63mFIjFl/doiwdn5qbwgcwi/vUXnX7dmIUC/Cw1f3LPhzVT9V8Z3eqyvvFToy53O+BsuLy2e/WmDw==} + peerDependencies: + solid-js: ^1.9.7 + + '@suid/system@0.14.0': + resolution: {integrity: sha512-aRVilPP53hHkqyAyQp2pasT/u8aQCcELwU4kFDnt3b+rj4fsPQRlhMumlX5mZ5aijIboH1CngU6TDG6Z9Mr3UA==} + peerDependencies: + solid-js: ^1.9.7 + + '@suid/types@0.8.0': + resolution: {integrity: sha512-/Z2abkbypMjF6ygSpnjqnWohcmPqvgw8Xpx1wPPHeh+LajBP2imNT6uEa5dBqNEkJY8O3wEUCVqErAad/rmn5Q==} + peerDependencies: + solid-js: ^1.9.7 + + '@suid/utils@0.11.0': + resolution: {integrity: sha512-dk+6YJkex9kcU2qQHCOk8J0/zkOKKbng0SsjC0LBLyBrf2OC3OtDQq7o22pH3m/8CU/0M6uyM7tnyzZA4eWF3Q==} + peerDependencies: + solid-js: ^1.9.7 + + '@swc/helpers@0.5.18': + resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@vue/reactivity@3.5.26': + resolution: {integrity: sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==} + + '@vue/shared@3.5.26': + resolution: {integrity: sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-sequence-parser@1.1.3: + resolution: {integrity: sha512-+fksAx9eG3Ab6LDnLs3ZqZa8KVJ/jYnX+D4Qe1azX+LFGFAXqynCQLOdLpNYN/l9e7l6hMWwZbrnctqr6eSQSw==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + autoprefixer@10.4.21: + resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + babel-plugin-jsx-dom-expressions@0.40.3: + resolution: {integrity: sha512-5HOwwt0BYiv/zxl7j8Pf2bGL6rDXfV6nUhLs8ygBX+EFJXzBPHM/euj9j/6deMZ6wa52Wb2PBaAV5U/jKwIY1w==} + peerDependencies: + '@babel/core': ^7.20.12 + + babel-preset-solid@1.9.10: + resolution: {integrity: sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ==} + peerDependencies: + '@babel/core': ^7.0.0 + solid-js: ^1.9.10 + peerDependenciesMeta: + solid-js: + optional: true + + baseline-browser-mapping@2.9.14: + resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==} + hasBin: true + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001763: + resolution: {integrity: sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + electron-to-chromium@1.5.267: + resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + github-markdown-css@5.8.1: + resolution: {integrity: sha512-8G+PFvqigBQSWLQjyzgpa2ThD9bo7+kDsriUIidGcRhXgmcaAWUIpCZf8DavJgc+xifjbCG+GvMyWr0XMXmc7g==} + engines: {node: '>=10'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + highlight.js@11.11.1: + resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} + engines: {node: '>=12.0.0'} + + html-entities@2.3.3: + resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lowlight@3.3.0: + resolution: {integrity: sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lucide-solid@0.300.0: + resolution: {integrity: sha512-FEAF0CYnuhQiFjpZe2UxQ0LX/wJFuPvFlyVwDdD4uvvAP/nzhCa1xSMhMBpaCTH3BIveJvoz14YOl7uiLkZYow==} + peerDependencies: + solid-js: ^1.4.7 + + marked@12.0.2: + resolution: {integrity: sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==} + engines: {node: '>= 18'} + hasBin: true + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + merge-anything@5.1.7: + resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==} + engines: {node: '>=12.13'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + + oniguruma-to-es@4.3.4: + resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + qrcode@1.5.4: + resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} + engines: {node: '>=10.13.0'} + hasBin: true + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react@19.2.3: + resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + engines: {node: '>=0.10.0'} + + reactivity-store@0.3.12: + resolution: {integrity: sha512-Idz9EL4dFUtQbHySZQzckWOTUfqjdYpUtNW0iOysC32mG7IjiUGB77QrsyR5eAWBkRiS9JscF6A3fuQAIy+LrQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.55.1: + resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + seroval-plugins@1.3.3: + resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.3.2: + resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} + engines: {node: '>=10'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + shiki@3.21.0: + resolution: {integrity: sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w==} + + solid-js@1.9.10: + resolution: {integrity: sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==} + + solid-presence@0.1.8: + resolution: {integrity: sha512-pWGtXUFWYYUZNbg5YpG5vkQJyOtzn2KXhxYaMx/4I+lylTLYkITOLevaCwMRN+liCVk0pqB6EayLWojNqBFECA==} + peerDependencies: + solid-js: ^1.8 + + solid-prevent-scroll@0.1.10: + resolution: {integrity: sha512-KplGPX2GHiWJLZ6AXYRql4M127PdYzfwvLJJXMkO+CMb8Np4VxqDAg5S8jLdwlEuBis/ia9DKw2M8dFx5u8Mhw==} + peerDependencies: + solid-js: ^1.8 + + solid-refresh@0.6.3: + resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==} + peerDependencies: + solid-js: ^1.3 + + solid-toast@0.5.0: + resolution: {integrity: sha512-t770JakjyS2P9b8Qa1zMLOD51KYKWXbTAyJePVUoYex5c5FH5S/HtUBUbZAWFcqRCKmAE8KhyIiCvDZA8bOnxQ==} + peerDependencies: + solid-js: ^1.5.4 + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite-plugin-solid@2.11.10: + resolution: {integrity: sha512-Yr1dQybmtDtDAHkii6hXuc1oVH9CPcS/Zb2jN/P36qqcrkNnVPsMTzQ06jyzFPFjj3U1IYKMVt/9ZqcwGCEbjw==} + peerDependencies: + '@testing-library/jest-dom': ^5.16.6 || ^5.17.0 || ^6.* + solid-js: ^1.7.2 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + '@testing-library/jest-dom': + optional: true + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitefu@1.1.1: + resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + vite: + optional: true + + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.5': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.18.6': + dependencies: + '@babel/types': 7.28.5 + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@corvu/utils@0.4.2(solid-js@1.9.10)': + dependencies: + '@floating-ui/dom': 1.7.4 + solid-js: 1.9.10 + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/utils@0.2.10': {} + + '@git-diff-view/core@0.0.35': + dependencies: + '@git-diff-view/lowlight': 0.0.35 + fast-diff: 1.3.0 + highlight.js: 11.11.1 + lowlight: 3.3.0 + + '@git-diff-view/lowlight@0.0.35': + dependencies: + '@types/hast': 3.0.4 + highlight.js: 11.11.1 + lowlight: 3.3.0 + + '@git-diff-view/solid@0.0.8(react@19.2.3)(solid-js@1.9.10)': + dependencies: + '@git-diff-view/core': 0.0.35 + '@types/hast': 3.0.4 + fast-diff: 1.3.0 + highlight.js: 11.11.1 + lowlight: 3.3.0 + reactivity-store: 0.3.12(react@19.2.3) + solid-js: 1.9.10 + transitivePeerDependencies: + - react + + '@internationalized/date@3.10.1': + dependencies: + '@swc/helpers': 0.5.18 + + '@internationalized/number@3.6.5': + dependencies: + '@swc/helpers': 0.5.18 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@kobalte/core@0.13.11(solid-js@1.9.10)': + dependencies: + '@floating-ui/dom': 1.7.4 + '@internationalized/date': 3.10.1 + '@internationalized/number': 3.6.5 + '@kobalte/utils': 0.9.1(solid-js@1.9.10) + '@solid-primitives/props': 3.2.2(solid-js@1.9.10) + '@solid-primitives/resize-observer': 2.1.3(solid-js@1.9.10) + solid-js: 1.9.10 + solid-presence: 0.1.8(solid-js@1.9.10) + solid-prevent-scroll: 0.1.10(solid-js@1.9.10) + + '@kobalte/utils@0.9.1(solid-js@1.9.10)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) + '@solid-primitives/keyed': 1.5.2(solid-js@1.9.10) + '@solid-primitives/map': 0.4.13(solid-js@1.9.10) + '@solid-primitives/media': 2.3.3(solid-js@1.9.10) + '@solid-primitives/props': 3.2.2(solid-js@1.9.10) + '@solid-primitives/refs': 1.1.2(solid-js@1.9.10) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@opencode-ai/sdk@1.1.12': {} + + '@popperjs/core@2.11.8': {} + + '@rollup/rollup-android-arm-eabi@4.55.1': + optional: true + + '@rollup/rollup-android-arm64@4.55.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.55.1': + optional: true + + '@rollup/rollup-darwin-x64@4.55.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.55.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.55.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.55.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.55.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.55.1': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.55.1': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.55.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.55.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.55.1': + optional: true + + '@rollup/rollup-openbsd-x64@4.55.1': + optional: true + + '@rollup/rollup-openharmony-arm64@4.55.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.55.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.55.1': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.55.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.55.1': + optional: true + + '@shikijs/core@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.4 + + '@shikijs/engine-oniguruma@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + + '@shikijs/themes@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + + '@shikijs/types@3.21.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@solid-primitives/event-listener@2.4.3(solid-js@1.9.10)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-primitives/keyed@1.5.2(solid-js@1.9.10)': + dependencies: + solid-js: 1.9.10 + + '@solid-primitives/map@0.4.13(solid-js@1.9.10)': + dependencies: + '@solid-primitives/trigger': 1.2.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-primitives/media@2.3.3(solid-js@1.9.10)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) + '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-primitives/props@3.2.2(solid-js@1.9.10)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-primitives/refs@1.1.2(solid-js@1.9.10)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-primitives/resize-observer@2.1.3(solid-js@1.9.10)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) + '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-primitives/rootless@1.5.2(solid-js@1.9.10)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-primitives/static-store@0.1.2(solid-js@1.9.10)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-primitives/trigger@1.2.2(solid-js@1.9.10)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-primitives/utils@6.3.2(solid-js@1.9.10)': + dependencies: + solid-js: 1.9.10 + + '@solidjs/router@0.13.6(solid-js@1.9.10)': + dependencies: + solid-js: 1.9.10 + + '@suid/base@0.11.0(solid-js@1.9.10)': + dependencies: + '@popperjs/core': 2.11.8 + '@suid/css': 0.4.1 + '@suid/system': 0.14.0(solid-js@1.9.10) + '@suid/types': 0.8.0(solid-js@1.9.10) + '@suid/utils': 0.11.0(solid-js@1.9.10) + clsx: 2.1.1 + solid-js: 1.9.10 + + '@suid/css@0.4.1': {} + + '@suid/icons-material@0.9.0(solid-js@1.9.10)': + dependencies: + '@suid/material': 0.19.0(solid-js@1.9.10) + solid-js: 1.9.10 + + '@suid/material@0.19.0(solid-js@1.9.10)': + dependencies: + '@suid/base': 0.11.0(solid-js@1.9.10) + '@suid/css': 0.4.1 + '@suid/system': 0.14.0(solid-js@1.9.10) + '@suid/types': 0.8.0(solid-js@1.9.10) + '@suid/utils': 0.11.0(solid-js@1.9.10) + clsx: 2.1.1 + solid-js: 1.9.10 + + '@suid/styled-engine@0.9.0(solid-js@1.9.10)': + dependencies: + '@suid/css': 0.4.1 + '@suid/utils': 0.11.0(solid-js@1.9.10) + solid-js: 1.9.10 + + '@suid/system@0.14.0(solid-js@1.9.10)': + dependencies: + '@suid/css': 0.4.1 + '@suid/styled-engine': 0.9.0(solid-js@1.9.10) + '@suid/types': 0.8.0(solid-js@1.9.10) + '@suid/utils': 0.11.0(solid-js@1.9.10) + clsx: 2.1.1 + csstype: 3.2.3 + solid-js: 1.9.10 + + '@suid/types@0.8.0(solid-js@1.9.10)': + dependencies: + solid-js: 1.9.10 + + '@suid/utils@0.11.0(solid-js@1.9.10)': + dependencies: + '@suid/types': 0.8.0(solid-js@1.9.10) + solid-js: 1.9.10 + + '@swc/helpers@0.5.18': + dependencies: + tslib: 2.8.1 + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/estree@1.0.8': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/unist@3.0.3': {} + + '@ungap/structured-clone@1.3.0': {} + + '@vue/reactivity@3.5.26': + dependencies: + '@vue/shared': 3.5.26 + + '@vue/shared@3.5.26': {} + + ansi-regex@5.0.1: {} + + ansi-sequence-parser@1.1.3: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + autoprefixer@10.4.21(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + caniuse-lite: 1.0.30001763 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.18.6 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/types': 7.28.5 + html-entities: 2.3.3 + parse5: 7.3.0 + + babel-preset-solid@1.9.10(@babel/core@7.28.5)(solid-js@1.9.10): + dependencies: + '@babel/core': 7.28.5 + babel-plugin-jsx-dom-expressions: 0.40.3(@babel/core@7.28.5) + optionalDependencies: + solid-js: 1.9.10 + + baseline-browser-mapping@2.9.14: {} + + binary-extensions@2.3.0: {} + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.14 + caniuse-lite: 1.0.30001763 + electron-to-chromium: 1.5.267 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + camelcase-css@2.0.1: {} + + camelcase@5.3.1: {} + + caniuse-lite@1.0.30001763: {} + + ccount@2.0.1: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + clsx@2.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + comma-separated-tokens@2.0.3: {} + + commander@4.1.1: {} + + convert-source-map@2.0.0: {} + + cssesc@3.0.0: {} + + csstype@3.2.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decamelize@1.2.0: {} + + dequal@2.0.3: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + didyoumean@1.2.2: {} + + dijkstrajs@1.0.3: {} + + dlv@1.1.3: {} + + electron-to-chromium@1.5.267: {} + + emoji-regex@8.0.0: {} + + entities@6.0.1: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.2.0: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + fraction.js@4.3.7: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + github-markdown-css@5.8.1: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + highlight.js@11.11.1: {} + + html-entities@2.3.3: {} + + html-void-elements@3.0.0: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-what@4.1.16: {} + + jiti@1.21.7: {} + + js-tokens@4.0.0: {} + + jsesc@3.1.0: {} + + json5@2.2.3: {} + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lowlight@3.3.0: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + highlight.js: 11.11.1 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lucide-solid@0.300.0(solid-js@1.9.10): + dependencies: + solid-js: 1.9.10 + + marked@12.0.2: {} + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + merge-anything@5.1.7: + dependencies: + is-what: 4.1.16 + + merge2@1.4.1: {} + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-encode@2.0.1: {} + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + node-releases@2.0.27: {} + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + oniguruma-parser@0.12.1: {} + + oniguruma-to-es@4.3.4: + dependencies: + oniguruma-parser: 0.12.1 + regex: 6.1.0 + regex-recursion: 6.0.2 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-try@2.2.0: {} + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + path-exists@4.0.0: {} + + path-parse@1.0.7: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pify@2.3.0: {} + + pirates@4.0.7: {} + + pngjs@5.0.0: {} + + postcss-import@15.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.11 + + postcss-js@4.1.0(postcss@8.5.6): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.6 + + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 1.21.7 + postcss: 8.5.6 + + postcss-nested@6.2.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + property-information@7.1.0: {} + + qrcode@1.5.4: + dependencies: + dijkstrajs: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + queue-microtask@1.2.3: {} + + react@19.2.3: {} + + reactivity-store@0.3.12(react@19.2.3): + dependencies: + '@vue/reactivity': 3.5.26 + '@vue/shared': 3.5.26 + react: 19.2.3 + use-sync-external-store: 1.6.0(react@19.2.3) + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + require-directory@2.1.1: {} + + require-main-filename@2.0.0: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rollup@4.55.1: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.55.1 + '@rollup/rollup-android-arm64': 4.55.1 + '@rollup/rollup-darwin-arm64': 4.55.1 + '@rollup/rollup-darwin-x64': 4.55.1 + '@rollup/rollup-freebsd-arm64': 4.55.1 + '@rollup/rollup-freebsd-x64': 4.55.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.55.1 + '@rollup/rollup-linux-arm-musleabihf': 4.55.1 + '@rollup/rollup-linux-arm64-gnu': 4.55.1 + '@rollup/rollup-linux-arm64-musl': 4.55.1 + '@rollup/rollup-linux-loong64-gnu': 4.55.1 + '@rollup/rollup-linux-loong64-musl': 4.55.1 + '@rollup/rollup-linux-ppc64-gnu': 4.55.1 + '@rollup/rollup-linux-ppc64-musl': 4.55.1 + '@rollup/rollup-linux-riscv64-gnu': 4.55.1 + '@rollup/rollup-linux-riscv64-musl': 4.55.1 + '@rollup/rollup-linux-s390x-gnu': 4.55.1 + '@rollup/rollup-linux-x64-gnu': 4.55.1 + '@rollup/rollup-linux-x64-musl': 4.55.1 + '@rollup/rollup-openbsd-x64': 4.55.1 + '@rollup/rollup-openharmony-arm64': 4.55.1 + '@rollup/rollup-win32-arm64-msvc': 4.55.1 + '@rollup/rollup-win32-ia32-msvc': 4.55.1 + '@rollup/rollup-win32-x64-gnu': 4.55.1 + '@rollup/rollup-win32-x64-msvc': 4.55.1 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + semver@6.3.1: {} + + seroval-plugins@1.3.3(seroval@1.3.2): + dependencies: + seroval: 1.3.2 + + seroval@1.3.2: {} + + set-blocking@2.0.0: {} + + shiki@3.21.0: + dependencies: + '@shikijs/core': 3.21.0 + '@shikijs/engine-javascript': 3.21.0 + '@shikijs/engine-oniguruma': 3.21.0 + '@shikijs/langs': 3.21.0 + '@shikijs/themes': 3.21.0 + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + solid-js@1.9.10: + dependencies: + csstype: 3.2.3 + seroval: 1.3.2 + seroval-plugins: 1.3.3(seroval@1.3.2) + + solid-presence@0.1.8(solid-js@1.9.10): + dependencies: + '@corvu/utils': 0.4.2(solid-js@1.9.10) + solid-js: 1.9.10 + + solid-prevent-scroll@0.1.10(solid-js@1.9.10): + dependencies: + '@corvu/utils': 0.4.2(solid-js@1.9.10) + solid-js: 1.9.10 + + solid-refresh@0.6.3(solid-js@1.9.10): + dependencies: + '@babel/generator': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/types': 7.28.5 + solid-js: 1.9.10 + transitivePeerDependencies: + - supports-color + + solid-toast@0.5.0(solid-js@1.9.10): + dependencies: + solid-js: 1.9.10 + + source-map-js@1.2.1: {} + + space-separated-tokens@2.0.2: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + + supports-preserve-symlinks-flag@1.0.0: {} + + tailwindcss@3.4.19: + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-import: 15.1.0(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6) + postcss-nested: 6.2.0(postcss@8.5.6) + postcss-selector-parser: 6.1.2 + resolve: 1.22.11 + sucrase: 3.35.1 + transitivePeerDependencies: + - tsx + - yaml + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + trim-lines@3.0.1: {} + + ts-interface-checker@0.1.13: {} + + tslib@2.8.1: {} + + typescript@5.9.3: {} + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + use-sync-external-store@1.6.0(react@19.2.3): + dependencies: + react: 19.2.3 + + util-deprecate@1.0.2: {} + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite-plugin-solid@2.11.10(solid-js@1.9.10)(vite@5.4.21): + dependencies: + '@babel/core': 7.28.5 + '@types/babel__core': 7.20.5 + babel-preset-solid: 1.9.10(@babel/core@7.28.5)(solid-js@1.9.10) + merge-anything: 5.1.7 + solid-js: 1.9.10 + solid-refresh: 0.6.3(solid-js@1.9.10) + vite: 5.4.21 + vitefu: 1.1.1(vite@5.4.21) + transitivePeerDependencies: + - supports-color + + vite@5.4.21: + dependencies: + esbuild: 0.21.5 + postcss: 8.5.6 + rollup: 4.55.1 + optionalDependencies: + fsevents: 2.3.3 + + vitefu@1.1.1(vite@5.4.21): + optionalDependencies: + vite: 5.4.21 + + which-module@2.0.1: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + y18n@4.0.3: {} + + yallist@3.1.1: {} + + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + + zwitch@2.0.4: {} diff --git a/packages/ui/scripts/monaco-public-assets.d.ts b/packages/ui/scripts/monaco-public-assets.d.ts new file mode 100644 index 00000000..3573f9b7 --- /dev/null +++ b/packages/ui/scripts/monaco-public-assets.d.ts @@ -0,0 +1,7 @@ +export type CopyMonacoPublicAssetsParams = { + uiRendererRoot: string + warn?: (message: string) => void + sourceRoots?: string[] +} + +export function copyMonacoPublicAssets(params: CopyMonacoPublicAssetsParams): void diff --git a/packages/ui/scripts/monaco-public-assets.js b/packages/ui/scripts/monaco-public-assets.js new file mode 100644 index 00000000..6ee3eaf7 --- /dev/null +++ b/packages/ui/scripts/monaco-public-assets.js @@ -0,0 +1,97 @@ +import fs from "fs" +import { resolve } from "path" + +/** + * Copy Monaco's AMD `min/vs` assets into the UI renderer public folder. + * + * Monaco is loaded at runtime via `/monaco/vs/loader.js`. These assets are gitignored + * and generated on demand in dev/build so the repo stays clean. + * + * @param {object} params + * @param {string} params.uiRendererRoot Absolute path to `packages/ui/src/renderer`. + * @param {(message: string) => void} [params.warn] Warning logger. + * @param {string[]} [params.sourceRoots] Optional override list of `.../monaco-editor/min/vs` roots. + */ +export function copyMonacoPublicAssets(params) { + const uiRendererRoot = params?.uiRendererRoot + if (!uiRendererRoot) { + throw new Error("copyMonacoPublicAssets: uiRendererRoot is required") + } + + const warn = params?.warn ?? ((message) => console.warn(message)) + const publicDir = resolve(uiRendererRoot, "public") + const destRoot = resolve(publicDir, "monaco/vs") + + const candidates = + params?.sourceRoots?.length > 0 + ? params.sourceRoots + : [ + // Workspace root hoisted deps. + resolve(process.cwd(), "node_modules/monaco-editor/min/vs"), + // UI package local deps (covers non-hoisted installs). + resolve(process.cwd(), "packages/ui/node_modules/monaco-editor/min/vs"), + ] + + const sourceRoot = candidates.find((p) => fs.existsSync(resolve(p, "loader.js"))) + if (!sourceRoot) { + warn("Monaco source directory not found; skipping copy") + return + } + + const copyRecursive = (src, dest) => { + const stat = fs.statSync(src) + if (stat.isDirectory()) { + fs.mkdirSync(dest, { recursive: true }) + for (const entry of fs.readdirSync(src)) { + copyRecursive(resolve(src, entry), resolve(dest, entry)) + } + return + } + fs.copyFileSync(src, dest) + } + + // Keep the working tree clean; these assets are generated. + try { + fs.rmSync(destRoot, { recursive: true, force: true }) + } catch { + // ignore + } + fs.mkdirSync(destRoot, { recursive: true }) + + // Copy core Monaco runtime. + for (const dir of ["base", "editor", "platform"]) { + const src = resolve(sourceRoot, dir) + if (fs.existsSync(src)) { + copyRecursive(src, resolve(destRoot, dir)) + } + } + + // loader.js is required. + copyRecursive(resolve(sourceRoot, "loader.js"), resolve(destRoot, "loader.js")) + + // Copy baseline rich language packages + workers. + for (const lang of ["typescript", "html", "json", "css"]) { + const src = resolve(sourceRoot, "language", lang) + if (fs.existsSync(src)) { + copyRecursive(src, resolve(destRoot, "language", lang)) + } + } + + // Copy baseline basic tokenizers. + for (const lang of ["python", "markdown", "cpp", "kotlin"]) { + const src = resolve(sourceRoot, "basic-languages", lang) + if (fs.existsSync(src)) { + copyRecursive(src, resolve(destRoot, "basic-languages", lang)) + } + } + + // Copy monaco.contribution.js entrypoints (needed by some loads). + const monacoContribution = resolve(sourceRoot, "basic-languages", "monaco.contribution.js") + if (fs.existsSync(monacoContribution)) { + copyRecursive(monacoContribution, resolve(destRoot, "basic-languages", "monaco.contribution.js")) + } + const underscoreContribution = resolve(sourceRoot, "basic-languages", "_.contribution.js") + if (fs.existsSync(underscoreContribution)) { + copyRecursive(underscoreContribution, resolve(destRoot, "basic-languages", "_.contribution.js")) + } +} diff --git a/packages/ui/src/App.tsx b/packages/ui/src/App.tsx index 81064972..f4092ad3 100644 --- a/packages/ui/src/App.tsx +++ b/packages/ui/src/App.tsx @@ -19,6 +19,7 @@ import { getLogger } from "./lib/logger" import { initReleaseNotifications } from "./stores/releases" import { runtimeEnv } from "./lib/runtime-env" import { useI18n } from "./lib/i18n" +import { setWakeLockDesired } from "./lib/native/wake-lock" import { hasInstances, isSelectingFolder, @@ -48,6 +49,8 @@ import { updateSessionModel, } from "./stores/sessions" +import { getInstanceSessionIndicatorStatus } from "./stores/session-status" + const log = getLogger("actions") const App: Component = () => { @@ -60,6 +63,7 @@ const App: Component = () => { toggleShowTimelineTools, toggleAutoCleanupBlankSessions, toggleUsageMetrics, + togglePromptSubmitOnEnter, setDiffViewMode, setToolOutputExpansion, setDiagnosticsExpansion, @@ -90,6 +94,26 @@ const App: Component = () => { initReleaseNotifications() }) + const shouldHoldWakeLock = createMemo(() => { + const map = instances() + for (const id of map.keys()) { + const status = getInstanceSessionIndicatorStatus(id) + if (status !== "idle") { + return true + } + } + return false + }) + + createEffect(() => { + const hold = shouldHoldWakeLock() + void setWakeLockDesired(hold) + }) + + onCleanup(() => { + void setWakeLockDesired(false) + }) + createEffect(() => { instances() hasInstances() @@ -271,6 +295,7 @@ const App: Component = () => { toggleShowThinkingBlocks, toggleShowTimelineTools, toggleUsageMetrics, + togglePromptSubmitOnEnter, setDiffViewMode, setToolOutputExpansion, setDiagnosticsExpansion, @@ -329,32 +354,34 @@ const App: Component = () => { -
- -
- {t("app.launchError.title")} - - {t("app.launchError.description")} - -
- -
-

{t("app.launchError.binaryPathLabel")}

-

{launchErrorPath()}

-
- - -
-

{t("app.launchError.errorOutputLabel")}

-
{launchErrorMessage()}
-
-
- -
- -
+ +
+
+

Timeout Settings

+

Configure timeouts for various operations

+
+
+
+ + { + const val = parseInt(e.currentTarget.value) + if (!isNaN(val) && val > 0) { + setAskUserTimeout(val * 1000) + } + }} + class="px-3 py-2 text-sm bg-surface-base border border-base rounded text-primary focus-ring-accent w-32" + /> +

+ Time to wait for user response before timing out (Default: 300s) +

+
+
+
diff --git a/packages/ui/src/components/agent-selector.tsx b/packages/ui/src/components/agent-selector.tsx index a06568d9..33fdd235 100644 --- a/packages/ui/src/components/agent-selector.tsx +++ b/packages/ui/src/components/agent-selector.tsx @@ -1,5 +1,5 @@ import { Select } from "@kobalte/core/select" -import { For, Show, createEffect, createMemo } from "solid-js" +import { Show, createEffect, createMemo } from "solid-js" import { agents, fetchAgents, sessions } from "../stores/sessions" import { ChevronDown } from "lucide-solid" import type { Agent } from "../types/session" diff --git a/packages/ui/src/components/askquestion-wizard.tsx b/packages/ui/src/components/askquestion-wizard.tsx new file mode 100644 index 00000000..3e13a6d4 --- /dev/null +++ b/packages/ui/src/components/askquestion-wizard.tsx @@ -0,0 +1,662 @@ +import { createMemo, For, onCleanup, Show, type Component, createSignal } from "solid-js" +import { createStore, produce } from "solid-js/store" +import { createEffect, onMount } from "solid-js" +import { Minus } from "lucide-solid" +import type { WizardQuestion, QuestionAnswer, QuestionOption } from "../types/question" +import { renderMarkdown } from "../lib/markdown" + +// Custom option marker +const CUSTOM_OPTION_LABEL = "Type something..." + +// Extended option type that includes the custom option +type WizardOption = QuestionOption & { isCustom?: boolean } + +export interface AskQuestionWizardProps { + questions: WizardQuestion[] + onSubmit: (answers: QuestionAnswer[]) => void + onCancel: () => void + onMinimize?: () => void + /** Request ID for render confirmation (MCP questions only) */ + requestId?: string + /** Source of the question: 'mcp' needs render confirmation */ + source?: 'opencode' | 'mcp' +} + +interface QuestionState { + selectedOption: number + selectedValues: string[] + customText?: string +} + +export const AskQuestionWizard: Component = (props) => { + // State for the wizard + const [store, setStore] = createStore({ + activeTab: 0, + questionStates: props.questions.map(() => ({ + selectedOption: 0, + selectedValues: [] as string[], + customText: undefined as string | undefined, + })) as QuestionState[], + isTypingCustom: false, + customInputValue: "", + }) + + // Send render confirmation when wizard actually mounts (MCP questions only) + onMount(() => { + if (props.source === 'mcp' && props.requestId) { + // Small delay to ensure UI is fully rendered + setTimeout(() => { + if (typeof window !== 'undefined' && (window as any).electronAPI) { + const electronAPI = (window as any).electronAPI; + electronAPI.mcpSend('mcp:renderConfirmed', { + requestId: props.requestId, + timestamp: Date.now() + }); + if (import.meta.env.DEV) { + console.log('[AskQuestionWizard] Sent render confirmation for:', props.requestId); + } + } + }, 100); + } + }) + + let containerRef: HTMLDivElement | undefined + let inputRef: HTMLInputElement | undefined + let optionsContainerRef: HTMLDivElement | undefined + let optionRefs: HTMLButtonElement[] = [] + + // Current question based on active tab + const currentQuestion = createMemo(() => { + const question = props.questions[store.activeTab] + return question + }) + const currentState = createMemo(() => store.questionStates[store.activeTab]) + + // Rendered markdown for the question text + const [questionHtml, setQuestionHtml] = createSignal("") + + // Render question text as markdown + createEffect(async () => { + const question = currentQuestion() + if (question && question.question) { + try { + const html = await renderMarkdown(question.question) + setQuestionHtml(html) + } catch (error) { + console.error("[AskQuestionWizard] Failed to render question markdown:", error) + setQuestionHtml(question.question) // Fallback to plain text + } + } else { + setQuestionHtml("") + } + }) + + // Options including "Type something..." at the end + const optionsWithCustom = createMemo((): WizardOption[] => { + const current = currentQuestion() + if (!current) return [] + return [ + ...current.options, + { label: CUSTOM_OPTION_LABEL, description: "Enter your own response", isCustom: true }, + ] + }) + + // Check if all questions have at least one answer + const allAnswered = createMemo(() => + store.questionStates.every((state) => state.selectedValues.length > 0 || state.customText), + ) + + // Check if current question is answered + const currentAnswered = createMemo(() => { + const state = currentState() + return state.selectedValues.length > 0 || state.customText + }) + + function handleSubmit() { + if (!allAnswered()) { + return + } + // Unwrap proxy values to plain arrays/objects before passing to parent + const answers: QuestionAnswer[] = props.questions.map((q, i) => { + const state = store.questionStates[i] + return { + questionId: q.id || `q-${i}`, + // Convert proxy array to plain array + values: [...state.selectedValues], + customText: state.customText, + } + }) + props.onSubmit(answers) + } + + function selectOption(optionLabel: string) { + const question = currentQuestion() + + setStore( + produce((s) => { + const state = s.questionStates[s.activeTab] + state.customText = undefined + + if (question.multiple) { + // Toggle for multi-select (use label as value) + const idx = state.selectedValues.indexOf(optionLabel) + if (import.meta.env.DEV) { + console.log('[AskQuestionWizard] Multi-select toggle', { + optionLabel, + currentIndex: idx, + currentArray: [...state.selectedValues] + }) + } + + if (idx >= 0) { + // Remove if already selected + state.selectedValues.splice(idx, 1) + if (import.meta.env.DEV) { + console.log('[AskQuestionWizard] Removed from selection', { + newArray: [...state.selectedValues] + }) + } + } else { + // Add if not selected + state.selectedValues.push(optionLabel) + if (import.meta.env.DEV) { + console.log('[AskQuestionWizard] Added to selection', { + newArray: [...state.selectedValues] + }) + } + } + } else { + // Select for single-select and auto-advance + state.selectedValues = [optionLabel] + if (s.activeTab < props.questions.length - 1) { + s.activeTab++ + } + } + }), + ) + // Auto-submit if single-select on last question and all answered + if (!question.multiple) { + setTimeout(() => { + if (allAnswered()) { + handleSubmit() + } + }, 50) + } + } + + function navigateOption(direction: "up" | "down") { + const current = currentState().selectedOption + const max = optionsWithCustom().length - 1 + const newOptionIdx = direction === "up" + ? (current > 0 ? current - 1 : max) + : (current < max ? current + 1 : 0) + + setStore( + produce((s) => { + s.questionStates[s.activeTab].selectedOption = newOptionIdx + }), + ) + + // Scroll the newly selected option into view + setTimeout(() => { + const selectedElement = optionsContainerRef?.querySelector('[data-option-selected="true"]') + if (selectedElement) { + selectedElement.scrollIntoView({ + behavior: 'smooth', + block: 'nearest' + }) + } + }, 0) + } + + function navigateQuestion(direction: "left" | "right") { + if (direction === "right") { + if (store.activeTab < props.questions.length - 1) { + setStore("activeTab", store.activeTab + 1) + // Reset option refs when switching questions + optionRefs = [] + } else if (allAnswered()) { + handleSubmit() + } + } else { + if (store.activeTab > 0) { + setStore("activeTab", store.activeTab - 1) + // Reset option refs when switching questions + optionRefs = [] + } + } + } + + function openCustomInput() { + setStore("isTypingCustom", true) + setTimeout(() => inputRef?.focus(), 10) + } + + function submitCustomInput() { + const value = store.customInputValue.trim() + if (value) { + setStore( + produce((s) => { + s.questionStates[s.activeTab].customText = value + s.questionStates[s.activeTab].selectedValues = [] + }), + ) + } + setStore("isTypingCustom", false) + setStore("customInputValue", "") + // Auto-advance to next question or submit + if (store.activeTab < props.questions.length - 1) { + setStore("activeTab", store.activeTab + 1) + } else if (allAnswered()) { + handleSubmit() + } + } + + function handleKeyDown(evt: KeyboardEvent) { + // Allow the event to be handled when inside our component + if (store.isTypingCustom) { + // In custom input mode + if (evt.key === "Escape") { + evt.preventDefault() + evt.stopPropagation() + setStore("isTypingCustom", false) + setStore("customInputValue", "") + return + } + if (evt.key === "Enter" && !evt.shiftKey) { + evt.preventDefault() + evt.stopPropagation() + submitCustomInput() + return + } + // Let other keys through for typing + return + } + + // Tab/arrow navigation between questions + if (evt.key === "Tab" && !evt.shiftKey) { + evt.preventDefault() + evt.stopPropagation() + navigateQuestion("right") + return + } + if (evt.key === "Tab" && evt.shiftKey) { + evt.preventDefault() + evt.stopPropagation() + navigateQuestion("left") + return + } + if (evt.key === "ArrowRight") { + evt.preventDefault() + evt.stopPropagation() + navigateQuestion("right") + return + } + if (evt.key === "ArrowLeft") { + evt.preventDefault() + evt.stopPropagation() + navigateQuestion("left") + return + } + + // Up/down navigation within options + if (evt.key === "ArrowUp" || (evt.ctrlKey && evt.key === "p")) { + evt.preventDefault() + evt.stopPropagation() + navigateOption("up") + return + } + if (evt.key === "ArrowDown" || (evt.ctrlKey && evt.key === "n")) { + evt.preventDefault() + evt.stopPropagation() + navigateOption("down") + return + } + + // Space to toggle selection (especially useful for multi-select) + if (evt.key === " ") { + evt.preventDefault() + evt.stopPropagation() + const selectedIdx = currentState().selectedOption + const option = optionsWithCustom()[selectedIdx] + if (!option) return + + if (option.isCustom) { + openCustomInput() + return + } + + selectOption(option.label) + return + } + + // Enter to select option (single-select) or confirm and advance (multi-select) + if (evt.key === "Enter" && !evt.ctrlKey && !evt.metaKey) { + evt.preventDefault() + evt.stopPropagation() + const selectedIdx = currentState().selectedOption + const option = optionsWithCustom()[selectedIdx] + if (!option) return + + if (option.isCustom) { + openCustomInput() + return + } + + const question = currentQuestion() + if (question.multiple) { + // For multi-select: Enter confirms current selections and advances + if (currentAnswered()) { + navigateQuestion("right") + return + } + // If nothing selected yet, toggle the current option + selectOption(option.label) + return + } + + // Single-select: select and advance + selectOption(option.label) + return + } + + // Number keys for quick selection (1-8) + if (evt.key >= "1" && evt.key <= "8" && !evt.ctrlKey && !evt.metaKey) { + evt.preventDefault() + evt.stopPropagation() + const idx = parseInt(evt.key) - 1 + if (idx < currentQuestion().options.length) { + const option = currentQuestion().options[idx] + if (option) { + selectOption(option.label) + } + } + return + } + + // Escape to cancel + if (evt.key === "Escape") { + evt.preventDefault() + evt.stopPropagation() + props.onCancel() + return + } + + // Ctrl+Enter to submit + if ((evt.ctrlKey || evt.metaKey) && evt.key === "Enter") { + evt.preventDefault() + evt.stopPropagation() + if (allAnswered()) { + handleSubmit() + } + return + } + } + + onMount(() => { + // Focus container to capture keyboard events + containerRef?.focus() + document.addEventListener("keydown", handleKeyDown, true) + // Reset option refs when switching questions + optionRefs = [] + }) + + // Scroll selected option into view when active tab changes + createEffect(() => { + const activeTab = store.activeTab + const _selectedOption = store.questionStates[activeTab].selectedOption + + // Scroll to selected option with a slight delay to ensure DOM is updated + setTimeout(() => { + const selectedElement = optionsContainerRef?.querySelector('[data-option-selected="true"]') + if (selectedElement) { + selectedElement.scrollIntoView({ + behavior: 'smooth', + block: 'nearest' + }) + } + }, 0) + }) + + onCleanup(() => { + document.removeEventListener("keydown", handleKeyDown, true) + }) + + return ( +
+
+
Answer the questions
+
+ + + + +
+
+ + {/* Tab bar */} +
+ + + {(question, index) => { + const isActive = createMemo(() => store.activeTab === index()) + const isAnswered = createMemo(() => { + const state = store.questionStates[index()] + return state.selectedValues.length > 0 || !!state.customText + }) + return ( + + ) + }} + + + + + +
+ + {/* Current question */} +
+ {/* eslint-disable-next-line solid/no-innerhtml -- User input rendered as markdown */} +
+ +

(select multiple, press Enter to confirm)

+
+
+ + {/* Options */} +
+ + {(option, index) => { + const optionLabel = option.label // Use label as value + const optionLabelText = option.label + const optionDescription = option.description + const isCustomOption = option.isCustom === true + + const isSelected = createMemo(() => currentState().selectedOption === index()) + const isChosen = createMemo(() => { + if (isCustomOption) { + return !!currentState().customText + } + return currentState().selectedValues.includes(optionLabel) + }) + + return ( + + ) + }} + +
+ + {/* Custom input (when active) */} + +
+ setStore("customInputValue", e.currentTarget.value)} + onKeyDown={(e: KeyboardEvent) => { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault() + submitCustomInput() + } else if (e.key === "Escape") { + e.preventDefault() + setStore("isTypingCustom", false) + setStore("customInputValue", "") + } + }} + class="askquestion-wizard-custom-input-field" + /> +
+ + +
+
+
+ + {/* Instructions - desktop only */} +
+

+ {currentQuestion().multiple + ? "Space to toggle · Enter to confirm · ↑↓ to navigate · Esc to cancel" + : "Enter/Space to select · ↑↓ to navigate · Esc to cancel"} +

+
+ + {/* Action buttons - desktop */} +
+ + + + +
+
+ ) +} diff --git a/packages/ui/src/components/background-process-output-dialog.tsx b/packages/ui/src/components/background-process-output-dialog.tsx index 64ff1e4f..87d1ea75 100644 --- a/packages/ui/src/components/background-process-output-dialog.tsx +++ b/packages/ui/src/components/background-process-output-dialog.tsx @@ -153,12 +153,13 @@ export function BackgroundProcessOutputDialog(props: BackgroundProcessOutputDial {output()} } - > -
-                
+                  >
+                
+              
               
             
diff --git a/packages/ui/src/components/code-block-inline.tsx b/packages/ui/src/components/code-block-inline.tsx index dc26c153..a9fa5327 100644 --- a/packages/ui/src/components/code-block-inline.tsx +++ b/packages/ui/src/components/code-block-inline.tsx @@ -95,8 +95,8 @@ export function CodeBlockInline(props: CodeBlockInlineProps) { stroke="currentColor" stroke-width="2" > - - + + @@ -105,6 +105,7 @@ export function CodeBlockInline(props: CodeBlockInlineProps) {
+ {/* eslint-disable-next-line solid/no-innerhtml -- HTML from syntax highlighter */}
diff --git a/packages/ui/src/components/diff-viewer.tsx b/packages/ui/src/components/diff-viewer.tsx index b2fef6a2..3bd07f8d 100644 --- a/packages/ui/src/components/diff-viewer.tsx +++ b/packages/ui/src/components/diff-viewer.tsx @@ -1,4 +1,4 @@ -import { createMemo, Show, createEffect, onCleanup } from "solid-js" +import { createMemo, Show, createEffect } from "solid-js" import { DiffView, DiffModeEnum } from "@git-diff-view/solid" import { disableCache } from "@git-diff-view/core" import type { DiffHighlighterLang } from "@git-diff-view/core" @@ -30,7 +30,7 @@ type DiffData = { hunks: string[] } -type CaptureContext = { +type _CaptureContext = { theme: ToolCallDiffViewerProps["theme"] mode: DiffViewMode diffText: string @@ -130,7 +130,8 @@ export function ToolCallDiffViewer(props: ToolCallDiffViewerProps) { } > -
+ {/* eslint-disable-next-line solid/no-innerhtml -- Cached HTML from trusted diff renderer */} +
) diff --git a/packages/ui/src/components/environment-variables-editor.tsx b/packages/ui/src/components/environment-variables-editor.tsx index 07e3738d..b4dcb317 100644 --- a/packages/ui/src/components/environment-variables-editor.tsx +++ b/packages/ui/src/components/environment-variables-editor.tsx @@ -35,7 +35,7 @@ const EnvironmentVariablesEditor: Component = ( function handleRemoveVariable(key: string) { removeEnvironmentVariable(key) - const { [key]: removed, ...rest } = envVars() + const { [key]: _removed, ...rest } = envVars() setEnvVars(rest) } diff --git a/packages/ui/src/components/expand-button.tsx b/packages/ui/src/components/expand-button.tsx index 953b3f87..851cac22 100644 --- a/packages/ui/src/components/expand-button.tsx +++ b/packages/ui/src/components/expand-button.tsx @@ -1,32 +1,111 @@ -import { Show } from "solid-js" +import { createSignal, Show } from "solid-js" import { Maximize2, Minimize2 } from "lucide-solid" import { useI18n } from "../lib/i18n" +import { isElectronHost } from "../lib/runtime-env" interface ExpandButtonProps { - expandState: () => "normal" | "expanded" - onToggleExpand: (nextState: "normal" | "expanded") => void + expandState: () => "normal" | "fifty" | "eighty" | "expanded" + onToggleExpand: (nextState: "normal" | "fifty" | "eighty" | "expanded") => void } export default function ExpandButton(props: ExpandButtonProps) { + const [clickTime, setClickTime] = createSignal(0) + const [clickTimer, setClickTimer] = createSignal(null) + const DOUBLE_CLICK_THRESHOLD = 300 + + // Check if we're in Electron (desktop app with 3-state support) + const isDesktopApp = isElectronHost() const { t } = useI18n() function handleClick() { const current = props.expandState() - props.onToggleExpand(current === "normal" ? "expanded" : "normal") + + if (!isDesktopApp) { + // Web/Mobile: Simple 2-state toggle (instant, no delay) + if (current === "normal") { + props.onToggleExpand("expanded") + } else { + props.onToggleExpand("normal") + } + return + } + + // Electron: 3-state with double-click detection + const now = Date.now() + const lastClick = clickTime() + const isDoubleClick = now - lastClick < DOUBLE_CLICK_THRESHOLD + + // Clear any pending single-click timer + const timer = clickTimer() + if (timer !== null) { + clearTimeout(timer) + setClickTimer(null) + } + + if (isDoubleClick) { + // Double click behavior - execute immediately + if (current === "normal") { + props.onToggleExpand("eighty") + } else if (current === "fifty") { + props.onToggleExpand("eighty") + } else { + props.onToggleExpand("fifty") + } + // Reset click time to prevent triple-click issues + setClickTime(0) + } else { + // Single click behavior - delay to wait for potential double-click + setClickTime(now) + + const newTimer = window.setTimeout(() => { + const currentState = props.expandState() + if (currentState === "normal") { + props.onToggleExpand("fifty") + } else { + props.onToggleExpand("normal") + } + setClickTimer(null) + }, DOUBLE_CLICK_THRESHOLD) + + setClickTimer(newTimer) + } + } + + const getTooltip = () => { + // No tooltip for web/mobile - only Electron gets tooltips + if (!isDesktopApp) { + return undefined + } + + const current = props.expandState() + if (current === "normal") { + return "Click to expand (50%) • Double-click to expand further (80%)" + } else if (current === "fifty") { + return "Double-click to expand to 80% • Click to minimize" + } else { + return "Click to minimize • Double-click to reduce to 50%" + } + } + + const isExpanded = () => { + const state = props.expandState() + return state !== "normal" } return ( ) diff --git a/packages/ui/src/components/failed-notification-banner.tsx b/packages/ui/src/components/failed-notification-banner.tsx new file mode 100644 index 00000000..c52b419d --- /dev/null +++ b/packages/ui/src/components/failed-notification-banner.tsx @@ -0,0 +1,64 @@ +import { Show, createMemo, createEffect, type Component } from "solid-js" +import { AlertCircle } from "lucide-solid" +import { failedNotificationsMap, ensureLoaded, getStorageKeyForFolder } from "../stores/failed-notifications" + +interface FailedNotificationBannerProps { + folderPath: string + onClick: () => void +} + +const FailedNotificationBanner: Component = (props) => { + // Debug log to see what folder path we're using + createEffect(() => { + if (import.meta.env.DEV) { + console.log("[FailedNotificationBanner] Mounted with folderPath:", props.folderPath) + console.log("[FailedNotificationBanner] folderPath type:", typeof props.folderPath) + console.log("[FailedNotificationBanner] folderPath value:", JSON.stringify(props.folderPath)) + const storageKey = getStorageKeyForFolder(props.folderPath) + console.log("[FailedNotificationBanner] Storage key:", storageKey) + } + }) + + // Access signal directly for proper reactivity + const count = createMemo(() => { + ensureLoaded(props.folderPath) + const map = failedNotificationsMap() + const result = (map.get(props.folderPath) ?? []).length + if (import.meta.env.DEV) { + console.log("[FailedNotificationBanner] Computed count:", result, "for folder:", props.folderPath) + } + return result + }) + const hasFailedNotifications = createMemo(() => count() > 0) + const label = createMemo(() => { + const num = count() + return `${num} failed notification${num === 1 ? "" : "s"}` + }) + + // Debug logging + createEffect(() => { + const currentCount = count() + if (import.meta.env.DEV) { + console.log(`[FailedNotificationBanner] Current count: ${currentCount}, hasNotifications: ${hasFailedNotifications()}`) + } + }) + + return ( + + + + ) +} + +export default FailedNotificationBanner diff --git a/packages/ui/src/components/failed-notification-panel.tsx b/packages/ui/src/components/failed-notification-panel.tsx new file mode 100644 index 00000000..5ee6c21f --- /dev/null +++ b/packages/ui/src/components/failed-notification-panel.tsx @@ -0,0 +1,265 @@ +import { Show, For, createMemo, createSignal, type Component } from "solid-js" +import { Dialog } from "@kobalte/core" +import { X, MessageCircleQuestion, ShieldAlert, ChevronDown, ChevronUp } from "lucide-solid" +import { + failedNotificationsMap, + ensureLoaded, + removeFailedNotification, + dismissAllFailedNotifications, + type FailedNotification, +} from "../stores/failed-notifications" +import { getPermissionDisplayTitle, getPermissionKind, getPermissionPatterns } from "../types/permission" +import { Markdown } from "./markdown" +import type { TextPart } from "../types/message" + +interface FailedNotificationPanelProps { + folderPath: string + isOpen: boolean + onClose: () => void +} + +const FailedNotificationPanel: Component = (props) => { + // Track which notifications are expanded + const [expandedIds, setExpandedIds] = createSignal>(new Set()) + + // Access signal directly for proper reactivity + const notifications = createMemo(() => { + ensureLoaded(props.folderPath) + const map = failedNotificationsMap() + return map.get(props.folderPath) ?? [] + }) + const hasNotifications = createMemo(() => notifications().length > 0) + + const isExpanded = (id: string) => expandedIds().has(id) + + const toggleExpanded = (id: string) => { + setExpandedIds((prev) => { + const next = new Set(prev) + if (next.has(id)) { + next.delete(id) + } else { + next.add(id) + } + return next + }) + } + + const handleDismiss = (notificationId: string) => { + removeFailedNotification(props.folderPath, notificationId) + // Close panel if no more notifications (check in next tick after state updates) + queueMicrotask(() => { + if (notifications().length === 0) { + props.onClose() + } + }) + } + + const handleDismissAll = () => { + dismissAllFailedNotifications(props.folderPath) + props.onClose() + } + + const formatTimestamp = (timestamp: number): string => { + const now = Date.now() + const diff = now - timestamp + const seconds = Math.floor(diff / 1000) + const minutes = Math.floor(seconds / 60) + const hours = Math.floor(minutes / 60) + const days = Math.floor(hours / 24) + + if (seconds < 60) { + return "just now" + } else if (minutes < 60) { + return `${minutes}m ago` + } else if (hours < 24) { + return `${hours}h ago` + } else { + return `${days}d ago` + } + } + + const getReasonLabel = (reason: FailedNotification["reason"]): string => { + switch (reason) { + case "timeout": + return "Request timeout" + case "session-stop": + return "Session stopped" + case "cancelled": + return "Cancelled" + default: + return reason + } + } + + const getTitleForNotification = (notification: FailedNotification): string => { + if (notification.type === "question" && notification.questionData) { + return notification.questionData.questions[0]?.question || "Question" + } else if (notification.type === "permission" && notification.permissionData) { + return getPermissionDisplayTitle(notification.permissionData.permission) + } + return notification.title + } + + const createTextPart = (id: string, text: string): TextPart => ({ + id: `${id}-text`, + type: "text", + text, + }) + + return ( + !open && props.onClose()}> + + +
+ +
+ Failed Notifications +
+ + + + + + +
+
+ +
+ +

No failed notifications

+
+ } + > +
+ + {(notification) => { + const expanded = createMemo(() => isExpanded(notification.id)) + return ( +
+
+ } + > + + +
+
+
+
+ {getTitleForNotification(notification)} +
+
+ + {getReasonLabel(notification.reason)} + + + + {formatTimestamp(notification.timestamp)} + +
+
+ + +
+ + + {(q, index) => ( +
+
Question
+
+ +
+ 0}> +
Options
+
    + + {(opt) => ( +
  • + {opt.label} + + {opt.description} + +
  • + )} +
    +
+
+
+ )} +
+
+ + +
+
+ Type: + + {getPermissionKind(notification.permissionData!.permission)} + +
+
+ Resources: +
+ + {(pattern) => ( +
{pattern}
+ )} +
+
+
+
+
+
+
+
+ +
+ + +
+
+ ) + }} +
+
+ +
+ +
+
+ + ) +} + +export default FailedNotificationPanel diff --git a/packages/ui/src/components/file-viewer/monaco-diff-viewer.tsx b/packages/ui/src/components/file-viewer/monaco-diff-viewer.tsx new file mode 100644 index 00000000..6c6b71de --- /dev/null +++ b/packages/ui/src/components/file-viewer/monaco-diff-viewer.tsx @@ -0,0 +1,116 @@ +import { createEffect, createSignal, onCleanup, onMount } from "solid-js" +import { loadMonaco } from "../../lib/monaco/setup" +import { getOrCreateTextModel } from "../../lib/monaco/model-cache" +import { inferMonacoLanguageId } from "../../lib/monaco/language" +import { ensureMonacoLanguageLoaded } from "../../lib/monaco/setup" +import { useTheme } from "../../lib/theme" + +interface MonacoDiffViewerProps { + scopeKey: string + path: string + before: string + after: string + viewMode?: "split" | "unified" + contextMode?: "expanded" | "collapsed" +} + +export function MonacoDiffViewer(props: MonacoDiffViewerProps) { + const { isDark } = useTheme() + let host: HTMLDivElement | undefined + + let diffEditor: any = null + let monaco: any = null + const [ready, setReady] = createSignal(false) + + const disposeEditor = () => { + try { + diffEditor?.setModel(null as any) + } catch { + // ignore + } + try { + diffEditor?.dispose() + } catch { + // ignore + } + diffEditor = null + } + + onMount(() => { + let cancelled = false + void (async () => { + monaco = await loadMonaco() + if (cancelled) return + if (!host || !monaco) return + + monaco.editor.setTheme(isDark() ? "vs-dark" : "vs") + diffEditor = monaco.editor.createDiffEditor(host, { + readOnly: true, + automaticLayout: true, + renderSideBySide: true, + renderSideBySideInlineBreakpoint: 0, + renderMarginRevertIcon: false, + minimap: { enabled: false }, + scrollBeyondLastLine: false, + renderWhitespace: "selection", + fontSize: 13, + wordWrap: "off", + glyphMargin: false, + folding: false, + // Keep enough gutter space so unified diffs don't overlap `+`/`-` markers. + lineNumbersMinChars: 4, + lineDecorationsWidth: 12, + }) + + setReady(true) + })() + + onCleanup(() => { + cancelled = true + setReady(false) + disposeEditor() + }) + }) + + createEffect(() => { + if (!ready() || !monaco || !diffEditor) return + monaco.editor.setTheme(isDark() ? "vs-dark" : "vs") + }) + + createEffect(() => { + if (!ready() || !monaco || !diffEditor) return + const viewMode = props.viewMode === "unified" ? "unified" : "split" + const contextMode = props.contextMode === "collapsed" ? "collapsed" : "expanded" + + diffEditor.updateOptions({ + renderSideBySide: viewMode === "split", + renderSideBySideInlineBreakpoint: 0, + hideUnchangedRegions: + contextMode === "collapsed" + ? { enabled: true } + : { enabled: false }, + }) + }) + + createEffect(() => { + if (!ready() || !monaco || !diffEditor) return + const languageId = inferMonacoLanguageId(monaco, props.path) + const beforeKey = `${props.scopeKey}:diff:${props.path}:before` + const afterKey = `${props.scopeKey}:diff:${props.path}:after` + + const original = getOrCreateTextModel({ monaco, cacheKey: beforeKey, value: props.before, languageId }) + const modified = getOrCreateTextModel({ monaco, cacheKey: afterKey, value: props.after, languageId }) + diffEditor.setModel({ original, modified }) + + void ensureMonacoLanguageLoaded(languageId).then(() => { + try { + monaco.editor.setModelLanguage(original, languageId) + monaco.editor.setModelLanguage(modified, languageId) + } catch { + // ignore + } + }) + }) + + return
+} diff --git a/packages/ui/src/components/file-viewer/monaco-file-viewer.tsx b/packages/ui/src/components/file-viewer/monaco-file-viewer.tsx new file mode 100644 index 00000000..cffecf2d --- /dev/null +++ b/packages/ui/src/components/file-viewer/monaco-file-viewer.tsx @@ -0,0 +1,89 @@ +import { createEffect, createSignal, onCleanup, onMount } from "solid-js" +import { loadMonaco } from "../../lib/monaco/setup" +import { getOrCreateTextModel } from "../../lib/monaco/model-cache" +import { inferMonacoLanguageId } from "../../lib/monaco/language" +import { ensureMonacoLanguageLoaded } from "../../lib/monaco/setup" +import { useTheme } from "../../lib/theme" + +interface MonacoFileViewerProps { + scopeKey: string + path: string + content: string +} + +export function MonacoFileViewer(props: MonacoFileViewerProps) { + const { isDark } = useTheme() + let host: HTMLDivElement | undefined + + let editor: any = null + let monaco: any = null + const [ready, setReady] = createSignal(false) + + const disposeEditor = () => { + try { + editor?.setModel(null) + } catch { + // ignore + } + try { + editor?.dispose() + } catch { + // ignore + } + editor = null + } + + onMount(() => { + let cancelled = false + void (async () => { + monaco = await loadMonaco() + if (cancelled) return + if (!host || !monaco) return + + monaco.editor.setTheme(isDark() ? "vs-dark" : "vs") + editor = monaco.editor.create(host, { + value: "", + language: "plaintext", + readOnly: true, + automaticLayout: true, + lineNumbers: "on", + minimap: { enabled: false }, + scrollBeyondLastLine: false, + wordWrap: "off", + renderWhitespace: "selection", + fontSize: 13, + }) + + setReady(true) + })() + + onCleanup(() => { + cancelled = true + setReady(false) + disposeEditor() + }) + }) + + createEffect(() => { + if (!ready() || !monaco || !editor) return + monaco.editor.setTheme(isDark() ? "vs-dark" : "vs") + }) + + createEffect(() => { + if (!ready() || !monaco || !editor) return + const languageId = inferMonacoLanguageId(monaco, props.path) + const cacheKey = `${props.scopeKey}:file:${props.path}` + const model = getOrCreateTextModel({ monaco, cacheKey, value: props.content, languageId }) + editor.setModel(model) + + void ensureMonacoLanguageLoaded(languageId).then(() => { + try { + monaco.editor.setModelLanguage(model, languageId) + } catch { + // ignore + } + }) + }) + + return
+} diff --git a/packages/ui/src/components/folder-selection-view.tsx b/packages/ui/src/components/folder-selection-view.tsx index a77e3547..281ea084 100644 --- a/packages/ui/src/components/folder-selection-view.tsx +++ b/packages/ui/src/components/folder-selection-view.tsx @@ -254,12 +254,63 @@ const FolderSelectionView: Component = (props) => { function getDisplayPath(path: string): string { + if (!path) return path + + // macOS: /Users//... if (path.startsWith("/Users/")) { return path.replace(/^\/Users\/[^/]+/, "~") } + + // Linux: /home//... + if (path.startsWith("/home/")) { + return path.replace(/^\/home\/[^/]+/, "~") + } + + // Windows: C:\Users\\... (and the forward-slash variant) + if (/^[A-Za-z]:\\Users\\/.test(path)) { + return path.replace(/^[A-Za-z]:\\Users\\[^\\]+/, "~") + } + if (/^[A-Za-z]:\/Users\//.test(path)) { + return path.replace(/^[A-Za-z]:\/Users\/[^/]+/, "~") + } + return path } + function looksLikeWindowsPath(value: string): boolean { + if (!value) return false + // Drive letter (C:\...) or UNC (\\server\share\...) + return /^[A-Za-z]:[\\/]/.test(value) || /^\\\\[^\\]+\\[^\\]+/.test(value) + } + + function splitFolderPath(rawPath: string): { baseName: string; dirName: string } { + if (!rawPath) return { baseName: "", dirName: "" } + + const isWindows = looksLikeWindowsPath(rawPath) + const trimmed = rawPath.replace(/[\\/]+$/, "") + + // Root edge-cases ("/", "C:\\", "\\\\server\\share\\") + if (!trimmed) { + return { baseName: rawPath, dirName: "" } + } + + if (isWindows && /^[A-Za-z]:$/.test(trimmed)) { + return { baseName: `${trimmed}\\`, dirName: "" } + } + + const lastSlash = trimmed.lastIndexOf("/") + const lastBackslash = isWindows ? trimmed.lastIndexOf("\\") : -1 + const lastSep = Math.max(lastSlash, lastBackslash) + + if (lastSep < 0) { + return { baseName: trimmed, dirName: "" } + } + + const baseName = trimmed.slice(lastSep + 1) || trimmed + const dirName = trimmed.slice(0, lastSep) + return { baseName, dirName } + } + return ( <>
= (props) => {
- {folder.path.split("/").pop()} + {splitFolderPath(folder.path).baseName}
-
- {getDisplayPath(folder.path)} -
-
- {formatRelativeTime(folder.lastAccessed)} +
+ + {getDisplayPath(folder.path)} + + {formatRelativeTime(folder.lastAccessed)}
diff --git a/packages/ui/src/components/folder-tree-browser.tsx b/packages/ui/src/components/folder-tree-browser.tsx new file mode 100644 index 00000000..3afad018 --- /dev/null +++ b/packages/ui/src/components/folder-tree-browser.tsx @@ -0,0 +1,251 @@ +import { Component, createSignal, Show, createEffect } from "solid-js" +import { Dialog } from "@kobalte/core/dialog" +import { X, FolderTree } from "lucide-solid" +import { serverApi } from "../lib/api-client" +import { useMarkdownPreview } from "../lib/hooks/use-markdown-preview" +import FolderTreeNode from "./folder-tree-node" +import MarkdownPreviewModal from "./markdown-preview-modal" +import type { FileSystemEntry } from "../../../server/src/api-types" +import { getLogger } from "../lib/logger" + +const log = getLogger("api") + +/** + * Props for FolderTreeBrowser component + */ +interface FolderTreeBrowserProps { + /** Whether the browser modal is open */ + isOpen: boolean + + /** Workspace ID to browse files from */ + workspaceId: string + + /** Workspace display name (optional) */ + workspaceName?: string + + /** Callback when modal closes */ + onClose: () => void +} + +/** + * Folder Tree Browser Modal Component + * + * VSCode-style file tree browser that displays workspace files and folders. + * + * Features: + * - Collapsible folder tree structure + * - Double-click markdown files to preview + * - Read-only for non-markdown files + * - Lazy loading of folder contents + * - Keyboard navigation support + * + * @example + * setBrowserOpen(false)} + * /> + */ +const FolderTreeBrowser: Component = (props) => { + const [rootEntries, setRootEntries] = createSignal([]) + const [isLoadingRoot, setIsLoadingRoot] = createSignal(false) + const [rootError, setRootError] = createSignal(null) + const [previewFile, setPreviewFile] = createSignal(null) + const preview = useMarkdownPreview() + + /** + * Fetch root directory entries when modal opens + */ + createEffect(() => { + if (props.isOpen && rootEntries().length === 0 && !isLoadingRoot()) { + void loadRootDirectory() + } + }) + + /** + * Fetch root directory contents + */ + async function loadRootDirectory() { + setIsLoadingRoot(true) + setRootError(null) + try { + log.info("Loading root directory for workspace:", props.workspaceId) + const entries = await serverApi.listWorkspaceFiles(props.workspaceId, ".") + + // Sort: directories first, then files, both alphabetically + const sorted = entries.sort((a, b) => { + if (a.type === b.type) { + return a.name.localeCompare(b.name) + } + return a.type === "directory" ? -1 : 1 + }) + + setRootEntries(sorted) + log.info("Loaded root directory:", sorted.length, "entries") + } catch (err) { + const message = err instanceof Error ? err.message : "Failed to load workspace files" + log.error("Failed to load root directory:", err) + setRootError(message) + } finally { + setIsLoadingRoot(false) + } + } + + /** + * Fetch children for a directory (used by FolderTreeNode) + */ + async function fetchChildren(_workspaceId: string, path: string): Promise { + log.info("Fetching children for path:", path) + return await serverApi.listWorkspaceFiles(props.workspaceId, path) + } + + /** + * Handle double-click on a file + * - Markdown files: open preview modal + * - Other files: no action (read-only) + */ + function handleFileDoubleClick(entry: FileSystemEntry) { + log.info("File double-clicked:", entry.name, "type:", entry.type) + + if (entry.type !== "file") { + return + } + + const isMarkdown = entry.name.toLowerCase().endsWith(".md") + + if (isMarkdown) { + log.info("Opening markdown preview for:", entry.path) + setPreviewFile(entry) + void preview.fetch(entry.path) + } else { + log.info("Non-markdown file clicked - no action:", entry.name) + // Could show a toast/notification here if desired + } + } + + /** + * Close markdown preview modal + */ + function handleClosePreview() { + setPreviewFile(null) + preview.clear() + } + + /** + * Get display title for the browser + */ + const getTitle = () => { + return props.workspaceName + ? `Files - ${props.workspaceName}` + : "Workspace Files" + } + + return ( + <> + {/* Folder Tree Browser Modal */} + !open && props.onClose()}> + + + +
+ + {/* Header */} +
+
+ + + {getTitle()} + +
+ + +
+ + {/* Content area */} +
+ {/* Loading state */} + +
+
+

Loading workspace files...

+
+ + + {/* Error state */} + +
+
+
+

Could not load files

+

{rootError()}

+ +
+
+
+ + {/* Tree view */} + +
+ +
+

No files found in workspace

+
+
+ + 0}> + {rootEntries().map((entry) => ( + + ))} + +
+
+
+ + {/* Footer */} +
+

+ 💡 Double-click markdown files to preview +

+
+ +
+ +
+ + {/* Markdown Preview Modal (nested) */} + + + + + ) +} + +export default FolderTreeBrowser diff --git a/packages/ui/src/components/folder-tree-node.tsx b/packages/ui/src/components/folder-tree-node.tsx new file mode 100644 index 00000000..63a9ec28 --- /dev/null +++ b/packages/ui/src/components/folder-tree-node.tsx @@ -0,0 +1,225 @@ +import { Component, createSignal, Show, For, createEffect, onCleanup } from "solid-js" +import { ChevronRight, ChevronDown, File, Folder, FolderOpen } from "lucide-solid" +import type { FileSystemEntry } from "../../../server/src/api-types" +import { SECTION_EXPANSION_EVENT, type SectionExpansionRequest } from "../lib/section-expansion" + +/** + * Props for FolderTreeNode component + */ +interface FolderTreeNodeProps { + /** File system entry (file or directory) */ + entry: FileSystemEntry + + /** Workspace ID for API calls */ + workspaceId: string + + /** Current indentation level (0 = root) */ + level: number + + /** Callback when a file is double-clicked */ + onFileDoubleClick: (entry: FileSystemEntry) => void + + /** Function to fetch child entries for a directory */ + fetchChildren: (workspaceId: string, path: string) => Promise +} + +/** + * Recursive tree node component for displaying files and folders + * + * Features: + * - Collapsible folders with chevron indicator + * - File/folder icons + * - Double-click to open files + * - Lazy loading of folder contents + * - Keyboard accessible + */ +const FolderTreeNode: Component = (props) => { + const [isExpanded, setIsExpanded] = createSignal(false) + const [children, setChildren] = createSignal([]) + const [isLoading, setIsLoading] = createSignal(false) + const [error, setError] = createSignal(null) + + // Listen for folder expansion requests from search system + createEffect(() => { + if (typeof window === "undefined") return + + const handler = (event: Event) => { + const detail = (event as CustomEvent).detail + if ( + detail.action === "expand-folder-node" && + detail.elementId === props.entry.path + ) { + // Auto-expand the folder + setIsExpanded(true) + } + } + + window.addEventListener(SECTION_EXPANSION_EVENT, handler) + onCleanup(() => window.removeEventListener(SECTION_EXPANSION_EVENT, handler)) + }) + + const isDirectory = () => props.entry.type === "directory" + const isMarkdownFile = () => { + return props.entry.type === "file" && props.entry.name.toLowerCase().endsWith(".md") + } + + /** + * Toggle folder expand/collapse + */ + async function handleToggle() { + if (!isDirectory()) return + + if (!isExpanded()) { + // Expanding - fetch children if not already loaded + if (children().length === 0 && !isLoading() && !error()) { + setIsLoading(true) + setError(null) + try { + const entries = await props.fetchChildren(props.workspaceId, props.entry.path) + // Sort: directories first, then files, both alphabetically + const sorted = entries.sort((a, b) => { + if (a.type === b.type) { + return a.name.localeCompare(b.name) + } + return a.type === "directory" ? -1 : 1 + }) + setChildren(sorted) + } catch (err) { + const message = err instanceof Error ? err.message : "Failed to load folder contents" + setError(message) + } finally { + setIsLoading(false) + } + } + setIsExpanded(true) + } else { + // Collapsing + setIsExpanded(false) + } + } + + /** + * Handle double-click on files + */ + function handleDoubleClick(e: MouseEvent) { + if (isDirectory()) { + // For directories, just toggle + void handleToggle() + } else { + // For files, trigger callback + e.stopPropagation() + props.onFileDoubleClick(props.entry) + } + } + + /** + * Handle single click for directories (toggle expand/collapse) + */ + function handleClick(e: MouseEvent) { + if (isDirectory()) { + e.stopPropagation() + void handleToggle() + } + } + + /** + * Handle keyboard navigation + */ + function handleKeyDown(e: KeyboardEvent) { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault() + if (isDirectory()) { + void handleToggle() + } else { + props.onFileDoubleClick(props.entry) + } + } else if (e.key === "ArrowRight" && isDirectory() && !isExpanded()) { + e.preventDefault() + void handleToggle() + } else if (e.key === "ArrowLeft" && isDirectory() && isExpanded()) { + e.preventDefault() + setIsExpanded(false) + } + } + + return ( +
+ {/* Node row */} +
+ {/* Chevron icon for directories */} + + + }> + + + + + + {/* File/Folder icon */} + + }> + }> + + + + + + {/* Name */} + {props.entry.name} +
+ + {/* Children (for expanded directories) */} + +
+ {/* Loading state */} + +
+ + Loading... +
+
+ + {/* Error state */} + +
+ ⚠ {error()} +
+
+ + {/* Child nodes */} + + + {(childEntry) => ( + + )} + + +
+
+
+ ) +} + +export default FolderTreeNode diff --git a/packages/ui/src/components/hint-row.tsx b/packages/ui/src/components/hint-row.tsx index 40d3745c..af3829b3 100644 --- a/packages/ui/src/components/hint-row.tsx +++ b/packages/ui/src/components/hint-row.tsx @@ -3,10 +3,15 @@ import { Component, JSX } from "solid-js" interface HintRowProps { children: JSX.Element class?: string + ariaHidden?: boolean } const HintRow: Component = (props) => { - return {props.children} + return ( + + {props.children} + + ) } export default HintRow diff --git a/packages/ui/src/components/instance-tab.tsx b/packages/ui/src/components/instance-tab.tsx index 3fd8f6dd..f345f637 100644 --- a/packages/ui/src/components/instance-tab.tsx +++ b/packages/ui/src/components/instance-tab.tsx @@ -11,20 +11,11 @@ interface InstanceTabProps { onClose: () => void } -function formatFolderName(path: string, instances: Instance[], currentInstance: Instance): string { - const name = path.split("/").pop() || path - - const duplicates = instances.filter((i) => { - const iName = i.folder.split("/").pop() || i.folder - return iName === name - }) - - if (duplicates.length > 1) { - const index = duplicates.findIndex((i) => i.id === currentInstance.id) - return `~/${name} (${index + 1})` - } - - return `~/${name}` +function getPathBasename(path: string): string { + // Instance folders can be POSIX-like (/Users/...) on macOS/Linux or Windows-like (C:\Users\...). + // Normalize by trimming trailing separators and then splitting on both '/' and '\\'. + const normalized = path.replace(/[\\/]+$/, "") + return normalized.split(/[\\/]/).pop() || path } const InstanceTab: Component = (props) => { @@ -58,7 +49,7 @@ const InstanceTab: Component = (props) => { > - {props.instance.folder.split("/").pop() || props.instance.folder} + {getPathBasename(props.instance.folder)} @@ -18,6 +22,21 @@ interface InstanceTabsProps { const InstanceTabs: Component = (props) => { const { t } = useI18n() + const { preferences } = useConfig() + const [notificationsOpen, setNotificationsOpen] = createSignal(false) + + const notificationsSupported = createMemo(() => isOsNotificationSupportedSync()) + const notificationsEnabled = createMemo(() => Boolean(preferences().osNotificationsEnabled)) + const notificationIcon = createMemo(() => { + if (!notificationsSupported()) return BellOff + return notificationsEnabled() ? Bell : BellOff + }) + + const notificationTitle = createMemo(() => { + if (!notificationsSupported()) return "Notifications unsupported" + return notificationsEnabled() ? "Notifications enabled" : "Notifications disabled" + }) + return (
@@ -54,6 +73,16 @@ const InstanceTabs: Component = (props) => {
+ + +
+ + setNotificationsOpen(false)} />
) diff --git a/packages/ui/src/components/instance-welcome-view.tsx b/packages/ui/src/components/instance-welcome-view.tsx index 38622aed..832fd26c 100644 --- a/packages/ui/src/components/instance-welcome-view.tsx +++ b/packages/ui/src/components/instance-welcome-view.tsx @@ -37,7 +37,7 @@ const InstanceWelcomeView: Component = (props) => { const deleting = loading().deletingSession.get(props.instance.id) return deleting ? deleting.has(sessionId) : false } - const newSessionShortcut = createMemo(() => { + const _newSessionShortcut = createMemo(() => { const registered = keyboardRegistry.get("session-new") if (registered) return registered return { @@ -256,7 +256,7 @@ const InstanceWelcomeView: Component = (props) => { return t("time.relative.justNow") } - function formatTimestamp(timestamp: number): string { + function _formatTimestamp(timestamp: number): string { return new Date(timestamp).toLocaleString() } diff --git a/packages/ui/src/components/instance/instance-shell2.tsx b/packages/ui/src/components/instance/instance-shell2.tsx index 68f76bc8..5a3f14f4 100644 --- a/packages/ui/src/components/instance/instance-shell2.tsx +++ b/packages/ui/src/components/instance/instance-shell2.tsx @@ -12,15 +12,15 @@ import { } from "solid-js" import type { ToolState } from "@opencode-ai/sdk" import { Accordion } from "@kobalte/core" -import { ChevronDown, TerminalSquare, Trash2, XOctagon } from "lucide-solid" +import { ChevronDown, TerminalSquare, Trash2, XOctagon, FolderTree } from "lucide-solid" import AppBar from "@suid/material/AppBar" import Box from "@suid/material/Box" +import Divider from "@suid/material/Divider" import Drawer from "@suid/material/Drawer" import IconButton from "@suid/material/IconButton" import Toolbar from "@suid/material/Toolbar" import Typography from "@suid/material/Typography" import useMediaQuery from "@suid/material/useMediaQuery" -import CloseIcon from "@suid/icons-material/Close" import MenuIcon from "@suid/icons-material/Menu" import MenuOpenIcon from "@suid/icons-material/MenuOpen" import PushPinIcon from "@suid/icons-material/PushPin" @@ -30,6 +30,7 @@ import type { Instance } from "../../types/instance" import type { Command } from "../../lib/commands" import type { BackgroundProcess } from "../../../../server/src/api-types" import type { Session } from "../../types/session" +import { SECTION_EXPANSION_EVENT, type SectionExpansionRequest } from "../../lib/section-expansion" import { activeParentSessionId, activeSessionId as activeSessionMap, @@ -45,6 +46,7 @@ import { messageStoreBus } from "../../stores/message-v2/bus" import { clearSessionRenderCache } from "../message-block" import { isOpen as isCommandPaletteOpen, hideCommandPalette, showCommandPalette } from "../../stores/command-palette" +import { openSearch } from "../../stores/search-store" import SessionList from "../session-list" import KeyboardHint from "../keyboard-hint" import Kbd from "../kbd" @@ -55,23 +57,34 @@ import AgentSelector from "../agent-selector" import ModelSelector from "../model-selector" import ThinkingSelector from "../thinking-selector" import CommandPalette from "../command-palette" +import FolderTreeBrowser from "../folder-tree-browser" import PermissionNotificationBanner from "../permission-notification-banner" import PermissionApprovalModal from "../permission-approval-modal" +import QuestionNotificationBanner from "../question-notification-banner" +import FailedNotificationBanner from "../failed-notification-banner" +import FailedNotificationPanel from "../failed-notification-panel" +import { AskQuestionWizard } from "../askquestion-wizard" import { TodoListView } from "../tool-call/renderers/todo" import ContextUsagePanel from "../session/context-usage-panel" import SessionView from "../session/session-view" import { formatTokenTotal } from "../../lib/formatters" import { sseManager } from "../../lib/sse-manager" +import "../../styles/components/failed-notification.css" import { getLogger } from "../../lib/logger" import { serverApi } from "../../lib/api-client" import { getBackgroundProcesses, loadBackgroundProcesses } from "../../stores/background-processes" import { BackgroundProcessOutputDialog } from "../background-process-output-dialog" import { useI18n } from "../../lib/i18n" +import SourceControlPanel from "../source-control/source-control-panel" import { SESSION_SIDEBAR_EVENT, type SessionSidebarRequestAction, type SessionSidebarRequestDetail, } from "../../lib/session-sidebar-events" +import { getPendingQuestion, removeQuestionFromQueue } from "../../stores/questions" +import type { QuestionAnswer } from "../../types/question" +import { sendMcpAnswer, sendMcpCancel, initMcpBridge, cleanupMcpBridge, clearProcessedQuestion, isMcpBridgeInitialized } from "../../lib/mcp-bridge" +import { requestData } from "../../lib/opencode-api" const log = getLogger("session") @@ -87,9 +100,9 @@ interface InstanceShellProps { tabBarOffset: number } -const DEFAULT_SESSION_SIDEBAR_WIDTH = 340 +const DEFAULT_SESSION_SIDEBAR_WIDTH = 280 const MIN_SESSION_SIDEBAR_WIDTH = 220 -const MAX_SESSION_SIDEBAR_WIDTH = 400 +const MAX_SESSION_SIDEBAR_WIDTH = 360 const RIGHT_DRAWER_WIDTH = 260 const MIN_RIGHT_DRAWER_WIDTH = 200 const MAX_RIGHT_DRAWER_WIDTH = 380 @@ -142,6 +155,7 @@ const InstanceShell2: Component = (props) => { const [resizeStartX, setResizeStartX] = createSignal(0) const [resizeStartWidth, setResizeStartWidth] = createSignal(0) const [rightPanelExpandedItems, setRightPanelExpandedItems] = createSignal([ + "source-control", "plan", "background-processes", "mcp", @@ -150,10 +164,27 @@ const InstanceShell2: Component = (props) => { ]) const [selectedBackgroundProcess, setSelectedBackgroundProcess] = createSignal(null) const [showBackgroundOutput, setShowBackgroundOutput] = createSignal(false) + const [folderTreeBrowserOpen, setFolderTreeBrowserOpen] = createSignal(false) const [permissionModalOpen, setPermissionModalOpen] = createSignal(false) + const [questionWizardOpen, setQuestionWizardOpen] = createSignal(false) + const [questionWizardMinimized, setQuestionWizardMinimized] = createSignal(false) + const [failedPanelOpen, setFailedPanelOpen] = createSignal(false) const messageStore = createMemo(() => messageStoreBus.getOrCreate(props.instance.id)) + // Reactive memo to track pending questions - properly triggers Show component updates + const pendingQuestion = createMemo(() => { + const result = getPendingQuestion(props.instance.id) + if (import.meta.env.DEV) { + console.log('[Instance Shell] pendingQuestion memo computed:', { + instanceId: props.instance.id, + pendingId: result?.id ?? null, + hasResult: !!result + }) + } + return result + }) + const desktopQuery = useMediaQuery("(min-width: 1280px)") const tabletQuery = useMediaQuery("(min-width: 768px)") @@ -209,6 +240,169 @@ const InstanceShell2: Component = (props) => { } }) + // Auto-open question wizard when a pending question appears (unless minimized) + // Uses pendingQuestion() memo for proper SolidJS reactivity + createEffect(() => { + if (import.meta.env.DEV) { + console.log('[Instance Shell] createEffect TRIGGERED (reactive update)') + } + const pending = pendingQuestion() + if (import.meta.env.DEV) { + console.log('[Instance Shell] createEffect check:', { + instanceId: props.instance.id, + pendingQuestionId: pending?.id ?? null, + minimized: questionWizardMinimized(), + willOpen: !!(pending && !questionWizardMinimized()) + }) + } + if (pending && !questionWizardMinimized()) { + // Auto-open only if user hasn't minimized + if (import.meta.env.DEV) { + console.log('[Instance Shell] Opening question wizard for:', pending.id) + } + setQuestionWizardOpen(true) + // Note: render confirmation is sent from AskQuestionWizard's onMount + // to ensure it's only sent when the wizard is actually visible + } else if (!pending) { + // Reset states when no pending questions + if (import.meta.env.DEV) { + console.log('[Instance Shell] No pending question, closing wizard') + } + setQuestionWizardOpen(false) + setQuestionWizardMinimized(false) + } + }) + + // Question wizard handlers - defined at component level for proper binding + const handleQuestionSubmit = async (answers: QuestionAnswer[]) => { + const question = getPendingQuestion(props.instance.id) + if (!question || !props.instance.client) { + return + } + + if (import.meta.env.DEV) { + console.log('[✅ ANSWER SUBMIT] Question answer submitted:', { + questionId: question.id, + source: question.source || 'NOT_SET', + instanceId: props.instance.id, + hasAnswers: answers.length > 0, + timestamp: new Date().toISOString() + }) + } + + // Route by source: MCP or OpenCode + if (question.source === 'mcp') { + if (import.meta.env.DEV) { + console.log('[✅ ROUTING] Using MCP path (zero-cost IPC) for question:', question.id) + } + // MCP questions: send via IPC bridge + try { + sendMcpAnswer(question.id, answers) + removeQuestionFromQueue(props.instance.id, question.id) + clearProcessedQuestion(question.id) // Clear from deduplication set + setQuestionWizardOpen(false) + if (import.meta.env.DEV) { + console.log('[✅ MCP SUCCESS] Answer sent via MCP IPC, no premium request') + } + } catch (error) { + console.error("Failed to submit MCP question answer", error) + } + + } else { + if (import.meta.env.DEV) { + console.log('[❌ ROUTING] Using OpenCode SDK path (PREMIUM REQUEST) for question:', question.id) + console.log('[❌ WARNING] This will consume 1 premium LLM request!') + } + // OpenCode questions: use existing API + try { + // Map answers to SDK format: array of string arrays + const sdkAnswers = answers.map(answer => { + const custom = answer.customText?.trim() + if (custom) return [custom] + return answer.values + }) + + await requestData( + props.instance.client.question.reply({ + requestID: question.id, + answers: sdkAnswers + }), + "question.reply" + ) + + setQuestionWizardOpen(false) + if (import.meta.env.DEV) { + console.log('[❌ OPENCODE COMPLETED] Answer sent via OpenCode SDK (premium request used)') + } + } catch (error) { + console.error("Failed to submit question answers", error) + } + } + } + + + const handleQuestionCancel = async () => { + const question = getPendingQuestion(props.instance.id) + if (!question) { + setQuestionWizardOpen(false) + return + } + + if (import.meta.env.DEV) { + console.log('[🚫 CANCEL] Question cancelled:', { + questionId: question.id, + source: question.source || 'NOT_SET', + instanceId: props.instance.id + }) + } + + // Route by source: MCP or OpenCode + if (question.source === 'mcp') { + if (import.meta.env.DEV) { + console.log('[🚫 ROUTING] Using MCP cancel path (zero-cost) for question:', question.id) + } + // MCP questions: send via IPC bridge + try { + sendMcpCancel(question.id) + removeQuestionFromQueue(props.instance.id, question.id) + clearProcessedQuestion(question.id) // Clear from deduplication set + setQuestionWizardOpen(false) + } catch (error) { + console.error("Failed to cancel MCP question", error) + } + + } else { + if (import.meta.env.DEV) { + console.log('[🚫 ROUTING] Using OpenCode SDK cancel path for question:', question.id) + } + // OpenCode questions: use existing API + if (!props.instance.client) { + setQuestionWizardOpen(false) + return + } + + try { + await requestData( + props.instance.client.question.reject({ + requestID: question.id + }), + "question.reject" + ) + + setQuestionWizardOpen(false) + } catch (error) { + console.error("Failed to reject question", error) + setQuestionWizardOpen(false) + } + } + } + + const handleQuestionMinimize = () => { + setQuestionWizardMinimized(true) + setQuestionWizardOpen(false) + // Question remains in queue, notification banner will show + } + const measureDrawerHost = () => { if (typeof window === "undefined") return const host = drawerHost() @@ -293,7 +487,7 @@ const InstanceShell2: Component = (props) => { return activeSessionMap().get(props.instance.id) || null }) - const parentSessionIdForInstance = createMemo(() => { + const _parentSessionIdForInstance = createMemo(() => { return activeParentSessionId().get(props.instance.id) || null }) @@ -371,6 +565,11 @@ const InstanceShell2: Component = (props) => { showCommandPalette(props.instance.id) } + const _openCurrentSessionSearch = () => { + const currentSessionId = activeSessionIdForInstance() + openSearch(props.instance.id, currentSessionId || undefined) + } + const openBackgroundOutput = (process: BackgroundProcess) => { setSelectedBackgroundProcess(process) setShowBackgroundOutput(true) @@ -511,6 +710,43 @@ const InstanceShell2: Component = (props) => { onCleanup(() => window.removeEventListener("keydown", handleEscape, true)) }) + // Initialize MCP bridge for this instance + onMount(() => { + if (import.meta.env.DEV) { + console.log('[Instance Shell] onMount fired - checking window...') + console.log('[Instance Shell] window type:', typeof window) + console.log('[Instance Shell] window exists:', typeof window !== 'undefined') + } + if (typeof window === "undefined") { + if (import.meta.env.DEV) { + console.log('[Instance Shell] window is undefined, skipping MCP bridge init') + } + return + } + try { + if (!isMcpBridgeInitialized(props.instance.id)) { + if (import.meta.env.DEV) { + console.log(`[Instance Shell] Initializing MCP bridge for instance: ${props.instance.id}`) + } + initMcpBridge(props.instance.id) + } + } catch (error) { + console.error("[Instance Shell] Failed to initialize MCP bridge:", error) + } + + // Cleanup MCP bridge when instance unmounts + onCleanup(() => { + if (import.meta.env.DEV) { + console.log(`[Instance Shell] Cleaning up MCP bridge for instance: ${props.instance.id}`) + } + try { + cleanupMcpBridge(props.instance.id) + } catch (error) { + console.error("[Instance Shell] Failed to cleanup MCP bridge:", error) + } + }) + }) + const handleSessionSelect = (sessionId: string) => { if (sessionId === "info") { setActiveSession(props.instance.id, sessionId) @@ -874,7 +1110,7 @@ const InstanceShell2: Component = (props) => { -
+
= (props) => { void result.catch((error) => log.error("Failed to create session:", error)) } }} - enableFilterBar showHeader={false} showFooter={false} /> -
+ {(activeSession) => ( <> @@ -936,12 +1171,6 @@ const InstanceShell2: Component = (props) => { /> - -
)} @@ -1025,6 +1254,11 @@ const InstanceShell2: Component = (props) => { } const sections = [ + { + id: "source-control", + label: "Source Control", + render: () => , + }, { id: "plan", labelKey: "instanceShell.rightPanel.sections.plan", @@ -1073,22 +1307,40 @@ const InstanceShell2: Component = (props) => { }, ] - createEffect(() => { - const currentExpanded = new Set(rightPanelExpandedItems()) - if (sections.every((section) => currentExpanded.has(section.id))) return - setRightPanelExpandedItems(sections.map((section) => section.id)) - }) + // Accordion state is managed by user interaction via handleAccordionChange + // No need to force all sections to be expanded const handleAccordionChange = (values: string[]) => { setRightPanelExpandedItems(values) } + // Listen for sidebar accordion expansion requests from search system + createEffect(() => { + if (typeof window === "undefined") return + + const handler = (event: Event) => { + const detail = (event as CustomEvent).detail + if ( + detail.action === "expand-sidebar-accordion" && + detail.instanceId === props.instance.id + ) { + const sectionId = detail.sectionId + if (sectionId && !rightPanelExpandedItems().includes(sectionId)) { + setRightPanelExpandedItems((prev) => [...prev, sectionId]) + } + } + } + + window.addEventListener(SECTION_EXPANSION_EVENT, handler) + onCleanup(() => window.removeEventListener(SECTION_EXPANSION_EVENT, handler)) + }) + const isSectionExpanded = (id: string) => rightPanelExpandedItems().includes(id) return (
-
- +
+ {t("instanceShell.rightPanel.title")}
@@ -1120,7 +1372,7 @@ const InstanceShell2: Component = (props) => { > - {t(section.labelKey)} + {section.labelKey ? t(section.labelKey) : section.label} @@ -1274,74 +1526,96 @@ const InstanceShell2: Component = (props) => { -
- + + {leftAppBarButtonIcon()} + + +
+ + {t("instanceShell.metrics.usedLabel")} + + {formattedUsedTokens()} +
+
+ + {t("instanceShell.metrics.availableLabel")} + + {formattedAvailableTokens()} +
+ + + - - - - - - + + + + setPermissionModalOpen(true)} + /> -
+ + { + setQuestionWizardMinimized(false) + setQuestionWizardOpen(true) + }} + /> + - - {rightAppBarButtonIcon()} - -
+ setFailedPanelOpen(true)} + /> -
-
- - {t("instanceShell.metrics.usedLabel")} - - {formattedUsedTokens()} -
-
- - {t("instanceShell.metrics.availableLabel")} - - {formattedAvailableTokens()} -
-
+ + + + + + + + + + + {rightAppBarButtonIcon()} +
} > @@ -1360,13 +1634,13 @@ const InstanceShell2: Component = (props) => {
- + {t("instanceShell.metrics.usedLabel")} {formattedUsedTokens()}
- + {t("instanceShell.metrics.availableLabel")} {formattedAvailableTokens()} @@ -1376,10 +1650,38 @@ const InstanceShell2: Component = (props) => {
- setPermissionModalOpen(true)} - /> + + + + +
+ setPermissionModalOpen(true)} + /> + + { + setQuestionWizardMinimized(false) + setQuestionWizardOpen(true) + }} + /> + + setFailedPanelOpen(true)} + /> +
+ + + +
+ +
+
+
+
+
+ +
+ + + + + + void openGitFile(path)} + onRefresh={() => void refreshGitStatus()} + listOpen={gitChangesListOpen} + onToggleList={toggleGitList} + splitWidth={gitChangesSplitWidth} + onResizeMouseDown={handleSplitResizeMouseDown("git-changes")} + onResizeTouchStart={handleSplitResizeTouchStart("git-changes")} + isPhoneLayout={props.isPhoneLayout} + /> + + + + void loadBrowserEntries(path)} + onOpenFile={(path) => void openBrowserFile(path)} + onRefresh={() => void refreshFilesTab()} + listOpen={filesListOpen} + onToggleList={toggleFilesList} + splitWidth={filesSplitWidth} + onResizeMouseDown={handleSplitResizeMouseDown("files")} + onResizeTouchStart={handleSplitResizeTouchStart("files")} + isPhoneLayout={props.isPhoneLayout} + /> + + + + + +
+
+ ) +} + +export default RightPanel diff --git a/packages/ui/src/components/instance/shell/right-panel/components/DiffToolbar.tsx b/packages/ui/src/components/instance/shell/right-panel/components/DiffToolbar.tsx new file mode 100644 index 00000000..beb249ee --- /dev/null +++ b/packages/ui/src/components/instance/shell/right-panel/components/DiffToolbar.tsx @@ -0,0 +1,53 @@ +import type { Component } from "solid-js" + +import type { DiffContextMode, DiffViewMode } from "../types" + +interface DiffToolbarProps { + viewMode: DiffViewMode + contextMode: DiffContextMode + onViewModeChange: (mode: DiffViewMode) => void + onContextModeChange: (mode: DiffContextMode) => void +} + +const DiffToolbar: Component = (props) => { + return ( +
+ + + + +
+ ) +} + +export default DiffToolbar diff --git a/packages/ui/src/components/instance/shell/right-panel/components/OverlayList.tsx b/packages/ui/src/components/instance/shell/right-panel/components/OverlayList.tsx new file mode 100644 index 00000000..43299f68 --- /dev/null +++ b/packages/ui/src/components/instance/shell/right-panel/components/OverlayList.tsx @@ -0,0 +1,16 @@ +import type { Component, JSX } from "solid-js" + +interface OverlayListProps { + ariaLabel: string + children: JSX.Element +} + +const OverlayList: Component = (props) => { + return ( + + ) +} + +export default OverlayList diff --git a/packages/ui/src/components/instance/shell/right-panel/components/SplitFilePanel.tsx b/packages/ui/src/components/instance/shell/right-panel/components/SplitFilePanel.tsx new file mode 100644 index 00000000..56fd6211 --- /dev/null +++ b/packages/ui/src/components/instance/shell/right-panel/components/SplitFilePanel.tsx @@ -0,0 +1,70 @@ +import { Show, type Component, type JSX } from "solid-js" + +import OverlayList from "./OverlayList" + +type SplitFilePanelList = { + panel: () => JSX.Element + overlay: () => JSX.Element +} + +interface SplitFilePanelProps { + header: JSX.Element + list: SplitFilePanelList + viewer: JSX.Element + + listOpen: boolean + onToggleList: () => void + + splitWidth: number + onResizeMouseDown: (event: MouseEvent) => void + onResizeTouchStart: (event: TouchEvent) => void + + isPhoneLayout: boolean + overlayAriaLabel: string +} + +const SplitFilePanel: Component = (props) => { + return ( +
+
+
+ + + {props.header} +
+
+ +
+ +
+
+
{props.list.panel()}
+
+ + + + + + {props.list.overlay()} + + +
+
+ ) +} + +export default SplitFilePanel diff --git a/packages/ui/src/components/instance/shell/right-panel/tabs/ChangesTab.tsx b/packages/ui/src/components/instance/shell/right-panel/tabs/ChangesTab.tsx new file mode 100644 index 00000000..9821d3c5 --- /dev/null +++ b/packages/ui/src/components/instance/shell/right-panel/tabs/ChangesTab.tsx @@ -0,0 +1,203 @@ +import { For, Show, type Accessor, type Component, type JSX } from "solid-js" + +import { MonacoDiffViewer } from "../../../../file-viewer/monaco-diff-viewer" + +import DiffToolbar from "../components/DiffToolbar" +import SplitFilePanel from "../components/SplitFilePanel" +import type { DiffContextMode, DiffViewMode } from "../types" + +interface ChangesTabProps { + t: (key: string, vars?: Record) => string + + instanceId: string + activeSessionId: Accessor + activeSessionDiffs: Accessor + + selectedFile: Accessor + onSelectFile: (file: string, closeList: boolean) => void + + diffViewMode: Accessor + diffContextMode: Accessor + onViewModeChange: (mode: DiffViewMode) => void + onContextModeChange: (mode: DiffContextMode) => void + + listOpen: Accessor + onToggleList: () => void + splitWidth: Accessor + onResizeMouseDown: (event: MouseEvent) => void + onResizeTouchStart: (event: TouchEvent) => void + isPhoneLayout: Accessor +} + +const ChangesTab: Component = (props) => { + const renderContent = (): JSX.Element => { + const sessionId = props.activeSessionId() + + const hasSession = Boolean(sessionId && sessionId !== "info") + const diffs = hasSession ? props.activeSessionDiffs() : null + + const sorted = Array.isArray(diffs) ? [...diffs].sort((a, b) => String(a.file || "").localeCompare(String(b.file || ""))) : [] + const totals = sorted.reduce( + (acc, item) => { + acc.additions += typeof item.additions === "number" ? item.additions : 0 + acc.deletions += typeof item.deletions === "number" ? item.deletions : 0 + return acc + }, + { additions: 0, deletions: 0 }, + ) + + const mostChanged = sorted.length + ? sorted.reduce((best, item) => { + const bestAdd = typeof (best as any)?.additions === "number" ? (best as any).additions : 0 + const bestDel = typeof (best as any)?.deletions === "number" ? (best as any).deletions : 0 + const bestScore = bestAdd + bestDel + + const add = typeof (item as any)?.additions === "number" ? (item as any).additions : 0 + const del = typeof (item as any)?.deletions === "number" ? (item as any).deletions : 0 + const score = add + del + + if (score > bestScore) return item + if (score < bestScore) return best + return String(item.file || "").localeCompare(String((best as any)?.file || "")) < 0 ? item : best + }, sorted[0]) + : null + + // Auto-select the most-changed file if none selected. + const currentSelected = props.selectedFile() + const selectedFileData = sorted.find((f) => f.file === currentSelected) || mostChanged + + const scopeKey = `${props.instanceId}:${hasSession ? sessionId : "no-session"}` + + const emptyViewerMessage = () => { + if (!hasSession) return props.t("instanceShell.sessionChanges.noSessionSelected") + if (diffs === undefined) return props.t("instanceShell.sessionChanges.loading") + if (!Array.isArray(diffs) || diffs.length === 0) return props.t("instanceShell.sessionChanges.empty") + return props.t("instanceShell.filesShell.viewerEmpty") + } + + const renderViewer = () => ( +
+
+ +
+
+ 0 ? selectedFileData : null} + fallback={ +
+ {emptyViewerMessage()} +
+ } + > + {(file) => ( + + )} +
+
+
+ ) + + const renderEmptyList = () => ( +
{emptyViewerMessage()}
+ ) + + const renderListPanel = () => ( + 0} fallback={renderEmptyList()}> + + {(item) => ( +
{ + props.onSelectFile(item.file, props.isPhoneLayout()) + }} + > +
+
+ {item.file} +
+
+ +{item.additions} + -{item.deletions} +
+
+
+ )} +
+
+ ) + + const renderListOverlay = () => ( + 0} fallback={renderEmptyList()}> + + {(item) => ( +
{ + props.onSelectFile(item.file, true) + }} + title={item.file} + > +
+
+ {item.file} +
+
+ +{item.additions} + -{item.deletions} +
+
+
+ )} +
+
+ ) + + const headerPath = () => (selectedFileData?.file ? selectedFileData.file : props.t("instanceShell.rightPanel.tabs.changes")) + + return ( + + + {headerPath()} + + +
+ + +{totals.additions} + + + -{totals.deletions} + +
+ + } + list={{ panel: renderListPanel, overlay: renderListOverlay }} + viewer={renderViewer()} + listOpen={props.listOpen()} + onToggleList={props.onToggleList} + splitWidth={props.splitWidth()} + onResizeMouseDown={props.onResizeMouseDown} + onResizeTouchStart={props.onResizeTouchStart} + isPhoneLayout={props.isPhoneLayout()} + overlayAriaLabel="Changes" + /> + ) + } + + return <>{renderContent()} +} + +export default ChangesTab diff --git a/packages/ui/src/components/instance/shell/right-panel/tabs/FilesTab.tsx b/packages/ui/src/components/instance/shell/right-panel/tabs/FilesTab.tsx new file mode 100644 index 00000000..dc462474 --- /dev/null +++ b/packages/ui/src/components/instance/shell/right-panel/tabs/FilesTab.tsx @@ -0,0 +1,191 @@ +import { For, Show, type Accessor, type Component, type JSX } from "solid-js" +import type { FileNode } from "@opencode-ai/sdk/v2/client" + +import { RefreshCw } from "lucide-solid" + +import { MonacoFileViewer } from "../../../../file-viewer/monaco-file-viewer" + +import SplitFilePanel from "../components/SplitFilePanel" + +interface FilesTabProps { + t: (key: string, vars?: Record) => string + + browserPath: Accessor + browserEntries: Accessor + browserLoading: Accessor + browserError: Accessor + + browserSelectedPath: Accessor + browserSelectedContent: Accessor + browserSelectedLoading: Accessor + browserSelectedError: Accessor + + parentPath: Accessor + scopeKey: Accessor + + onLoadEntries: (path: string) => void + onOpenFile: (path: string) => void + onRefresh: () => void + + listOpen: Accessor + onToggleList: () => void + splitWidth: Accessor + onResizeMouseDown: (event: MouseEvent) => void + onResizeTouchStart: (event: TouchEvent) => void + isPhoneLayout: Accessor +} + +const FilesTab: Component = (props) => { + const renderContent = (): JSX.Element => { + const entriesValue = props.browserEntries() + const entries = entriesValue || [] + const sorted = [...entries].sort((a, b) => { + const aDir = a.type === "directory" ? 0 : 1 + const bDir = b.type === "directory" ? 0 : 1 + if (aDir !== bDir) return aDir - bDir + return String(a.name || "").localeCompare(String(b.name || "")) + }) + + const parent = props.parentPath() + + const headerDisplayedPath = () => props.browserSelectedPath() || props.browserPath() + + const emptyViewerMessage = () => { + if (props.browserLoading() && entriesValue === null) return "Loading files..." + return "Select a file to preview" + } + + const renderViewer = () => ( +
+
+ + {emptyViewerMessage()} +
+ } + > + {(payload) => ( + + )} + + } + > + {(err) => ( +
+ {err()} +
+ )} + + } + > +
+ Loading… +
+ +
+
+ ) + + const renderList = () => ( + <> + + {(p) => ( +
props.onLoadEntries(p())}> +
+
+ .. +
+
+
+ )} +
+ + +
Loading files...
+
+ + + {(item) => ( +
{ + if (item.type === "directory") { + props.onLoadEntries(item.path) + return + } + props.onOpenFile(item.path) + }} + title={item.path} + > +
+
+ {item.name} +
+
+ {item.type} +
+
+
+ )} +
+ + ) + + return ( + +
+ + + {headerDisplayedPath()} + + + + Loading… + + {(err) => {err()}} +
+ + + + } + list={{ panel: renderList, overlay: renderList }} + viewer={renderViewer()} + listOpen={props.listOpen()} + onToggleList={props.onToggleList} + splitWidth={props.splitWidth()} + onResizeMouseDown={props.onResizeMouseDown} + onResizeTouchStart={props.onResizeTouchStart} + isPhoneLayout={props.isPhoneLayout()} + overlayAriaLabel="Files" + /> + ) + } + + return <>{renderContent()} +} + +export default FilesTab diff --git a/packages/ui/src/components/instance/shell/right-panel/tabs/GitChangesTab.tsx b/packages/ui/src/components/instance/shell/right-panel/tabs/GitChangesTab.tsx new file mode 100644 index 00000000..bd77d7e5 --- /dev/null +++ b/packages/ui/src/components/instance/shell/right-panel/tabs/GitChangesTab.tsx @@ -0,0 +1,258 @@ +import { For, Show, type Accessor, type Component, type JSX } from "solid-js" +import type { File as GitFileStatus } from "@opencode-ai/sdk/v2/client" + +import { RefreshCw } from "lucide-solid" + +import { MonacoDiffViewer } from "../../../../file-viewer/monaco-diff-viewer" + +import DiffToolbar from "../components/DiffToolbar" +import SplitFilePanel from "../components/SplitFilePanel" +import type { DiffContextMode, DiffViewMode } from "../types" + +interface GitChangesTabProps { + t: (key: string, vars?: Record) => string + + activeSessionId: Accessor + + entries: Accessor + statusLoading: Accessor + statusError: Accessor + + selectedPath: Accessor + selectedLoading: Accessor + selectedError: Accessor + selectedBefore: Accessor + selectedAfter: Accessor + mostChangedPath: Accessor + + scopeKey: Accessor + + diffViewMode: Accessor + diffContextMode: Accessor + onViewModeChange: (mode: DiffViewMode) => void + onContextModeChange: (mode: DiffContextMode) => void + + onOpenFile: (path: string) => void + onRefresh: () => void + + listOpen: Accessor + onToggleList: () => void + splitWidth: Accessor + onResizeMouseDown: (event: MouseEvent) => void + onResizeTouchStart: (event: TouchEvent) => void + isPhoneLayout: Accessor +} + +const GitChangesTab: Component = (props) => { + const renderContent = (): JSX.Element => { + const sessionId = props.activeSessionId() + + const hasSession = Boolean(sessionId && sessionId !== "info") + const entries = hasSession ? props.entries() : null + + const sorted = Array.isArray(entries) + ? [...entries].sort((a, b) => String(a.path || "").localeCompare(String(b.path || ""))) + : [] + + const totals = sorted.reduce( + (acc, item) => { + acc.additions += typeof item.added === "number" ? item.added : 0 + acc.deletions += typeof item.removed === "number" ? item.removed : 0 + return acc + }, + { additions: 0, deletions: 0 }, + ) + + const nonDeleted = sorted.filter((item) => item && item.status !== "deleted") + + const emptyViewerMessage = () => { + if (!hasSession) return "Select a session to view changes." + if (entries === null) return "Loading git changes…" + if (nonDeleted.length === 0) return "No git changes yet." + return "No file selected." + } + + const selectedPath = props.selectedPath() + const fallbackPath = props.mostChangedPath() + const selectedEntry = + sorted.find((item) => item.path === selectedPath) || + (fallbackPath ? sorted.find((item) => item.path === fallbackPath) : null) + + const renderViewer = () => ( +
+
+ +
+
+ + {emptyViewerMessage()} +
+ } + > + {(file) => ( + + )} + + } + > + {(err) => ( +
+ {err()} +
+ )} + + } + > +
+ Loading… +
+ +
+
+ ) + + const renderEmptyList = () =>
{emptyViewerMessage()}
+ + const renderListPanel = () => ( + 0} fallback={renderEmptyList()}> + + {(item) => ( +
{ + props.onOpenFile(item.path) + }} + > +
+
+ {item.path} +
+
+ + deleted + + + <> + +{item.added} + -{item.removed} + + +
+
+
+ )} +
+
+ ) + + const renderListOverlay = () => ( + 0} fallback={renderEmptyList()}> + + {(item) => ( +
props.onOpenFile(item.path)} + title={item.path} + > +
+
+ {item.path} +
+
+ + deleted + + + <> + +{item.added} + -{item.removed} + + +
+
+
+ )} +
+
+ ) + + return ( + + + {selectedEntry?.path || "Git Changes"} + + +
+ + +{totals.additions} + + + -{totals.deletions} + + {(err) => {err()}} +
+ + + + } + list={{ panel: renderListPanel, overlay: renderListOverlay }} + viewer={renderViewer()} + listOpen={props.listOpen()} + onToggleList={props.onToggleList} + splitWidth={props.splitWidth()} + onResizeMouseDown={props.onResizeMouseDown} + onResizeTouchStart={props.onResizeTouchStart} + isPhoneLayout={props.isPhoneLayout()} + overlayAriaLabel="Git Changes" + /> + ) + } + + return <>{renderContent()} +} + +export default GitChangesTab diff --git a/packages/ui/src/components/instance/shell/right-panel/tabs/StatusTab.tsx b/packages/ui/src/components/instance/shell/right-panel/tabs/StatusTab.tsx new file mode 100644 index 00000000..6786b455 --- /dev/null +++ b/packages/ui/src/components/instance/shell/right-panel/tabs/StatusTab.tsx @@ -0,0 +1,294 @@ +import { For, Show, type Accessor, type Component } from "solid-js" +import type { ToolState } from "@opencode-ai/sdk" +import { Accordion } from "@kobalte/core" + +import { ChevronDown, TerminalSquare, Trash2, XOctagon } from "lucide-solid" + +import type { Instance } from "../../../../../types/instance" +import type { BackgroundProcess } from "../../../../../../../server/src/api-types" +import type { Session } from "../../../../../types/session" + +import ContextUsagePanel from "../../../../session/context-usage-panel" +import { TodoListView } from "../../../../tool-call/renderers/todo" +import InstanceServiceStatus from "../../../../instance-service-status" + +interface StatusTabProps { + t: (key: string, vars?: Record) => string + + instanceId: string + instance: Instance + + activeSessionId: Accessor + activeSession: Accessor + activeSessionDiffs: Accessor + + latestTodoState: Accessor + + backgroundProcessList: Accessor + onOpenBackgroundOutput: (process: BackgroundProcess) => void + onStopBackgroundProcess: (processId: string) => Promise | void + onTerminateBackgroundProcess: (processId: string) => Promise | void + + expandedItems: Accessor + onExpandedItemsChange: (values: string[]) => void + + onOpenChangesTab: (file?: string) => void +} + +const StatusTab: Component = (props) => { + const isSectionExpanded = (id: string) => props.expandedItems().includes(id) + + const renderStatusSessionChanges = () => { + const sessionId = props.activeSessionId() + if (!sessionId || sessionId === "info") { + return ( +
+ {props.t("instanceShell.sessionChanges.noSessionSelected")} +
+ ) + } + + const diffs = props.activeSessionDiffs() + if (diffs === undefined) { + return ( +
+ {props.t("instanceShell.sessionChanges.loading")} +
+ ) + } + + if (!Array.isArray(diffs) || diffs.length === 0) { + return ( +
+ {props.t("instanceShell.sessionChanges.empty")} +
+ ) + } + + const sorted = [...diffs].sort((a, b) => String(a.file || "").localeCompare(String(b.file || ""))) + const totals = sorted.reduce( + (acc, item) => { + acc.additions += typeof item.additions === "number" ? item.additions : 0 + acc.deletions += typeof item.deletions === "number" ? item.deletions : 0 + return acc + }, + { additions: 0, deletions: 0 }, + ) + + return ( +
+
+ {props.t("instanceShell.sessionChanges.filesChanged", { count: sorted.length })} + + {`+${totals.additions}`} + {`-${totals.deletions}`} + +
+ +
+
+ + {(item) => ( + + )} + +
+
+
+ ) + } + + const renderPlanSectionContent = () => { + const sessionId = props.activeSessionId() + if (!sessionId || sessionId === "info") { + return ( +
+ {props.t("instanceShell.plan.noSessionSelected")} +
+ ) + } + const todoState = props.latestTodoState() + if (!todoState) { + return ( +
+ {props.t("instanceShell.plan.empty")} +
+ ) + } + return + } + + const renderBackgroundProcesses = () => { + const processes = props.backgroundProcessList() + if (processes.length === 0) { + return ( +
+ {props.t("instanceShell.backgroundProcesses.empty")} +
+ ) + } + + return ( +
+ + {(process) => ( +
+
+ {process.title} +
+ {props.t("instanceShell.backgroundProcesses.status", { status: process.status })} + + + {props.t("instanceShell.backgroundProcesses.output", { + sizeKb: Math.round((process.outputSizeBytes ?? 0) / 1024), + })} + + +
+
+
+ + + +
+
+ )} +
+
+ ) + } + + const statusSections = [ + { + id: "session-changes", + labelKey: "instanceShell.rightPanel.sections.sessionChanges", + render: renderStatusSessionChanges, + }, + { + id: "plan", + labelKey: "instanceShell.rightPanel.sections.plan", + render: renderPlanSectionContent, + }, + { + id: "background-processes", + labelKey: "instanceShell.rightPanel.sections.backgroundProcesses", + render: renderBackgroundProcesses, + }, + { + id: "mcp", + labelKey: "instanceShell.rightPanel.sections.mcp", + render: () => ( + + ), + }, + { + id: "lsp", + labelKey: "instanceShell.rightPanel.sections.lsp", + render: () => ( + + ), + }, + { + id: "plugins", + labelKey: "instanceShell.rightPanel.sections.plugins", + render: () => ( + + ), + }, + ] + + return ( +
+ + {(activeSession) => ( + + )} + + + + + {(section) => ( + + + + {props.t(section.labelKey)} + + + + {section.render()} + + )} + + +
+ ) +} + +export default StatusTab diff --git a/packages/ui/src/components/instance/shell/right-panel/types.ts b/packages/ui/src/components/instance/shell/right-panel/types.ts new file mode 100644 index 00000000..e651e528 --- /dev/null +++ b/packages/ui/src/components/instance/shell/right-panel/types.ts @@ -0,0 +1,5 @@ +export type RightPanelTab = "changes" | "git-changes" | "files" | "status" + +export type DiffViewMode = "split" | "unified" + +export type DiffContextMode = "expanded" | "collapsed" diff --git a/packages/ui/src/components/instance/shell/storage.ts b/packages/ui/src/components/instance/shell/storage.ts new file mode 100644 index 00000000..5f1d7421 --- /dev/null +++ b/packages/ui/src/components/instance/shell/storage.ts @@ -0,0 +1,92 @@ +export const DEFAULT_SESSION_SIDEBAR_WIDTH = 340 +export const MIN_SESSION_SIDEBAR_WIDTH = 220 +export const MAX_SESSION_SIDEBAR_WIDTH = 400 + +export const RIGHT_DRAWER_WIDTH = 260 +export const MIN_RIGHT_DRAWER_WIDTH = 200 +export const MAX_RIGHT_DRAWER_WIDTH = 1200 + +export const LEFT_DRAWER_STORAGE_KEY = "opencode-session-sidebar-width-v8" +export const RIGHT_DRAWER_STORAGE_KEY = "opencode-session-right-drawer-width-v1" +export const LEFT_PIN_STORAGE_KEY = "opencode-session-left-drawer-pinned-v1" +export const RIGHT_PIN_STORAGE_KEY = "opencode-session-right-drawer-pinned-v1" +export const RIGHT_PANEL_TAB_STORAGE_KEY = "opencode-session-right-panel-tab-v2" +export const LEGACY_RIGHT_PANEL_TAB_STORAGE_KEY = "opencode-session-right-panel-tab-v1" +export const RIGHT_PANEL_CHANGES_SPLIT_WIDTH_KEY = "opencode-session-right-panel-changes-split-width-v1" +export const RIGHT_PANEL_FILES_SPLIT_WIDTH_KEY = "opencode-session-right-panel-files-split-width-v1" +export const RIGHT_PANEL_GIT_CHANGES_SPLIT_WIDTH_KEY = "opencode-session-right-panel-git-changes-split-width-v1" +export const RIGHT_PANEL_CHANGES_LIST_OPEN_NONPHONE_KEY = "opencode-session-right-panel-changes-list-open-nonphone-v1" +export const RIGHT_PANEL_CHANGES_LIST_OPEN_PHONE_KEY = "opencode-session-right-panel-changes-list-open-phone-v1" +export const RIGHT_PANEL_FILES_LIST_OPEN_NONPHONE_KEY = "opencode-session-right-panel-files-list-open-nonphone-v1" +export const RIGHT_PANEL_FILES_LIST_OPEN_PHONE_KEY = "opencode-session-right-panel-files-list-open-phone-v1" +export const RIGHT_PANEL_GIT_CHANGES_LIST_OPEN_NONPHONE_KEY = "opencode-session-right-panel-git-changes-list-open-nonphone-v1" +export const RIGHT_PANEL_GIT_CHANGES_LIST_OPEN_PHONE_KEY = "opencode-session-right-panel-git-changes-list-open-phone-v1" +export const RIGHT_PANEL_CHANGES_DIFF_VIEW_MODE_KEY = "opencode-session-right-panel-changes-diff-view-mode-v1" +export const RIGHT_PANEL_CHANGES_DIFF_CONTEXT_MODE_KEY = "opencode-session-right-panel-changes-diff-context-mode-v1" + +export const clampWidth = (value: number) => + Math.min(MAX_SESSION_SIDEBAR_WIDTH, Math.max(MIN_SESSION_SIDEBAR_WIDTH, value)) + +export const clampRightWidth = (value: number) => { + const windowMax = typeof window !== "undefined" ? Math.floor(window.innerWidth * 0.7) : MAX_RIGHT_DRAWER_WIDTH + const max = Math.max(MIN_RIGHT_DRAWER_WIDTH, windowMax) + return Math.min(max, Math.max(MIN_RIGHT_DRAWER_WIDTH, value)) +} + +const getPinStorageKey = (side: "left" | "right") => (side === "left" ? LEFT_PIN_STORAGE_KEY : RIGHT_PIN_STORAGE_KEY) + +export function readStoredPinState(side: "left" | "right", defaultValue: boolean) { + if (typeof window === "undefined") return defaultValue + const stored = window.localStorage.getItem(getPinStorageKey(side)) + if (stored === "true") return true + if (stored === "false") return false + return defaultValue +} + +export function persistPinState(side: "left" | "right", value: boolean) { + if (typeof window === "undefined") return + window.localStorage.setItem(getPinStorageKey(side), value ? "true" : "false") +} + +export function readStoredRightPanelTab( + defaultValue: "changes" | "git-changes" | "files" | "status", +): "changes" | "git-changes" | "files" | "status" { + if (typeof window === "undefined") return defaultValue + + const stored = window.localStorage.getItem(RIGHT_PANEL_TAB_STORAGE_KEY) + if (stored === "status") return "status" + if (stored === "changes") return "changes" + if (stored === "git-changes") return "git-changes" + if (stored === "files") return "files" + + // Migrate from v1 (where the stored values were the internal tab ids). + const legacy = window.localStorage.getItem(LEGACY_RIGHT_PANEL_TAB_STORAGE_KEY) + if (legacy === "status") return "status" + if (legacy === "browser") return "files" + if (legacy === "files") return "changes" + + return defaultValue +} + +export function readStoredPanelWidth(key: string, fallback: number) { + if (typeof window === "undefined") return fallback + const stored = window.localStorage.getItem(key) + if (!stored) return fallback + const parsed = Number.parseInt(stored, 10) + return Number.isFinite(parsed) ? parsed : fallback +} + +export function readStoredBool(key: string): boolean | null { + if (typeof window === "undefined") return null + const stored = window.localStorage.getItem(key) + if (stored === "true") return true + if (stored === "false") return false + return null +} + +export function readStoredEnum(key: string, allowed: readonly T[]): T | null { + if (typeof window === "undefined") return null + const stored = window.localStorage.getItem(key) + if (!stored) return null + return (allowed as readonly string[]).includes(stored) ? (stored as T) : null +} diff --git a/packages/ui/src/components/instance/shell/types.ts b/packages/ui/src/components/instance/shell/types.ts new file mode 100644 index 00000000..9ca38695 --- /dev/null +++ b/packages/ui/src/components/instance/shell/types.ts @@ -0,0 +1,3 @@ +export type LayoutMode = "desktop" | "tablet" | "phone" + +export type DrawerViewState = "pinned" | "floating-open" | "floating-closed" diff --git a/packages/ui/src/components/instance/shell/useDrawerChrome.ts b/packages/ui/src/components/instance/shell/useDrawerChrome.ts new file mode 100644 index 00000000..bccc8444 --- /dev/null +++ b/packages/ui/src/components/instance/shell/useDrawerChrome.ts @@ -0,0 +1,260 @@ +import { + batch, + createComponent, + createEffect, + createMemo, + createSignal, + onCleanup, + onMount, + type Accessor, + type JSX, + type Setter, +} from "solid-js" +import MenuIcon from "@suid/icons-material/Menu" + +import type { TranslateParams } from "../../../lib/i18n" + +import type { DrawerViewState, LayoutMode } from "./types" +import { persistPinState, readStoredPinState } from "./storage" + +export interface UseDrawerChromeOptions { + t: (key: string, params?: TranslateParams) => string + layoutMode: Accessor + leftPinningSupported: Accessor + rightPinningSupported: Accessor + leftDrawerContentEl: Accessor + rightDrawerContentEl: Accessor + leftToggleButtonEl: Accessor + rightToggleButtonEl: Accessor + measureDrawerHost?: () => void +} + +export interface DrawerChromeApi { + leftPinned: Accessor + leftOpen: Accessor + rightPinned: Accessor + rightOpen: Accessor + setLeftOpen: Setter + setRightOpen: Setter + leftDrawerState: Accessor + rightDrawerState: Accessor + pinLeft: () => void + unpinLeft: () => void + pinRight: () => void + unpinRight: () => void + closeLeft: () => void + closeRight: () => void + leftAppBarButtonLabel: Accessor + rightAppBarButtonLabel: Accessor + leftAppBarButtonIcon: Accessor + rightAppBarButtonIcon: Accessor + handleLeftAppBarButtonClick: () => void + handleRightAppBarButtonClick: () => void +} + +export function useDrawerChrome(options: UseDrawerChromeOptions): DrawerChromeApi { + const [leftPinned, setLeftPinned] = createSignal(true) + const [leftOpen, setLeftOpen] = createSignal(true) + const [rightPinned, setRightPinned] = createSignal(true) + const [rightOpen, setRightOpen] = createSignal(true) + + const measureDrawerHost = () => options.measureDrawerHost?.() + + const focusTarget = (element: HTMLElement | null) => { + if (!element) return + requestAnimationFrame(() => { + element.focus() + }) + } + + const blurIfInside = (element: HTMLElement | null) => { + if (typeof document === "undefined" || !element) return + const active = document.activeElement as HTMLElement | null + if (active && element.contains(active)) { + active.blur() + } + } + + const persistPinIfSupported = (side: "left" | "right", value: boolean) => { + if (side === "left" && !options.leftPinningSupported()) return + if (side === "right" && !options.rightPinningSupported()) return + persistPinState(side, value) + } + + createEffect(() => { + switch (options.layoutMode()) { + case "desktop": { + const leftSaved = readStoredPinState("left", true) + const rightSaved = readStoredPinState("right", true) + setLeftPinned(leftSaved) + setLeftOpen(leftSaved) + setRightPinned(rightSaved) + setRightOpen(rightSaved) + break + } + case "tablet": { + setLeftPinned(true) + setLeftOpen(true) + setRightPinned(false) + setRightOpen(false) + break + } + default: + setLeftPinned(false) + setLeftOpen(false) + setRightPinned(false) + setRightOpen(false) + break + } + }) + + const leftDrawerState = createMemo(() => { + if (leftPinned()) return "pinned" + return leftOpen() ? "floating-open" : "floating-closed" + }) + + const rightDrawerState = createMemo(() => { + if (rightPinned()) return "pinned" + return rightOpen() ? "floating-open" : "floating-closed" + }) + + const leftAppBarButtonLabel = () => { + const state = leftDrawerState() + if (state === "pinned") return options.t("instanceShell.leftDrawer.toggle.pinned") + return options.t("instanceShell.leftDrawer.toggle.open") + } + + const rightAppBarButtonLabel = () => { + const state = rightDrawerState() + if (state === "pinned") return options.t("instanceShell.rightDrawer.toggle.pinned") + return options.t("instanceShell.rightDrawer.toggle.open") + } + + const leftAppBarButtonIcon = () => { + return createComponent(MenuIcon, { fontSize: "small" }) + } + + const rightAppBarButtonIcon = () => { + return createComponent(MenuIcon, { fontSize: "small", sx: { transform: "scaleX(-1)" } }) + } + + const pinLeft = () => { + blurIfInside(options.leftDrawerContentEl()) + batch(() => { + setLeftPinned(true) + setLeftOpen(true) + }) + persistPinIfSupported("left", true) + measureDrawerHost() + } + + const unpinLeft = () => { + blurIfInside(options.leftDrawerContentEl()) + batch(() => { + setLeftPinned(false) + setLeftOpen(true) + }) + persistPinIfSupported("left", false) + measureDrawerHost() + } + + const pinRight = () => { + blurIfInside(options.rightDrawerContentEl()) + batch(() => { + setRightPinned(true) + setRightOpen(true) + }) + persistPinIfSupported("right", true) + measureDrawerHost() + } + + const unpinRight = () => { + blurIfInside(options.rightDrawerContentEl()) + batch(() => { + setRightPinned(false) + setRightOpen(true) + }) + persistPinIfSupported("right", false) + measureDrawerHost() + } + + const handleLeftAppBarButtonClick = () => { + const state = leftDrawerState() + if (state !== "floating-closed") return + setLeftOpen(true) + measureDrawerHost() + } + + const handleRightAppBarButtonClick = () => { + const state = rightDrawerState() + if (state !== "floating-closed") return + setRightOpen(true) + measureDrawerHost() + } + + const closeLeft = () => { + if (leftDrawerState() === "pinned") return + blurIfInside(options.leftDrawerContentEl()) + setLeftOpen(false) + focusTarget(options.leftToggleButtonEl()) + } + + const closeRight = () => { + if (rightDrawerState() === "pinned") return + blurIfInside(options.rightDrawerContentEl()) + setRightOpen(false) + focusTarget(options.rightToggleButtonEl()) + } + + const closeFloatingDrawersIfAny = () => { + let handled = false + if (!leftPinned() && leftOpen()) { + setLeftOpen(false) + blurIfInside(options.leftDrawerContentEl()) + focusTarget(options.leftToggleButtonEl()) + handled = true + } + if (!rightPinned() && rightOpen()) { + setRightOpen(false) + blurIfInside(options.rightDrawerContentEl()) + focusTarget(options.rightToggleButtonEl()) + handled = true + } + return handled + } + + onMount(() => { + if (typeof window === "undefined") return + const handleEscape = (event: KeyboardEvent) => { + if (event.key !== "Escape") return + if (!closeFloatingDrawersIfAny()) return + event.preventDefault() + event.stopPropagation() + } + window.addEventListener("keydown", handleEscape, true) + onCleanup(() => window.removeEventListener("keydown", handleEscape, true)) + }) + + return { + leftPinned, + leftOpen, + rightPinned, + rightOpen, + setLeftOpen, + setRightOpen, + leftDrawerState, + rightDrawerState, + pinLeft, + unpinLeft, + pinRight, + unpinRight, + closeLeft, + closeRight, + leftAppBarButtonLabel, + rightAppBarButtonLabel, + leftAppBarButtonIcon, + rightAppBarButtonIcon, + handleLeftAppBarButtonClick, + handleRightAppBarButtonClick, + } +} diff --git a/packages/ui/src/components/instance/shell/useDrawerHostMeasure.ts b/packages/ui/src/components/instance/shell/useDrawerHostMeasure.ts new file mode 100644 index 00000000..5675424e --- /dev/null +++ b/packages/ui/src/components/instance/shell/useDrawerHostMeasure.ts @@ -0,0 +1,65 @@ +import { createEffect, createSignal, type Accessor } from "solid-js" + +type DrawerHostMeasure = { + setDrawerHost: (element: HTMLElement) => void + drawerContainer: () => HTMLElement | undefined + measureDrawerHost: () => void + floatingTopPx: () => string + floatingHeight: () => string +} + +export function useDrawerHostMeasure(tabBarOffset: Accessor): DrawerHostMeasure { + const [drawerHost, setDrawerHost] = createSignal(null) + const [floatingDrawerTop, setFloatingDrawerTop] = createSignal(0) + const [floatingDrawerHeight, setFloatingDrawerHeight] = createSignal(0) + + const storeDrawerHost = (element: HTMLElement) => { + setDrawerHost(element) + } + + const measureDrawerHost = () => { + if (typeof window === "undefined") return + const host = drawerHost() + if (!host) return + const rect = host.getBoundingClientRect() + setFloatingDrawerTop(rect.top) + setFloatingDrawerHeight(Math.max(0, rect.height)) + } + + createEffect(() => { + tabBarOffset() + if (typeof window === "undefined") return + requestAnimationFrame(() => measureDrawerHost()) + }) + + const drawerContainer = () => { + const host = drawerHost() + if (host) return host + if (typeof document !== "undefined") { + return document.body + } + return undefined + } + + const fallbackDrawerTop = () => tabBarOffset() + const floatingTop = () => { + const measured = floatingDrawerTop() + if (measured > 0) return measured + return fallbackDrawerTop() + } + + const floatingTopPx = () => `${floatingTop()}px` + const floatingHeight = () => { + const measured = floatingDrawerHeight() + if (measured > 0) return `${measured}px` + return `calc(100% - ${floatingTop()}px)` + } + + return { + setDrawerHost: storeDrawerHost, + drawerContainer, + measureDrawerHost, + floatingTopPx, + floatingHeight, + } +} diff --git a/packages/ui/src/components/instance/shell/useDrawerResize.ts b/packages/ui/src/components/instance/shell/useDrawerResize.ts new file mode 100644 index 00000000..d3a4f982 --- /dev/null +++ b/packages/ui/src/components/instance/shell/useDrawerResize.ts @@ -0,0 +1,113 @@ +import { createSignal, onCleanup, type Accessor, type Setter } from "solid-js" + +import { useGlobalPointerDrag } from "./useGlobalPointerDrag" + +type DrawerResizeSide = "left" | "right" + +type DrawerResizeOptions = { + sessionSidebarWidth: Accessor + rightDrawerWidth: Accessor + setSessionSidebarWidth: Setter + setRightDrawerWidth: Setter + clampLeft: (width: number) => number + clampRight: (width: number) => number + measureDrawerHost: () => void +} + +type DrawerResizeApi = { + handleDrawerResizeMouseDown: (side: DrawerResizeSide) => (event: MouseEvent) => void + handleDrawerResizeTouchStart: (side: DrawerResizeSide) => (event: TouchEvent) => void +} + +export function useDrawerResize(options: DrawerResizeOptions): DrawerResizeApi { + const [activeResizeSide, setActiveResizeSide] = createSignal(null) + const [resizeStartX, setResizeStartX] = createSignal(0) + const [resizeStartWidth, setResizeStartWidth] = createSignal(0) + + const scheduleDrawerMeasure = () => { + if (typeof window === "undefined") { + options.measureDrawerHost() + return + } + requestAnimationFrame(() => options.measureDrawerHost()) + } + + const applyDrawerWidth = (side: DrawerResizeSide, width: number) => { + if (side === "left") { + options.setSessionSidebarWidth(width) + } else { + options.setRightDrawerWidth(width) + } + scheduleDrawerMeasure() + } + + const handleDrawerPointerMove = (clientX: number) => { + const side = activeResizeSide() + if (!side) return + const startWidth = resizeStartWidth() + const clamp = side === "left" ? options.clampLeft : options.clampRight + const delta = side === "left" ? clientX - resizeStartX() : resizeStartX() - clientX + const nextWidth = clamp(startWidth + delta) + applyDrawerWidth(side, nextWidth) + } + + function drawerMouseMove(event: MouseEvent) { + event.preventDefault() + handleDrawerPointerMove(event.clientX) + } + + function drawerMouseUp() { + stopDrawerResize() + } + + function drawerTouchMove(event: TouchEvent) { + const touch = event.touches[0] + if (!touch) return + event.preventDefault() + handleDrawerPointerMove(touch.clientX) + } + + function drawerTouchEnd() { + stopDrawerResize() + } + + const drawerPointerDrag = useGlobalPointerDrag({ + onMouseMove: drawerMouseMove, + onMouseUp: drawerMouseUp, + onTouchMove: drawerTouchMove, + onTouchEnd: drawerTouchEnd, + }) + + function stopDrawerResize() { + setActiveResizeSide(null) + drawerPointerDrag.stop() + } + + const startDrawerResize = (side: DrawerResizeSide, clientX: number) => { + setActiveResizeSide(side) + setResizeStartX(clientX) + setResizeStartWidth(side === "left" ? options.sessionSidebarWidth() : options.rightDrawerWidth()) + drawerPointerDrag.start() + } + + const handleDrawerResizeMouseDown = (side: DrawerResizeSide) => (event: MouseEvent) => { + event.preventDefault() + startDrawerResize(side, event.clientX) + } + + const handleDrawerResizeTouchStart = (side: DrawerResizeSide) => (event: TouchEvent) => { + const touch = event.touches[0] + if (!touch) return + event.preventDefault() + startDrawerResize(side, touch.clientX) + } + + onCleanup(() => { + stopDrawerResize() + }) + + return { + handleDrawerResizeMouseDown, + handleDrawerResizeTouchStart, + } +} diff --git a/packages/ui/src/components/instance/shell/useGlobalPointerDrag.ts b/packages/ui/src/components/instance/shell/useGlobalPointerDrag.ts new file mode 100644 index 00000000..380d4133 --- /dev/null +++ b/packages/ui/src/components/instance/shell/useGlobalPointerDrag.ts @@ -0,0 +1,29 @@ +type GlobalPointerDragHandlers = { + onMouseMove: (event: MouseEvent) => void + onMouseUp: (event: MouseEvent) => void + onTouchMove: (event: TouchEvent) => void + onTouchEnd: (event: TouchEvent) => void +} + +type GlobalPointerDrag = { + start: () => void + stop: () => void +} + +export function useGlobalPointerDrag(handlers: GlobalPointerDragHandlers): GlobalPointerDrag { + const start = () => { + document.addEventListener("mousemove", handlers.onMouseMove) + document.addEventListener("mouseup", handlers.onMouseUp) + document.addEventListener("touchmove", handlers.onTouchMove, { passive: false }) + document.addEventListener("touchend", handlers.onTouchEnd) + } + + const stop = () => { + document.removeEventListener("mousemove", handlers.onMouseMove) + document.removeEventListener("mouseup", handlers.onMouseUp) + document.removeEventListener("touchmove", handlers.onTouchMove) + document.removeEventListener("touchend", handlers.onTouchEnd) + } + + return { start, stop } +} diff --git a/packages/ui/src/components/instance/shell/useInstanceSessionContext.ts b/packages/ui/src/components/instance/shell/useInstanceSessionContext.ts new file mode 100644 index 00000000..faee193a --- /dev/null +++ b/packages/ui/src/components/instance/shell/useInstanceSessionContext.ts @@ -0,0 +1,173 @@ +import { batch, createMemo, type Accessor } from "solid-js" +import type { ToolState } from "@opencode-ai/sdk" +import type { Session } from "../../../types/session" +import { + activeParentSessionId, + activeSessionId as activeSessionMap, + getSessionFamily, + getSessionInfo, + getSessionThreads, + sessions, + setActiveParentSession, + setActiveSession, +} from "../../../stores/sessions" +import { messageStoreBus } from "../../../stores/message-v2/bus" +import { getBackgroundProcesses } from "../../../stores/background-processes" +import type { LatestTodoSnapshot, SessionUsageState } from "../../../stores/message-v2/types" + +type InstanceSessionContextOptions = { + instanceId: Accessor +} + +type InstanceSessionContextState = { + // Session collections and selections + allInstanceSessions: Accessor> + sessionThreads: Accessor> + activeSessions: Accessor> + activeSessionIdForInstance: Accessor + parentSessionIdForInstance: Accessor + activeSessionForInstance: Accessor + activeSessionDiffs: Accessor + + // Usage / info summaries + activeSessionUsage: Accessor + activeSessionInfoDetails: Accessor | null> + tokenStats: Accessor<{ used: number; avail: number | null }> + + // Todo state + latestTodoSnapshot: Accessor + latestTodoState: Accessor + + // Background processes + backgroundProcessList: Accessor> + + // Controller + handleSessionSelect: (sessionId: string) => void +} + +type SessionFamilyMember = ReturnType[number] + +export function useInstanceSessionContext(options: InstanceSessionContextOptions): InstanceSessionContextState { + const messageStore = createMemo(() => messageStoreBus.getOrCreate(options.instanceId())) + + const allInstanceSessions = createMemo>(() => { + return sessions().get(options.instanceId()) ?? new Map() + }) + + const sessionThreads = createMemo(() => getSessionThreads(options.instanceId())) + + const activeSessions = createMemo(() => { + const parentId = activeParentSessionId().get(options.instanceId()) + if (!parentId) return new Map[number]>() + const sessionFamily = getSessionFamily(options.instanceId(), parentId) + return new Map(sessionFamily.map((s) => [s.id, s])) + }) + + const activeSessionIdForInstance = createMemo(() => { + return activeSessionMap().get(options.instanceId()) || null + }) + + const parentSessionIdForInstance = createMemo(() => { + return activeParentSessionId().get(options.instanceId()) || null + }) + + const activeSessionForInstance = createMemo(() => { + const sessionId = activeSessionIdForInstance() + if (!sessionId || sessionId === "info") return null + return activeSessions().get(sessionId) ?? null + }) + + const activeSessionDiffs = createMemo(() => { + const session = activeSessionForInstance() + return session?.diff + }) + + const activeSessionUsage = createMemo(() => { + const sessionId = activeSessionIdForInstance() + if (!sessionId) return null + const store = messageStore() + return store?.getSessionUsage(sessionId) ?? null + }) + + const activeSessionInfoDetails = createMemo(() => { + const sessionId = activeSessionIdForInstance() + if (!sessionId) return null + return getSessionInfo(options.instanceId(), sessionId) ?? null + }) + + const tokenStats = createMemo(() => { + const usage = activeSessionUsage() + const info = activeSessionInfoDetails() + return { + used: usage?.actualUsageTokens ?? info?.actualUsageTokens ?? 0, + avail: info?.contextAvailableTokens ?? null, + } + }) + + const latestTodoSnapshot = createMemo(() => { + const sessionId = activeSessionIdForInstance() + if (!sessionId || sessionId === "info") return null + const store = messageStore() + if (!store) return null + const snapshot = store.state.latestTodos[sessionId] + return snapshot ?? null + }) + + const latestTodoState = createMemo(() => { + const snapshot = latestTodoSnapshot() + if (!snapshot) return null + const store = messageStore() + if (!store) return null + const message = store.getMessage(snapshot.messageId) + if (!message) return null + const partRecord = message.parts?.[snapshot.partId] + const part = partRecord?.data as { type?: string; tool?: string; state?: ToolState } + if (!part || part.type !== "tool" || part.tool !== "todowrite") return null + const state = part.state + if (!state || state.status !== "completed") return null + return state + }) + + const backgroundProcessList = createMemo(() => getBackgroundProcesses(options.instanceId())) + + const handleSessionSelect = (sessionId: string) => { + const instanceId = options.instanceId() + if (sessionId === "info") { + setActiveSession(instanceId, sessionId) + return + } + + const session = allInstanceSessions().get(sessionId) + if (!session) return + + if (session.parentId === null) { + setActiveParentSession(instanceId, sessionId) + return + } + + const parentId = session.parentId + if (!parentId) return + + batch(() => { + setActiveParentSession(instanceId, parentId) + setActiveSession(instanceId, sessionId) + }) + } + + return { + allInstanceSessions, + sessionThreads, + activeSessions, + activeSessionIdForInstance, + parentSessionIdForInstance, + activeSessionForInstance, + activeSessionDiffs, + activeSessionUsage, + activeSessionInfoDetails, + tokenStats, + latestTodoSnapshot, + latestTodoState, + backgroundProcessList, + handleSessionSelect, + } +} diff --git a/packages/ui/src/components/instance/shell/useSessionCache.ts b/packages/ui/src/components/instance/shell/useSessionCache.ts new file mode 100644 index 00000000..0e3a3476 --- /dev/null +++ b/packages/ui/src/components/instance/shell/useSessionCache.ts @@ -0,0 +1,99 @@ +import { createEffect, createSignal, type Accessor } from "solid-js" +import { messageStoreBus } from "../../../stores/message-v2/bus" +import { clearSessionRenderCache } from "../../message-block" +import { getLogger } from "../../../lib/logger" + +const log = getLogger("session") + +const SESSION_CACHE_LIMIT = 5 + +type SessionCacheOptions = { + instanceId: Accessor + instanceSessions: Accessor> + activeSessionId: Accessor +} + +type SessionCacheState = { + cachedSessionIds: Accessor +} + +export function useSessionCache(options: SessionCacheOptions): SessionCacheState { + const [cachedSessionIds, setCachedSessionIds] = createSignal([]) + const [pendingEvictions, setPendingEvictions] = createSignal([]) + + const evictSession = (sessionId: string) => { + if (!sessionId) return + const instanceId = options.instanceId() + log.info("Evicting cached session", { instanceId, sessionId }) + const store = messageStoreBus.getInstance(instanceId) + store?.clearSession(sessionId) + clearSessionRenderCache(instanceId, sessionId) + } + + const scheduleEvictions = (ids: string[]) => { + if (!ids.length) return + setPendingEvictions((current) => { + const existing = new Set(current) + const next = [...current] + ids.forEach((id) => { + if (!existing.has(id)) { + next.push(id) + existing.add(id) + } + }) + return next + }) + } + + createEffect(() => { + const pending = pendingEvictions() + if (!pending.length) return + const cached = new Set(cachedSessionIds()) + const remaining: string[] = [] + pending.forEach((id) => { + if (cached.has(id)) { + remaining.push(id) + } else { + evictSession(id) + } + }) + if (remaining.length !== pending.length) { + setPendingEvictions(remaining) + } + }) + + createEffect(() => { + const instanceSessions = options.instanceSessions() + const activeId = options.activeSessionId() + + setCachedSessionIds((current) => { + const next = current.filter((id) => id !== "info" && instanceSessions.has(id)) + + const touch = (id: string | null) => { + if (!id || id === "info") return + if (!instanceSessions.has(id)) return + + const index = next.indexOf(id) + if (index !== -1) { + next.splice(index, 1) + } + next.unshift(id) + } + + touch(activeId) + + const trimmed = next.length > SESSION_CACHE_LIMIT ? next.slice(0, SESSION_CACHE_LIMIT) : next + + const trimmedSet = new Set(trimmed) + const removed = current.filter((id) => !trimmedSet.has(id)) + if (removed.length) { + scheduleEvictions(removed) + } + return trimmed + }) + }) + + return { + cachedSessionIds, + } +} diff --git a/packages/ui/src/components/instance/shell/useSessionSidebarRequests.ts b/packages/ui/src/components/instance/shell/useSessionSidebarRequests.ts new file mode 100644 index 00000000..3e0a5953 --- /dev/null +++ b/packages/ui/src/components/instance/shell/useSessionSidebarRequests.ts @@ -0,0 +1,109 @@ +import { createEffect, createSignal, onCleanup, onMount, type Accessor } from "solid-js" +import { + SESSION_SIDEBAR_EVENT, + type SessionSidebarRequestAction, + type SessionSidebarRequestDetail, +} from "../../../lib/session-sidebar-events" + +interface PendingSidebarAction { + action: SessionSidebarRequestAction + id: number +} + +interface UseSessionSidebarRequestsOptions { + instanceId: Accessor + sidebarContentEl: Accessor + leftPinned: Accessor + leftOpen: Accessor + setLeftOpen: (next: boolean) => void + measureDrawerHost: () => void +} + +export function useSessionSidebarRequests(options: UseSessionSidebarRequestsOptions) { + let sidebarActionId = 0 + const [pendingSidebarAction, setPendingSidebarAction] = createSignal(null) + + const triggerKeyboardEvent = (target: HTMLElement, options: { key: string; code: string; keyCode: number }) => { + target.dispatchEvent( + new KeyboardEvent("keydown", { + key: options.key, + code: options.code, + keyCode: options.keyCode, + which: options.keyCode, + bubbles: true, + cancelable: true, + }), + ) + } + + const focusAgentSelectorControl = () => { + const agentTrigger = options.sidebarContentEl()?.querySelector("[data-agent-selector]") as HTMLElement | null + if (!agentTrigger) return false + agentTrigger.focus() + setTimeout(() => triggerKeyboardEvent(agentTrigger, { key: "Enter", code: "Enter", keyCode: 13 }), 10) + return true + } + + const focusModelSelectorControl = () => { + const input = options.sidebarContentEl()?.querySelector("[data-model-selector]") + if (!input) return false + input.focus() + setTimeout(() => triggerKeyboardEvent(input, { key: "ArrowDown", code: "ArrowDown", keyCode: 40 }), 10) + return true + } + + const focusVariantSelectorControl = () => { + const input = options.sidebarContentEl()?.querySelector("[data-thinking-selector]") + if (!input) return false + input.focus() + setTimeout(() => triggerKeyboardEvent(input, { key: "ArrowDown", code: "ArrowDown", keyCode: 40 }), 10) + return true + } + + createEffect(() => { + const pending = pendingSidebarAction() + if (!pending) return + const action = pending.action + const contentReady = Boolean(options.sidebarContentEl()) + if (!contentReady) { + return + } + if (action === "show-session-list") { + setPendingSidebarAction(null) + return + } + const handled = + action === "focus-agent-selector" + ? focusAgentSelectorControl() + : action === "focus-model-selector" + ? focusModelSelectorControl() + : focusVariantSelectorControl() + if (handled) { + setPendingSidebarAction(null) + } + }) + + const handleSidebarRequest = (action: SessionSidebarRequestAction) => { + setPendingSidebarAction({ action, id: sidebarActionId++ }) + if (!options.leftPinned() && !options.leftOpen()) { + options.setLeftOpen(true) + options.measureDrawerHost() + } + } + + onMount(() => { + if (typeof window === "undefined") return + const handler = (event: Event) => { + const detail = (event as CustomEvent).detail + if (!detail || detail.instanceId !== options.instanceId()) return + handleSidebarRequest(detail.action) + } + window.addEventListener(SESSION_SIDEBAR_EVENT, handler) + onCleanup(() => window.removeEventListener(SESSION_SIDEBAR_EVENT, handler)) + }) + + return { + handleSidebarRequest, + pendingSidebarAction, + } +} diff --git a/packages/ui/src/components/kbd.tsx b/packages/ui/src/components/kbd.tsx index d5b9c977..b9869111 100644 --- a/packages/ui/src/components/kbd.tsx +++ b/packages/ui/src/components/kbd.tsx @@ -1,4 +1,5 @@ import { Component, JSX, For } from "solid-js" +import useMediaQuery from "@suid/material/useMediaQuery" import { isMac } from "../lib/keyboard-utils" interface KbdProps { @@ -27,6 +28,9 @@ const SPECIAL_KEY_LABELS: Record = { } const Kbd: Component = (props) => { + const desktopQuery = useMediaQuery("(min-width: 1280px)") + if (!desktopQuery()) return null + const parts = () => { if (props.children) return [{ text: props.children, isModifier: false }] if (!props.shortcut) return [] diff --git a/packages/ui/src/components/keyboard-hint.tsx b/packages/ui/src/components/keyboard-hint.tsx index f68e6de4..1176550f 100644 --- a/packages/ui/src/components/keyboard-hint.tsx +++ b/packages/ui/src/components/keyboard-hint.tsx @@ -1,14 +1,20 @@ import { Component, For } from "solid-js" -import { formatShortcut, isMac } from "../lib/keyboard-utils" +import useMediaQuery from "@suid/material/useMediaQuery" import type { KeyboardShortcut } from "../lib/keyboard-registry" import Kbd from "./kbd" import HintRow from "./hint-row" const KeyboardHint: Component<{ shortcuts: KeyboardShortcut[] - separator?: string + separator?: string | null showDescription?: boolean + class?: string + ariaHidden?: boolean }> = (props) => { + // Centralize layout gating here so call sites don't need to. + // We only show keyboard hint UI on desktop layouts. + const desktopQuery = useMediaQuery("(min-width: 1280px)") + function buildShortcutString(shortcut: KeyboardShortcut): string { const parts: string[] = [] @@ -26,12 +32,14 @@ const KeyboardHint: Component<{ return parts.join("+") } + if (!desktopQuery()) return null + return ( - + {(shortcut, i) => ( <> - {i() > 0 && {props.separator || "•"}} + {i() > 0 && props.separator !== null && {props.separator ?? "•"}} {props.showDescription !== false && {shortcut.description}} diff --git a/packages/ui/src/components/markdown-preview-icon.tsx b/packages/ui/src/components/markdown-preview-icon.tsx new file mode 100644 index 00000000..d51e2977 --- /dev/null +++ b/packages/ui/src/components/markdown-preview-icon.tsx @@ -0,0 +1,68 @@ +import { Component } from "solid-js" +import { BookOpen } from "lucide-solid" + +/** + * Small book icon button displayed on message blocks with markdown files + * Triggers preview modal when clicked + */ + +interface MarkdownPreviewIconProps { + // Path to the markdown file + filePath: string + + // Callback when icon is clicked to open preview + onOpenPreview: (filePath: string) => void + + // Optional CSS class for positioning/styling + className?: string + + // Tooltip text (defaults to "Preview {filename}") + tooltip?: string + + // Icon size in pixels (default: 18) + size?: number +} + +/** + * MarkdownPreviewIcon Component + * + * Renders a small book icon button that opens markdown file preview. + * Shows filename on hover via tooltip. + * + * @example + * openModal(path)} + * /> + */ +const MarkdownPreviewIcon: Component = (props) => { + const iconSize = () => props.size ?? 18 + const tooltipText = () => { + if (props.tooltip) return props.tooltip + const filename = props.filePath.split("/").pop() || props.filePath + return `Preview ${filename}` + } + + const handleClick = (e: MouseEvent) => { + e.stopPropagation() // Prevent message selection + props.onOpenPreview(props.filePath) + } + + return ( + + ) +} + +export default MarkdownPreviewIcon diff --git a/packages/ui/src/components/markdown-preview-modal.tsx b/packages/ui/src/components/markdown-preview-modal.tsx new file mode 100644 index 00000000..c262f20b --- /dev/null +++ b/packages/ui/src/components/markdown-preview-modal.tsx @@ -0,0 +1,162 @@ +import { Component, Show } from "solid-js" +import { Dialog } from "@kobalte/core/dialog" +import { X } from "lucide-solid" +import { Markdown } from "./markdown" + +/** + * Modal dialog that displays markdown file preview with GitHub-style rendering + */ + +interface MarkdownPreviewModalProps { + // Whether modal is open/visible + isOpen: boolean + + // Path to markdown file being previewed + filePath: string + + // Markdown content (pre-fetched or null if loading) + content?: string | null + + // True if content is being fetched + isLoading?: boolean + + // Error message if fetch failed + error?: string | null + + // Callback when modal closes (ESC, X button, click outside) + onClose: () => void + + // Whether to use dark theme (optional, auto-detects if not provided) + isDarkMode?: boolean +} + +/** + * MarkdownPreviewModal Component + * + * Displays markdown file preview in a modal dialog. + * Supports: + * - Loading state with spinner + * - Error state with friendly message + * - GitHub markdown styling with syntax highlighting + * - Dark/light theme support + * - Keyboard accessible (ESC to close) + * + * @example + * setModalOpen(false)} + * /> + */ +const MarkdownPreviewModal: Component = (props) => { + const getFilename = () => { + return props.filePath.split("/").pop() || props.filePath + } + + const isDark = () => { + if (props.isDarkMode !== undefined) return props.isDarkMode + if (typeof window !== "undefined") { + return window.matchMedia("(prefers-color-scheme: dark)").matches + } + return false + } + + return ( + !open && props.onClose()}> + + {/* Dark overlay */} + + + {/* Modal container */} +
+ + {/* Header */} +
+
+ + {getFilename()} + +

{props.filePath}

+
+ + +
+ + {/* Content area */} +
+ {/* Loading state */} + +
+
+

Loading preview...

+
+ + + {/* Error state */} + +
+
+
+

Could not load file

+

{props.error}

+

+ The file {props.filePath} could not be read from the workspace. +

+
+
+
+ + {/* Success state - markdown content */} + +
+ +
+
+ + {/* Empty state (no error, no loading, no content) */} + +
+

No content to display

+
+
+
+ + {/* Footer */} + + +
+ +
+ ) +} + +export default MarkdownPreviewModal diff --git a/packages/ui/src/components/markdown.tsx b/packages/ui/src/components/markdown.tsx index 39638e1b..50a65ff9 100644 --- a/packages/ui/src/components/markdown.tsx +++ b/packages/ui/src/components/markdown.tsx @@ -5,6 +5,12 @@ import type { TextPart, RenderCache } from "../types/message" import { getLogger } from "../lib/logger" import { copyToClipboard } from "../lib/clipboard" import { useI18n } from "../lib/i18n" +import { + matches as searchMatches, + currentIndex as searchCurrentIndex, + isOpen as searchIsOpen, + query as searchQuery, +} from "../stores/search-store" const log = getLogger("session") @@ -28,6 +34,8 @@ interface MarkdownProps { part: TextPart instanceId?: string sessionId?: string + messageId?: string + partIndex?: number isDark?: boolean size?: "base" | "sm" | "tight" disableHighlight?: boolean @@ -39,6 +47,201 @@ export function Markdown(props: MarkdownProps) { const [html, setHtml] = createSignal("") let containerRef: HTMLDivElement | undefined let latestRequestedText = "" + let highlightTimeout: ReturnType | undefined + + function clearSearchMarks() { + if (!containerRef) return + const marks = containerRef.querySelectorAll("mark.search-match") + for (const mark of Array.from(marks)) { + const parent = mark.parentNode + if (!parent) continue + parent.replaceChild(document.createTextNode(mark.textContent ?? ""), mark) + parent.normalize() + } + } + + function applySearchHighlights() { + if (!containerRef) return + + // Early check: container must have content + if (!containerRef.hasChildNodes()) return + + if (!searchIsOpen()) { + clearSearchMarks() + return + } + + const q = searchQuery() + if (!q) { + clearSearchMarks() + return + } + + // If store has no matches, do nothing. + // (We still clear to remove stale highlights.) + const allMatches = searchMatches() + if (allMatches.length === 0) { + clearSearchMarks() + return + } + + // Best-effort DOM highlight for markdown blocks: wrap occurrences in text nodes. + // We intentionally avoid code/pre/link nodes to prevent breaking markup. + clearSearchMarks() + + const queryLower = q.toLowerCase() + const scopeMessageId = props.messageId + const scopePartIndex = typeof props.partIndex === "number" ? props.partIndex : null + + let nodes: Text[] = [] + try { + const walker = document.createTreeWalker(containerRef, NodeFilter.SHOW_TEXT, { + acceptNode(node) { + const text = node.textContent + if (!text || !text.trim()) return NodeFilter.FILTER_REJECT + const parent = (node as Text).parentElement + if (!parent) return NodeFilter.FILTER_REJECT + if (parent.closest("code, pre, a")) return NodeFilter.FILTER_REJECT + if (parent.closest("mark.search-match")) return NodeFilter.FILTER_REJECT + return NodeFilter.FILTER_ACCEPT + }, + }) + + let currentNode: Node | null + while ((currentNode = walker.nextNode())) { + nodes.push(currentNode as Text) + } + } catch (error) { + log.error("Error during TreeWalker traversal:", error) + return + } + + let globalIndexOffset = 0 + // Track occurrence index within this (messageId, partIndex) scope for navigation + let occurrenceIndex = 0 + + try { + for (const textNode of nodes) { + const original = textNode.textContent ?? "" + const haystack = original.toLowerCase() + let fromIndex = 0 + const occurrences: Array<{ start: number; end: number }> = [] + + while (true) { + const at = haystack.indexOf(queryLower, fromIndex) + if (at === -1) break + occurrences.push({ start: at, end: at + q.length }) + fromIndex = at + 1 + if (occurrences.length > 200) break + } + + if (occurrences.length === 0) { + globalIndexOffset += original.length + continue + } + + const fragment = document.createDocumentFragment() + let last = 0 + for (const occ of occurrences) { + if (occ.start > last) { + fragment.appendChild(document.createTextNode(original.slice(last, occ.start))) + } + const mark = document.createElement("mark") + mark.className = "search-match" + mark.setAttribute("data-search-match", "true") + if (scopeMessageId && scopePartIndex !== null) { + const globalStart = globalIndexOffset + occ.start + const globalEnd = globalIndexOffset + occ.end + mark.setAttribute("data-search-message-id", scopeMessageId) + mark.setAttribute("data-search-part-index", String(scopePartIndex)) + mark.setAttribute("data-search-start", String(globalStart)) + mark.setAttribute("data-search-end", String(globalEnd)) + // Add occurrence index for reliable navigation + mark.setAttribute("data-search-occurrence", String(occurrenceIndex)) + occurrenceIndex++ + } + mark.textContent = original.slice(occ.start, occ.end) + fragment.appendChild(mark) + last = occ.end + } + if (last < original.length) { + fragment.appendChild(document.createTextNode(original.slice(last))) + } + + textNode.parentNode?.replaceChild(fragment, textNode) + globalIndexOffset += original.length + } + } catch (error) { + log.error("Error applying search highlights:", error) + } + + // Distinguish the current match. + // First, remove any existing --current class to ensure clean state + try { + const existingCurrent = containerRef.querySelector("mark.search-match--current") + if (existingCurrent) { + existingCurrent.classList.remove("search-match--current") + } + } catch { + // Ignore errors during cleanup + } + + try { + const idx = searchCurrentIndex() + if (idx >= 0) { + const currentMatch = allMatches[idx] + + // Only proceed if this message/part contains the current match + if (scopeMessageId && scopePartIndex !== null && currentMatch && + currentMatch.messageId === scopeMessageId && + currentMatch.partIndex === scopePartIndex) { + + // Method 1: Try direct start/end index matching first + const directSelector = + `mark.search-match[data-search-match="true"]` + + `[data-search-message-id="${CSS.escape(scopeMessageId)}"]` + + `[data-search-part-index="${scopePartIndex}"]` + + `[data-search-start="${currentMatch.startIndex}"]` + + `[data-search-end="${currentMatch.endIndex}"]` + const directMark = containerRef.querySelector(directSelector) + if (directMark) { + directMark.classList.add("search-match--current") + return + } + + // Method 2: Use occurrence index - calculate which occurrence this is + // Get all matches for this message/part from the store, sorted by position + const partMatches = allMatches + .filter((m) => m.messageId === scopeMessageId && m.partIndex === scopePartIndex) + .slice() + .sort((a, b) => a.startIndex - b.startIndex) + + const occIdx = partMatches.findIndex( + (m) => + m.startIndex === currentMatch.startIndex && + m.endIndex === currentMatch.endIndex && + m.messageId === currentMatch.messageId && + m.partIndex === currentMatch.partIndex + ) + + if (occIdx >= 0) { + const occSelector = + `mark.search-match[data-search-match="true"]` + + `[data-search-message-id="${CSS.escape(scopeMessageId)}"]` + + `[data-search-part-index="${scopePartIndex}"]` + + `[data-search-occurrence="${occIdx}"]` + const occMark = containerRef.querySelector(occSelector) + if (occMark) { + occMark.classList.add("search-match--current") + return + } + } + } + } + } catch (error) { + log.error("Error marking current match:", error) + } + } const notifyRendered = () => { Promise.resolve().then(() => props.onRendered?.()) @@ -197,10 +400,84 @@ export function Markdown(props: MarkdownProps) { onCleanup(() => { containerRef?.removeEventListener("click", handleClick) cleanupLanguageListener() + + // Clear any pending timeout + if (highlightTimeout) { + clearTimeout(highlightTimeout) + highlightTimeout = undefined + } }) }) const proseClass = () => "markdown-body" + function waitForDOMAndApplyHighlights() { + if (!containerRef) return + + // Clear any existing timeout + if (highlightTimeout) { + clearTimeout(highlightTimeout) + highlightTimeout = undefined + } + + // Early exit if no container content or search not active + if (!containerRef.hasChildNodes() || !searchIsOpen() || !searchQuery() || searchMatches().length === 0) { + applySearchHighlights() + return + } + + // Retry logic with rAF to wait for DOM to fully render + let retryCount = 0 + const maxRetries = 8 + + const tryApplyHighlights = () => { + if (retryCount >= maxRetries) { + // Max retries reached, apply highlights anyway + applySearchHighlights() + return + } + + // Count existing highlighted nodes before applying + const existingHighlights = containerRef!.querySelectorAll("mark.search-match").length + + // Apply highlights + applySearchHighlights() + + // Count highlighted nodes after applying + const newHighlights = containerRef!.querySelectorAll("mark.search-match").length + + // Check if we found all expected matches + const expectedMatches = searchMatches().length + const expectedForThisPart = expectedMatches > 0 ? expectedMatches : 0 + + // If we found highlights, or no matches expected, or content is stable + if (newHighlights > 0 || expectedForThisPart === 0 || existingHighlights === newHighlights && retryCount > 2) { + // Success or stable, no need to retry + return + } + + // Retry after one frame + retryCount++ + highlightTimeout = setTimeout(() => { + requestAnimationFrame(tryApplyHighlights) + }, 0) + } + + // Start retry sequence + tryApplyHighlights() + } + + createEffect(() => { + // Re-apply DOM highlights when search state changes + searchIsOpen() + searchQuery() + searchMatches() + searchCurrentIndex() + + // Wait for DOM to fully render before applying highlights + waitForDOMAndApplyHighlights() + }) + + {/* eslint-disable-next-line solid/no-innerhtml */} return
} diff --git a/packages/ui/src/components/message-block.tsx b/packages/ui/src/components/message-block.tsx index 8b1dcb48..bd88f767 100644 --- a/packages/ui/src/components/message-block.tsx +++ b/packages/ui/src/components/message-block.tsx @@ -1,5 +1,5 @@ -import { For, Match, Show, Switch, createEffect, createMemo, createSignal, untrack } from "solid-js" -import { ExternalLink, FoldVertical, Trash2 } from "lucide-solid" +import { For, Match, Show, Switch, createEffect, createMemo, createSignal, onCleanup, untrack } from "solid-js" +import { FoldVertical } from "lucide-solid" import MessageItem from "./message-item" import ToolCall from "./tool-call" import type { InstanceMessageStore } from "../stores/message-v2/instance-store" @@ -11,14 +11,14 @@ import { messageStoreBus } from "../stores/message-v2/bus" import { formatTokenTotal } from "../lib/formatters" import { sessions, setActiveParentSession, setActiveSession } from "../stores/sessions" import { setActiveInstanceId } from "../stores/instances" -import { showAlertDialog } from "../stores/alerts" -import { deleteMessagePart } from "../stores/session-actions" import { useI18n } from "../lib/i18n" +import { SECTION_EXPANSION_EVENT, type SectionExpansionRequest } from "../lib/section-expansion" const TOOL_ICON = "🔧" const USER_BORDER_COLOR = "var(--message-user-border)" const ASSISTANT_BORDER_COLOR = "var(--message-assistant-border)" const TOOL_BORDER_COLOR = "var(--message-tool-border)" +const QUESTION_BORDER_COLOR = "var(--message-question-border)" type ToolCallPart = Extract @@ -174,256 +174,21 @@ messageStoreBus.onInstanceDestroyed(clearInstanceCaches) interface ContentDisplayItem { type: "content" key: string - messageId: string - startPartId: string + record: MessageRecord + parts: ClientPart[] + messageInfo?: MessageInfo + isQueued: boolean + showAgentMeta?: boolean } interface ToolDisplayItem { type: "tool" key: string + toolPart: ToolCallPart + messageInfo?: MessageInfo messageId: string - partId: string -} - -interface MessageContentItemProps { - instanceId: string - sessionId: string - store: () => InstanceMessageStore - messageId: string - startPartId: string - messageIndex: number - lastAssistantIndex: () => number - onRevert?: (messageId: string) => void - onFork?: (messageId?: string) => void - onContentRendered?: () => void -} - -function MessageContentItem(props: MessageContentItemProps) { - const record = createMemo(() => props.store().getMessage(props.messageId)) - const messageInfo = createMemo(() => props.store().getMessageInfo(props.messageId)) - - const isQueued = createMemo(() => { - const current = record() - if (!current) return false - if (current.role !== "user") return false - const lastAssistant = props.lastAssistantIndex() - return lastAssistant === -1 || props.messageIndex > lastAssistant - }) - - const parts = createMemo(() => { - const current = record() - if (!current) return [] - const ids = current.partIds - const startIndex = ids.indexOf(props.startPartId) - if (startIndex === -1) return [] - - const resolved: ClientPart[] = [] - for (let idx = startIndex; idx < ids.length; idx++) { - const partId = ids[idx] - const part = current.parts[partId]?.data - if (!part) continue - if ( - part.type === "tool" || - part.type === "reasoning" || - part.type === "compaction" || - part.type === "step-start" || - part.type === "step-finish" - ) { - break - } - resolved.push(part) - } - - return resolved - }) - - const showAgentMeta = createMemo(() => { - const current = record() - if (!current) return false - if (current.role !== "assistant") return false - - const currentParts = parts() - if (!currentParts.some((part) => partHasRenderableText(part))) { - return false - } - - const ids = current.partIds - const startIndex = ids.indexOf(props.startPartId) - if (startIndex === -1) return false - - // Only show agent meta on the first content segment that contains renderable content. - for (let idx = 0; idx < startIndex; idx++) { - const partId = ids[idx] - const part = current.parts[partId]?.data - if (!part) continue - if ( - part.type === "tool" || - part.type === "reasoning" || - part.type === "compaction" || - part.type === "step-start" || - part.type === "step-finish" - ) { - continue - } - if (partHasRenderableText(part)) { - return false - } - } - - return true - }) - - return ( - - {(resolvedRecord) => ( - - )} - - ) -} - -interface ToolCallItemProps { - instanceId: string - sessionId: string - store: () => InstanceMessageStore - messageId: string - partId: string - onContentRendered?: () => void -} - -function ToolCallItem(props: ToolCallItemProps) { - const { t } = useI18n() - const [deleting, setDeleting] = createSignal(false) - - const record = createMemo(() => props.store().getMessage(props.messageId)) - const messageInfo = createMemo(() => props.store().getMessageInfo(props.messageId)) - const partEntry = createMemo(() => record()?.parts?.[props.partId]) - - const toolPart = createMemo(() => { - const part = partEntry()?.data as ClientPart | undefined - if (!part || part.type !== "tool") return undefined - return part as ToolCallPart - }) - - const toolState = createMemo(() => toolPart()?.state as ToolState | undefined) - const toolName = createMemo(() => toolPart()?.tool || "") - const messageVersion = createMemo(() => record()?.revision ?? 0) - const partVersion = createMemo(() => partEntry()?.revision ?? 0) - - const deleteDisabled = createMemo(() => { - if (deleting()) return true - // Avoid deleting while a tool is actively running to prevent confusing UI states. - if (isToolStateRunning(toolState())) return true - // Avoid deleting permission prompts from here; those are interactive. - return Boolean(toolPart()?.pendingPermission) - }) - - const taskSessionId = createMemo(() => { - const state = toolState() - if (!state) return "" - if (!(isToolStateRunning(state) || isToolStateCompleted(state) || isToolStateError(state))) { - return "" - } - return extractTaskSessionId(state) - }) - - const taskLocation = createMemo(() => { - const id = taskSessionId() - if (!id) return null - return findTaskSessionLocation(id, props.instanceId) - }) - - const handleGoToTaskSession = (event: MouseEvent) => { - event.preventDefault() - event.stopPropagation() - const location = taskLocation() - if (!location) return - navigateToTaskSession(location) - } - - const handleDeleteToolPart = async (event: MouseEvent) => { - event.preventDefault() - event.stopPropagation() - - if (deleteDisabled()) return - - setDeleting(true) - try { - await deleteMessagePart(props.instanceId, props.sessionId, props.messageId, props.partId) - } catch (error) { - showAlertDialog(t("messageBlock.tool.deletePart.failed.message"), { - title: t("messageBlock.tool.deletePart.failed.title"), - detail: error instanceof Error ? error.message : String(error), - variant: "error", - }) - } finally { - setDeleting(false) - } - } - - return ( - - {(resolvedToolPart) => ( - <> -
-
- {TOOL_ICON} - {t("messageBlock.tool.header")} - {toolName() || t("messageBlock.tool.unknown")} -
- -
- - - - - -
-
- - - - )} -
- ) + messageVersion: number + partVersion: number } interface StepDisplayItem { @@ -441,8 +206,6 @@ type ReasoningDisplayItem = { messageInfo?: MessageInfo showAgentMeta?: boolean defaultExpanded: boolean - messageId: string - partId: string } type CompactionDisplayItem = { @@ -451,8 +214,6 @@ type CompactionDisplayItem = { part: ClientPart messageInfo?: MessageInfo accentColor?: string - messageId: string - partId: string } type MessageBlockItem = ContentDisplayItem | ToolDisplayItem | StepDisplayItem | ReasoningDisplayItem | CompactionDisplayItem @@ -513,35 +274,41 @@ export default function MessageBlock(props: MessageBlockProps) { const items: MessageBlockItem[] = [] const blockContentKeys: string[] = [] const blockToolKeys: string[] = [] + let segmentIndex = 0 let pendingParts: ClientPart[] = [] - let agentMetaAttached = current.role !== "assistant" + let agentMetaAttached = false const defaultAccentColor = current.role === "user" ? USER_BORDER_COLOR : ASSISTANT_BORDER_COLOR let lastAccentColor = defaultAccentColor const flushContent = () => { if (pendingParts.length === 0) return - const startPartId = typeof (pendingParts[0] as any)?.id === "string" ? ((pendingParts[0] as any).id as string) : "" - if (!startPartId) { - pendingParts = [] - return - } - - if (!agentMetaAttached && pendingParts.some((part) => partHasRenderableText(part))) { - agentMetaAttached = true - } - - const segmentKey = `${current.id}:content:${startPartId}` + const segmentKey = `${current.id}:segment:${segmentIndex}` + segmentIndex += 1 + const shouldShowAgentMeta = + !agentMetaAttached && + pendingParts.some((part) => partHasRenderableText(part)) let cached = sessionCache.messageItems.get(segmentKey) if (!cached) { cached = { type: "content", key: segmentKey, - messageId: current.id, - startPartId, + record: current, + parts: pendingParts.slice(), + messageInfo: info, + isQueued, + showAgentMeta: shouldShowAgentMeta, } sessionCache.messageItems.set(segmentKey, cached) + } else { + cached.record = current + cached.parts = pendingParts.slice() + cached.messageInfo = info + cached.isQueued = isQueued + cached.showAgentMeta = shouldShowAgentMeta + } + if (shouldShowAgentMeta) { + agentMetaAttached = true } - items.push(cached) blockContentKeys.push(segmentKey) lastAccentColor = defaultAccentColor @@ -551,37 +318,42 @@ export default function MessageBlock(props: MessageBlockProps) { orderedParts.forEach((part, partIndex) => { if (part.type === "tool") { flushContent() - const partId = part.id - if (!partId) { - // Tool parts are required to have ids; if one slips through, skip rendering - // to avoid unstable keys and accidental remount cascades. - return - } - const key = `${current.id}:${partId}` + const partVersion = typeof (part as any).revision === "number" ? (part as any).revision : 0 + const messageVersion = current.revision + const key = `${current.id}:${part.id ?? partIndex}` let toolItem = sessionCache.toolItems.get(key) if (!toolItem) { toolItem = { type: "tool", key, + toolPart: part as ToolCallPart, + messageInfo: info, messageId: current.id, - partId, + messageVersion, + partVersion, } sessionCache.toolItems.set(key, toolItem) } else { toolItem.key = key + toolItem.toolPart = part as ToolCallPart + toolItem.messageInfo = info toolItem.messageId = current.id - toolItem.partId = partId + toolItem.messageVersion = messageVersion + toolItem.partVersion = partVersion } items.push(toolItem) blockToolKeys.push(key) - lastAccentColor = TOOL_BORDER_COLOR + + // Use purple border for question tools, regular tool border for others + const toolName = (part as ToolCallPart).tool + const isQuestionTool = toolName === 'ask_user' || toolName === 'question' || toolName === 'codenomad_ask_user' + lastAccentColor = isQuestionTool ? QUESTION_BORDER_COLOR : TOOL_BORDER_COLOR return } if (part.type === "compaction") { flushContent() - const partId = part.id ?? "" - const key = `${current.id}:${partId || partIndex}:compaction` + const key = `${current.id}:${part.id ?? partIndex}:compaction` const isAuto = Boolean((part as any)?.auto) items.push({ type: "compaction", @@ -589,8 +361,6 @@ export default function MessageBlock(props: MessageBlockProps) { part, messageInfo: info, accentColor: isAuto ? "var(--session-status-compacting-fg)" : USER_BORDER_COLOR, - messageId: current.id, - partId, }) lastAccentColor = isAuto ? "var(--session-status-compacting-fg)" : USER_BORDER_COLOR return @@ -615,9 +385,8 @@ export default function MessageBlock(props: MessageBlockProps) { if (part.type === "reasoning") { flushContent() if (props.showThinking() && reasoningHasRenderableContent(part)) { - const partId = part.id ?? "" - const key = `${current.id}:${partId || partIndex}:reasoning` - const showAgentMeta = current.role === "assistant" && !agentMetaAttached + const key = `${current.id}:${part.id ?? partIndex}:reasoning` + const showAgentMeta = !agentMetaAttached if (showAgentMeta) { agentMetaAttached = true } @@ -628,8 +397,6 @@ export default function MessageBlock(props: MessageBlockProps) { messageInfo: info, showAgentMeta, defaultExpanded: props.thinkingDefaultExpanded(), - messageId: current.id, - partId, }) lastAccentColor = ASSISTANT_BORDER_COLOR } @@ -665,21 +432,21 @@ export default function MessageBlock(props: MessageBlockProps) { }) return ( - + {(resolvedBlock) => ( -
- +
+ {(item) => ( - {(() => { const toolItem = item as ToolDisplayItem + const toolState = toolItem.toolPart.state as ToolState | undefined + const hasToolState = + Boolean(toolState) && (isToolStateRunning(toolState) || isToolStateCompleted(toolState) || isToolStateError(toolState)) + const taskSessionId = hasToolState ? extractTaskSessionId(toolState) : "" + const taskLocation = taskSessionId ? findTaskSessionLocation(taskSessionId, props.instanceId) : null + const handleGoToTaskSession = (event: MouseEvent) => { + event.preventDefault() + event.stopPropagation() + if (!taskLocation) return + navigateToTaskSession(taskLocation) + } + return (
- +
+ {TOOL_ICON} + {t("messageBlock.tool.header")} + {toolItem.toolPart.tool || t("messageBlock.tool.unknown")} +
+ + + +
+
@@ -703,12 +502,7 @@ export default function MessageBlock(props: MessageBlockProps) { })()} - + - + @@ -760,19 +544,8 @@ interface StepCardProps { borderColor?: string } -interface CompactionCardProps { - part: ClientPart - messageInfo?: MessageInfo - borderColor?: string - instanceId: string - sessionId: string - messageId: string - partId: string -} - -function CompactionCard(props: CompactionCardProps) { +function CompactionCard(props: { part: ClientPart; messageInfo?: MessageInfo; borderColor?: string }) { const { t } = useI18n() - const [deleting, setDeleting] = createSignal(false) const isAuto = () => Boolean((props.part as any)?.auto) const label = () => (isAuto() ? t("messageBlock.compaction.autoLabel") : t("messageBlock.compaction.manualLabel")) const borderColor = () => props.borderColor ?? (isAuto() ? "var(--session-status-compacting-fg)" : USER_BORDER_COLOR) @@ -780,43 +553,13 @@ function CompactionCard(props: CompactionCardProps) { const containerClass = () => `message-compaction-card ${isAuto() ? "message-compaction-card--auto" : "message-compaction-card--manual"}` - const canDelete = () => Boolean(props.partId) && !deleting() - - const handleDelete = async (event: MouseEvent) => { - event.preventDefault() - event.stopPropagation() - if (!canDelete()) return - setDeleting(true) - try { - await deleteMessagePart(props.instanceId, props.sessionId, props.messageId, props.partId) - } catch (error) { - showAlertDialog(t("messagePart.actions.deleteFailedMessage"), { - title: t("messagePart.actions.deleteFailedTitle"), - detail: error instanceof Error ? error.message : String(error), - variant: "error", - }) - } finally { - setDeleting(false) - } - } - return (
- -