From 41a46a3840f5f8d7187a398ee20853b9ac29b8b1 Mon Sep 17 00:00:00 2001 From: hsteude Date: Wed, 21 Jan 2026 18:29:46 +0200 Subject: [PATCH 001/144] feat: add prokube/app-prefixable with agent prompt for prefix-aware UI --- prokube/app-prefixable/AGENT_PROMPT.md | 609 +++++++++++++++++++++++++ 1 file changed, 609 insertions(+) create mode 100644 prokube/app-prefixable/AGENT_PROMPT.md diff --git a/prokube/app-prefixable/AGENT_PROMPT.md b/prokube/app-prefixable/AGENT_PROMPT.md new file mode 100644 index 00000000000..e50d5105947 --- /dev/null +++ b/prokube/app-prefixable/AGENT_PROMPT.md @@ -0,0 +1,609 @@ +# Coding Agent Prompt: Prefix-Aware Web UI for OpenCode + +## Objective + +Create a new, prefix-aware Web UI for OpenCode that can be deployed under any URL path prefix (e.g., `/opencode/`, `/tools/ai/`, etc.). This UI should achieve feature parity with the existing `packages/app` but be designed from the ground up to support dynamic base paths. + +--- + +## Background & Context + +### Current Architecture + +The existing OpenCode Web UI is located in `packages/app` and uses: + +- **Framework**: SolidJS +- **Build Tool**: Vite +- **Styling**: TailwindCSS +- **Routing**: `@solidjs/router` + +The backend API server runs on port 4096 and exposes: + +- REST endpoints for sessions, providers, config, etc. +- SSE endpoint `/event` for real-time updates +- OpenAPI spec at `/doc` + +### Problem with Current Setup + +Making Vite-based apps prefix-aware retroactively is painful because: + +1. Vite's `base` option requires rebuild for each prefix +2. Assets, router, and API calls all need separate handling +3. Hot-reload breaks in dev mode with prefixes +4. Many hardcoded `/` paths throughout the codebase + +### Solution + +Build a new UI package from scratch that: + +1. Uses **Bun Bundler** instead of Vite (native `publicPath` support) +2. Reads the prefix at **runtime** (not build-time) +3. Uses relative paths where possible +4. Has a single injection point for the base path + +--- + +## Technical Requirements + +### 1. Package Setup + +Create the new UI in the top-level `prokube/` directory (separate from upstream `packages/`): + +``` +prokube/app-prefixable/ +├── src/ +│ ├── index.html # HTML template with base path injection +│ ├── entry.tsx # Main entry point +│ ├── app.tsx # Root app component +│ ├── context/ +│ │ ├── base-path.tsx # Base path context provider +│ │ ├── sdk.tsx # SDK context (reuse from packages/app) +│ │ └── ... # Other contexts as needed +│ ├── pages/ +│ │ ├── home.tsx +│ │ ├── session.tsx +│ │ └── layout.tsx +│ ├── components/ +│ │ └── ... # Reuse from packages/ui where possible +│ └── utils/ +│ └── path.ts # Path utilities for prefix handling +├── build.ts # Bun build script +├── dev.ts # Development server script +├── package.json +└── tsconfig.json +``` + +### 2. Build Configuration (`build.ts`) + +```typescript +import { $ } from "bun" + +const BASE_PATH = process.env.BASE_PATH || "/" + +await Bun.build({ + entrypoints: ["./src/index.html"], + outdir: "./dist", + publicPath: BASE_PATH, + minify: process.env.NODE_ENV === "production", + splitting: true, + sourcemap: "linked", + define: { + "import.meta.env.BASE_PATH": JSON.stringify(BASE_PATH), + }, +}) + +// Copy static assets +await $`cp -r ./public/* ./dist/` +``` + +### 3. Runtime Base Path Detection + +The UI should support multiple ways to determine the base path: + +```typescript +// src/utils/path.ts +export function getBasePath(): string { + // Priority order: + // 1. Explicit config in window.__OPENCODE__ + // 2. tag + // 3. Build-time injected value + // 4. Auto-detect from current URL + + if (typeof window !== "undefined") { + // From global config + if (window.__OPENCODE__?.basePath) { + return normalizeBasePath(window.__OPENCODE__.basePath) + } + + // From tag + const baseTag = document.querySelector("base") + if (baseTag?.href) { + const url = new URL(baseTag.href) + return normalizeBasePath(url.pathname) + } + } + + // Build-time value + if (import.meta.env.BASE_PATH) { + return normalizeBasePath(import.meta.env.BASE_PATH) + } + + return "/" +} + +export function normalizeBasePath(path: string): string { + // Ensure leading slash, trailing slash + let normalized = path.trim() + if (!normalized.startsWith("/")) normalized = "/" + normalized + if (!normalized.endsWith("/")) normalized = normalized + "/" + return normalized +} + +export function prefixPath(path: string, basePath: string): string { + if (path.startsWith("http://") || path.startsWith("https://")) { + return path // Absolute URLs unchanged + } + const base = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath + const suffix = path.startsWith("/") ? path : "/" + path + return base + suffix +} +``` + +### 4. Base Path Context + +```typescript +// src/context/base-path.tsx +import { createContext, useContext, type ParentProps } from "solid-js" +import { getBasePath, prefixPath } from "../utils/path" + +interface BasePathContextValue { + basePath: string + prefix: (path: string) => string + apiUrl: string +} + +const BasePathContext = createContext() + +export function BasePathProvider(props: ParentProps & { apiUrl?: string }) { + const basePath = getBasePath() + + const value: BasePathContextValue = { + basePath, + prefix: (path: string) => prefixPath(path, basePath), + apiUrl: props.apiUrl || deriveApiUrl(basePath), + } + + return ( + + {props.children} + + ) +} + +export function useBasePath() { + const ctx = useContext(BasePathContext) + if (!ctx) throw new Error("useBasePath must be used within BasePathProvider") + return ctx +} + +function deriveApiUrl(basePath: string): string { + // If running on same origin, API is at origin root + // Otherwise, check for explicit config + if (window.__OPENCODE__?.serverUrl) { + return window.__OPENCODE__.serverUrl + } + return window.location.origin +} +``` + +### 5. Router Configuration + +```typescript +// src/app.tsx +import { Router, Route } from "@solidjs/router" +import { useBasePath } from "./context/base-path" + +export function App() { + const { basePath } = useBasePath() + + return ( + {/* Router wants no trailing slash */} + + + + + ) +} +``` + +### 6. HTML Template + +```html + + + + + + + OpenCode + + + + + +
+ + + + +``` + +### 7. Development Server (`dev.ts`) + +```typescript +import { watch } from "fs" + +const BASE_PATH = process.env.BASE_PATH || "/" +const PORT = process.env.PORT || 3000 + +// Build initially +await import("./build") + +// Start dev server +const server = Bun.serve({ + port: PORT, + async fetch(req) { + const url = new URL(req.url) + let path = url.pathname + + // Strip base path prefix for file lookup + if (path.startsWith(BASE_PATH)) { + path = path.slice(BASE_PATH.length - 1) || "/" + } + + // Try to serve static file + const file = Bun.file(`./dist${path}`) + if (await file.exists()) { + return new Response(file) + } + + // SPA fallback - serve index.html + const indexHtml = await Bun.file("./dist/index.html").text() + const injected = indexHtml.replace('', ``) + return new Response(injected, { + headers: { "Content-Type": "text/html" }, + }) + }, +}) + +console.log(`Dev server running at http://localhost:${PORT}${BASE_PATH}`) + +// Watch for changes and rebuild +watch("./src", { recursive: true }, async () => { + console.log("Rebuilding...") + await import("./build") + console.log("Done") +}) +``` + +### 8. Server-Side Integration + +The Hono backend server should serve the UI with the correct base path. Add to `packages/opencode/src/server/server.ts`: + +```typescript +// Serve UI with base path support +app.get("/*", async (c) => { + const basePath = Flag.OPENCODE_UI_BASE_PATH || "/" + + // Read and inject base path into index.html + const indexHtml = await Bun.file("path/to/dist/index.html").text() + const injected = indexHtml + .replace('', ``) + .replace( + "window.__OPENCODE__ = window.__OPENCODE__ || {};", + `window.__OPENCODE__ = { basePath: "${basePath}", serverUrl: "${serverUrl}" };`, + ) + + return c.html(injected) +}) +``` + +--- + +## Feature Parity Checklist + +The new UI must support all features from the existing `packages/app`: + +### Core Features + +- [ ] Session list and management +- [ ] Chat interface with message streaming +- [ ] Code blocks with syntax highlighting +- [ ] Diff viewer for file changes +- [ ] Markdown rendering + +### Settings & Configuration + +- [ ] Provider configuration (API keys, models) +- [ ] Model selection dialog +- [ ] MCP server configuration +- [ ] Keybinds settings +- [ ] Permissions settings +- [ ] Agent configuration + +### UI Components + +- [ ] Command palette +- [ ] File tree +- [ ] Terminal integration +- [ ] Toast notifications +- [ ] Dialogs (confirm, prompt, select) +- [ ] Tooltips and hover cards + +### Contexts to Implement + +Reuse or port from `packages/app/src/context/`: + +- [ ] `server.tsx` - Server connection management +- [ ] `sdk.tsx` - SDK client wrapper +- [ ] `settings.tsx` - User settings persistence +- [ ] `permission.tsx` - Permission handling +- [ ] `terminal.tsx` - Terminal integration +- [ ] `file.tsx` - File operations +- [ ] `prompt.tsx` - Prompt input handling +- [ ] `command.tsx` - Command system +- [ ] `notification.tsx` - Notifications +- [ ] `language.tsx` - i18n + +--- + +## Shared UI Components + +Reuse components from `packages/ui/` where possible: + +- Button, Dialog, Tabs, Select, etc. +- Markdown renderer +- Diff viewer +- Code blocks +- Theme system +- i18n utilities + +Import like: + +```typescript +import { Button } from "@opencode-ai/ui/button" +import { Dialog } from "@opencode-ai/ui/dialog" +import { Markdown } from "@opencode-ai/ui/markdown" +``` + +--- + +## Testing the Prefix + +Test with different base paths: + +```bash +# Default (root) +bun run dev + +# With prefix +BASE_PATH=/opencode/ bun run dev + +# With nested prefix +BASE_PATH=/tools/ai/opencode/ bun run dev +``` + +Verify: + +1. All assets load correctly +2. Router navigation works +3. API calls reach the backend +4. Page refresh maintains correct path +5. Direct URL access works + +--- + +## Key Principles + +1. **No hardcoded absolute paths** - Always use the `prefix()` helper or relative paths +2. **Runtime configuration** - Base path should be configurable without rebuild +3. **Graceful fallback** - If no base path configured, default to `/` +4. **Asset path consistency** - All assets (JS, CSS, images, fonts) must use prefixed paths +5. **API separation** - API URL is separate from UI base path + +--- + +## CLI Flags for Server + +Add these flags to the OpenCode server: + +```typescript +// In Flag module +export const OPENCODE_UI_BASE_PATH = process.env.OPENCODE_UI_BASE_PATH || "/" +export const OPENCODE_UI_ENABLED = process.env.OPENCODE_UI_ENABLED !== "false" +``` + +Usage: + +```bash +opencode server --ui-base-path=/opencode/ --port=4096 +``` + +--- + +## Deliverables + +1. New UI at `prokube/app-prefixable/` +2. Build script using Bun bundler +3. Development server with hot reload +4. Full feature parity with existing UI +5. Documentation for deployment with custom prefixes +6. Integration with existing Hono server + +--- + +## Resources + +- Existing UI: `packages/app/src/` +- Shared UI components: `packages/ui/src/` +- SDK: `packages/sdk/js/src/` +- Server: `packages/opencode/src/server/` +- Bun Bundler docs: https://bun.sh/docs/bundler +- SolidJS Router: https://docs.solidjs.com/solid-router + +--- + +## Fork & Upstream Sync Strategy + +This project is a fork of the upstream OpenCode repository. To ensure smooth upstream updates, follow these **critical rules**: + +### Golden Rule: Never Modify Upstream Files + +**ONLY add new files. NEVER modify existing upstream files.** + +This means: + +- Create `prokube/app-prefixable/` as a NEW directory +- Do NOT modify `packages/app/`, `packages/ui/`, `packages/opencode/`, etc. +- Do NOT modify `package.json` in the root (use a separate workspace config if needed) + +### Why This Matters + +When rebasing on upstream: + +- **New files** = No conflicts, ever +- **Modified files** = Potential merge conflicts on every rebase + +### Wrapper Pattern for Upstream Components + +If you need to modify behavior of an upstream component, create a wrapper: + +```typescript +// WRONG: Modifying packages/ui/src/components/button.tsx +// This will cause rebase conflicts! + +// CORRECT: Create prokube/app-prefixable/src/components/button.tsx +import { Button as UpstreamButton, type ButtonProps } from "@opencode-ai/ui/button" +import { useBasePath } from "../context/base-path" + +export function Button(props: ButtonProps & { href?: string }) { + const { prefix } = useBasePath() + + const href = props.href ? prefix(props.href) : undefined + + return +} +``` + +### Extending Upstream Contexts + +Same pattern for contexts: + +```typescript +// prokube/app-prefixable/src/context/sdk.tsx +import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" +import { useBasePath } from "./base-path" + +// Wrap the upstream SDK with your prefix-aware logic +export function useSDK() { + const { apiUrl } = useBasePath() + + return createOpencodeClient({ + baseUrl: apiUrl, + // ... your config + }) +} +``` + +### Directory Structure + +``` +opencode/ # Fork of upstream +├── packages/ # UPSTREAM - DO NOT TOUCH +│ ├── app/ +│ ├── ui/ +│ ├── opencode/ +│ └── sdk/ +│ +├── prokube/ # YOUR CODE - Safe to modify +│ └── app-prefixable/ +│ ├── src/ +│ ├── build.ts +│ └── package.json +│ +├── package.json # UPSTREAM - DO NOT TOUCH +└── pnpm-workspace.yaml # UPSTREAM - If you must add workspace, see below +``` + +### If You Must Modify Root Config + +If you absolutely need to add `prokube/app-prefixable` to the workspace, create a separate file: + +```yaml +# pnpm-workspace.prokube.yaml (NEW FILE) +packages: + - "packages/*" + - "prokube/*" +``` + +Then use: `pnpm install --workspace-file=pnpm-workspace.prokube.yaml` + +Or, add the package to `.gitignore` patterns that won't conflict. + +### Rebase Workflow + +```bash +# 1. Fetch upstream +git fetch upstream + +# 2. Rebase your branch onto upstream/dev +git rebase upstream/dev + +# 3. If you followed the rules: zero conflicts +# 4. Force push to your fork +git push --force-with-lease origin your-branch +``` + +### Testing After Rebase + +After each rebase, verify: + +1. `prokube/app-prefixable` still builds +2. Imports from `@opencode-ai/ui` still resolve +3. SDK types are still compatible +4. No breaking changes in upstream API + +### Handling Breaking Upstream Changes + +If upstream changes break your code: + +1. **API changes in `@opencode-ai/sdk`**: Update your SDK usage in `app-prefixable` +2. **Component changes in `@opencode-ai/ui`**: Update your wrappers +3. **Server changes**: May need to adapt your server integration + +Document any upstream version requirements in your package.json: + +```json +{ + "name": "@prokube/app-prefixable", + "peerDependencies": { + "@opencode-ai/ui": ">=1.1.0", + "@opencode-ai/sdk": ">=1.1.0" + } +} +``` + +--- + +## Notes + +- Prioritize correctness over performance initially +- Test with real OpenCode sessions, not just static pages +- Ensure SSE events work correctly through the proxy +- Consider CORS implications when API is on different origin +- **Always test rebase before pushing to ensure no conflicts** From 8fdfd996e696a6773ef5cd48cf9f6437309a0931 Mon Sep 17 00:00:00 2001 From: hsteude Date: Thu, 22 Jan 2026 08:09:11 +0200 Subject: [PATCH 002/144] feat(prokube): add prefix-aware web UI with SSE streaming and markdown support - esbuild + SolidJS build system with PostCSS/Tailwind - Runtime prefix detection via window.__OPENCODE__.basePath - Dev server with API proxy for backend at 127.0.0.1:4096 - Improved SSE streaming through proxy with TransformStream - Session page with message sending and polling fallback - Markdown rendering for assistant messages - Full component library (layout, sidebar, session list) --- bun.lock | 1170 ++++++++++++----- package.json | 3 +- prokube/app-prefixable/AGENTS.md | 69 + prokube/app-prefixable/build.ts | 50 + prokube/app-prefixable/dev.ts | 163 +++ prokube/app-prefixable/package.json | 33 + prokube/app-prefixable/postcss.config.js | 6 + prokube/app-prefixable/src/app.tsx | 31 + .../src/components/markdown.tsx | 22 + .../app-prefixable/src/context/base-path.tsx | 28 + prokube/app-prefixable/src/context/events.tsx | 89 ++ prokube/app-prefixable/src/context/sdk.tsx | 30 + prokube/app-prefixable/src/entry.tsx | 24 + prokube/app-prefixable/src/index.css | 341 +++++ prokube/app-prefixable/src/index.html | 39 + prokube/app-prefixable/src/pages/home.tsx | 41 + prokube/app-prefixable/src/pages/layout.tsx | 184 +++ prokube/app-prefixable/src/pages/session.tsx | 322 +++++ prokube/app-prefixable/src/utils/path.ts | 67 + prokube/app-prefixable/tailwind.config.js | 23 + prokube/app-prefixable/tsconfig.json | 23 + 21 files changed, 2396 insertions(+), 362 deletions(-) create mode 100644 prokube/app-prefixable/AGENTS.md create mode 100644 prokube/app-prefixable/build.ts create mode 100644 prokube/app-prefixable/dev.ts create mode 100644 prokube/app-prefixable/package.json create mode 100644 prokube/app-prefixable/postcss.config.js create mode 100644 prokube/app-prefixable/src/app.tsx create mode 100644 prokube/app-prefixable/src/components/markdown.tsx create mode 100644 prokube/app-prefixable/src/context/base-path.tsx create mode 100644 prokube/app-prefixable/src/context/events.tsx create mode 100644 prokube/app-prefixable/src/context/sdk.tsx create mode 100644 prokube/app-prefixable/src/entry.tsx create mode 100644 prokube/app-prefixable/src/index.css create mode 100644 prokube/app-prefixable/src/index.html create mode 100644 prokube/app-prefixable/src/pages/home.tsx create mode 100644 prokube/app-prefixable/src/pages/layout.tsx create mode 100644 prokube/app-prefixable/src/pages/session.tsx create mode 100644 prokube/app-prefixable/src/utils/path.ts create mode 100644 prokube/app-prefixable/tailwind.config.js create mode 100644 prokube/app-prefixable/tsconfig.json diff --git a/bun.lock b/bun.lock index 0857283634a..070ee1bb46b 100644 --- a/bun.lock +++ b/bun.lock @@ -23,7 +23,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -73,7 +73,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -107,7 +107,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -134,7 +134,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -158,7 +158,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -182,14 +182,12 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", - "@solid-primitives/i18n": "2.2.1", "@solid-primitives/storage": "catalog:", "@tauri-apps/api": "^2", - "@tauri-apps/plugin-deep-link": "~2", "@tauri-apps/plugin-dialog": "~2", "@tauri-apps/plugin-http": "~2", "@tauri-apps/plugin-notification": "~2", @@ -213,7 +211,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -242,7 +240,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -258,35 +256,35 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.1.48", + "version": "1.1.28", "bin": { "opencode": "./bin/opencode", }, "dependencies": { "@actions/core": "1.11.1", "@actions/github": "6.0.1", - "@agentclientprotocol/sdk": "0.13.0", - "@ai-sdk/amazon-bedrock": "3.0.74", - "@ai-sdk/anthropic": "2.0.58", + "@agentclientprotocol/sdk": "0.5.1", + "@ai-sdk/amazon-bedrock": "3.0.73", + "@ai-sdk/anthropic": "2.0.57", "@ai-sdk/azure": "2.0.91", - "@ai-sdk/cerebras": "1.0.36", + "@ai-sdk/cerebras": "1.0.34", "@ai-sdk/cohere": "2.0.22", - "@ai-sdk/deepinfra": "1.0.33", - "@ai-sdk/gateway": "2.0.30", + "@ai-sdk/deepinfra": "1.0.31", + "@ai-sdk/gateway": "2.0.25", "@ai-sdk/google": "2.0.52", - "@ai-sdk/google-vertex": "3.0.98", + "@ai-sdk/google-vertex": "3.0.97", "@ai-sdk/groq": "2.0.34", "@ai-sdk/mistral": "2.0.27", "@ai-sdk/openai": "2.0.89", - "@ai-sdk/openai-compatible": "1.0.32", + "@ai-sdk/openai-compatible": "1.0.30", "@ai-sdk/perplexity": "2.0.23", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", - "@ai-sdk/togetherai": "1.0.34", - "@ai-sdk/vercel": "1.0.33", - "@ai-sdk/xai": "2.0.56", + "@ai-sdk/togetherai": "1.0.31", + "@ai-sdk/vercel": "1.0.31", + "@ai-sdk/xai": "2.0.51", "@clack/prompts": "1.0.0-alpha.1", - "@gitlab/gitlab-ai-provider": "3.3.1", + "@gitlab/gitlab-ai-provider": "3.1.2", "@hono/standard-validator": "0.1.5", "@hono/zod-validator": "catalog:", "@modelcontextprotocol/sdk": "1.25.2", @@ -297,9 +295,9 @@ "@opencode-ai/script": "workspace:*", "@opencode-ai/sdk": "workspace:*", "@opencode-ai/util": "workspace:*", - "@openrouter/ai-sdk-provider": "1.5.4", - "@opentui/core": "0.1.75", - "@opentui/solid": "0.1.75", + "@openrouter/ai-sdk-provider": "1.5.2", + "@opentui/core": "0.1.74", + "@opentui/solid": "0.1.74", "@parcel/watcher": "2.5.1", "@pierre/diffs": "catalog:", "@solid-primitives/event-bus": "1.1.2", @@ -362,7 +360,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -382,9 +380,9 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.1.48", + "version": "1.1.28", "devDependencies": { - "@hey-api/openapi-ts": "0.90.10", + "@hey-api/openapi-ts": "0.90.4", "@tsconfig/node22": "catalog:", "@types/node": "catalog:", "@typescript/native-preview": "catalog:", @@ -393,7 +391,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -406,7 +404,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -425,7 +423,6 @@ "marked": "catalog:", "marked-katex-extension": "5.1.6", "marked-shiki": "catalog:", - "morphdom": "2.7.8", "remeda": "catalog:", "shiki": "catalog:", "solid-js": "catalog:", @@ -448,7 +445,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "zod": "catalog:", }, @@ -459,7 +456,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.1.48", + "version": "1.1.28", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", @@ -488,6 +485,31 @@ "typescript": "catalog:", }, }, + "prokube/app-prefixable": { + "name": "@prokube/app-prefixable", + "version": "0.0.1", + "dependencies": { + "@opencode-ai/sdk": "workspace:*", + "@opencode-ai/ui": "workspace:*", + "@opencode-ai/util": "workspace:*", + "@solidjs/router": "catalog:", + "marked": "catalog:", + "solid-js": "catalog:", + }, + "devDependencies": { + "@types/bun": "catalog:", + "autoprefixer": "^10.4.20", + "esbuild": "0.25.5", + "esbuild-plugin-solid": "0.6.0", + "postcss": "^8.5.6", + "tailwindcss": "^3.4.17", + "typescript": "catalog:", + }, + "peerDependencies": { + "@opencode-ai/sdk": ">=1.1.0", + "@opencode-ai/ui": ">=1.1.0", + }, + }, }, "trustedDependencies": [ "esbuild", @@ -521,7 +543,7 @@ "@types/node": "22.13.9", "@types/semver": "7.7.1", "@typescript/native-preview": "7.0.0-dev.20251207.1", - "ai": "5.0.124", + "ai": "5.0.119", "diff": "8.0.2", "dompurify": "3.3.1", "fuzzysort": "3.1.0", @@ -551,31 +573,31 @@ "@actions/github": ["@actions/github@6.0.1", "", { "dependencies": { "@actions/http-client": "^2.2.0", "@octokit/core": "^5.0.1", "@octokit/plugin-paginate-rest": "^9.2.2", "@octokit/plugin-rest-endpoint-methods": "^10.4.0", "@octokit/request": "^8.4.1", "@octokit/request-error": "^5.1.1", "undici": "^5.28.5" } }, "sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw=="], - "@actions/http-client": ["@actions/http-client@3.0.2", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^6.23.0" } }, "sha512-JP38FYYpyqvUsz+Igqlc/JG6YO9PaKuvqjM3iGvaLqFnJ7TFmcLyy2IDrY0bI0qCQug8E9K+elv5ZNfw62ZJzA=="], + "@actions/http-client": ["@actions/http-client@3.0.0", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^5.28.5" } }, "sha512-1s3tXAfVMSz9a4ZEBkXXRQD4QhY3+GAsWSbaYpeknPOKEeyRiU3lH+bHiLMZdo2x/fIeQ/hscL1wCkDLVM2DZQ=="], "@actions/io": ["@actions/io@1.1.3", "", {}, "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="], "@adobe/css-tools": ["@adobe/css-tools@4.4.4", "", {}, "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg=="], - "@agentclientprotocol/sdk": ["@agentclientprotocol/sdk@0.13.0", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Z6/Fp4cXLbYdMXr5AK752JM5qG2VKb6ShM0Ql6FimBSckMmLyK54OA20UhPYoH4C37FSFwUTARuwQOwQUToYrw=="], + "@agentclientprotocol/sdk": ["@agentclientprotocol/sdk@0.5.1", "", { "dependencies": { "zod": "^3.0.0" } }, "sha512-9bq2TgjhLBSUSC5jE04MEe+Hqw8YePzKghhYZ9QcjOyonY3q2oJfX6GoSO83hURpEnsqEPIrex6VZN3+61fBJg=="], - "@ai-sdk/amazon-bedrock": ["@ai-sdk/amazon-bedrock@3.0.74", "", { "dependencies": { "@ai-sdk/anthropic": "2.0.58", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-q83HE3FBb/HPIvjXsehrHOgCuGHPorSMFt6BYnzIYZy8gNnSqV1OWX4oXVsCAuYPPMtYW/KMK35hmoIFV8QKoQ=="], + "@ai-sdk/amazon-bedrock": ["@ai-sdk/amazon-bedrock@3.0.73", "", { "dependencies": { "@ai-sdk/anthropic": "2.0.57", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-EAAGJ/dfbAZaqIhK3w52hq6cftSLZwXdC6uHKh8Cls1T0N4MxS6ykDf54UyFO3bZWkQxR+Mdw1B3qireGOxtJQ=="], "@ai-sdk/anthropic": ["@ai-sdk/anthropic@2.0.0", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-uyyaO4KhxoIKZztREqLPh+6/K3ZJx/rp72JKoUEL9/kC+vfQTThUfPnY/bUryUpcnawx8IY/tSoYNOi/8PCv7w=="], "@ai-sdk/azure": ["@ai-sdk/azure@2.0.91", "", { "dependencies": { "@ai-sdk/openai": "2.0.89", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-9tznVSs6LGQNKKxb8pKd7CkBV9yk+a/ENpFicHCj2CmBUKefxzwJ9JbUqrlK3VF6dGZw3LXq0dWxt7/Yekaj1w=="], - "@ai-sdk/cerebras": ["@ai-sdk/cerebras@1.0.36", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.32", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-zoJYL33+ieyd86FSP0Whm86D79d1lKPR7wUzh1SZ1oTxwYmsGyvIrmMf2Ll0JA9Ds2Es6qik4VaFCrjwGYRTIQ=="], + "@ai-sdk/cerebras": ["@ai-sdk/cerebras@1.0.34", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.30", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-XOK0dJsAGoPYi/lfR4KFBi8xhvJ46oCpAxUD6FmJAuJ4eh0qlj5zDt+myvzM8gvN7S6K7zHD+mdWlOPKGQT8Vg=="], "@ai-sdk/cohere": ["@ai-sdk/cohere@2.0.22", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-yJ9kP5cEDJwo8qpITq5TQFD8YNfNtW+HbyvWwrKMbFzmiMvIZuk95HIaFXE7PCTuZsqMA05yYu+qX/vQ3rNKjA=="], - "@ai-sdk/deepinfra": ["@ai-sdk/deepinfra@1.0.33", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.32", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-hn2y8Q+2iZgGNVJyzPsH8EECECryFMVmxBJrBvBWoi8xcJPRyt0fZP5dOSLyGg3q0oxmPS9M0Eq0NNlKot/bYQ=="], + "@ai-sdk/deepinfra": ["@ai-sdk/deepinfra@1.0.31", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.30", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-87qFcYNvDF/89hB//MQjYTb3tlsAfmgeZrZ34RESeBTZpSgs0EzYOMqPMwFTHUNp4wteoifikDJbaS/9Da8cfw=="], - "@ai-sdk/gateway": ["@ai-sdk/gateway@2.0.30", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@vercel/oidc": "3.1.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-5Nrkj8B4MzkkOfjjA+Cs5pamkbkK4lI11bx80QV7TFcen/hWA8wEC+UVzwuM5H2zpekoNMjvl6GonHnR62XIZw=="], + "@ai-sdk/gateway": ["@ai-sdk/gateway@2.0.25", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@vercel/oidc": "3.0.5" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Rq+FX55ne7lMiqai7NcvvDZj4HLsr+hg77WayqmySqc6zhw3tIOLxd4Ty6OpwNj0C0bVMi3iCl2zvJIEirh9XA=="], "@ai-sdk/google": ["@ai-sdk/google@2.0.52", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-2XUnGi3f7TV4ujoAhA+Fg3idUoG/+Y2xjCRg70a1/m0DH1KSQqYaCboJ1C19y6ZHGdf5KNT20eJdswP6TvrY2g=="], - "@ai-sdk/google-vertex": ["@ai-sdk/google-vertex@3.0.98", "", { "dependencies": { "@ai-sdk/anthropic": "2.0.58", "@ai-sdk/google": "2.0.52", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "google-auth-library": "^10.5.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-uuv0RHkdJ5vTzeH1+iuBlv7GAjRcOPd2jiqtGLz6IKOUDH+PRQoE3ExrvOysVnKuhhTBMqvawkktDhMDQE6sVQ=="], + "@ai-sdk/google-vertex": ["@ai-sdk/google-vertex@3.0.97", "", { "dependencies": { "@ai-sdk/anthropic": "2.0.57", "@ai-sdk/google": "2.0.52", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "google-auth-library": "^10.5.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-s4tI7Z15i6FlbtCvS4SBRal8wRfkOXJzKxlS6cU4mJW/QfUfoVy4b22836NVNJwDvkG/HkDSfzwm/X8mn46MhA=="], "@ai-sdk/groq": ["@ai-sdk/groq@2.0.34", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-wfCYkVgmVjxNA32T57KbLabVnv9aFUflJ4urJ7eWgTwbnmGQHElCTu+rJ3ydxkXSqxOkXPwMOttDm7XNrvPjmg=="], @@ -591,11 +613,11 @@ "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.20", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-iXHVe0apM2zUEzauqJwqmpC37A5rihrStAih5Ks+JE32iTe4LZ58y17UGBjpQQTCRw9YxMeo2UFLxLpBluyvLQ=="], - "@ai-sdk/togetherai": ["@ai-sdk/togetherai@1.0.34", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.32", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-jjJmJms6kdEc4nC3MDGFJfhV8F1ifY4nolV2dbnT7BM4ab+Wkskc0GwCsJ7G7WdRMk7xDbFh4he3DPL8KJ/cyA=="], + "@ai-sdk/togetherai": ["@ai-sdk/togetherai@1.0.31", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.30", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-RlYubjStoZQxna4Ng91Vvo8YskvL7lW9zj68IwZfCnaDBSAp1u6Nhc5BR4ZtKnY6PA3XEtu4bATIQl7yiiQ+Lw=="], - "@ai-sdk/vercel": ["@ai-sdk/vercel@1.0.33", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.32", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Qwjm+HdwKasu7L9bDUryBMGKDMscIEzMUkjw/33uGdJpktzyNW13YaNIObOZ2HkskqDMIQJSd4Ao2BBT8fEYLw=="], + "@ai-sdk/vercel": ["@ai-sdk/vercel@1.0.31", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.30", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ggvwAMt/KsbqcdR6ILQrjwrRONLV/8aG6rOLbjcOGvV0Ai+WdZRRKQj5nOeQ06PvwVQtKdkp7S4IinpXIhCiHg=="], - "@ai-sdk/xai": ["@ai-sdk/xai@2.0.56", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.32", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-FGlqwWc3tAYqDHE8r8hQGQLcMiPUwgz90oU2QygUH930OWtCLapFkSu114DgVaIN/qoM1DUX+inv0Ee74Fgp5g=="], + "@ai-sdk/xai": ["@ai-sdk/xai@2.0.51", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.30", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-AI3le03qiegkZvn9hpnpDwez49lOvQLj4QUBT8H41SMbrdTYOxn3ktTwrsSu90cNDdzKGMvoH0u2GHju1EdnCg=="], "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], @@ -613,11 +635,11 @@ "@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.1", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.2.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.1", "remark-smartypants": "^3.0.2", "shiki": "^3.0.0", "smol-toml": "^1.3.1", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-c5F5gGrkczUaTVgmMW9g1YMJGzOtRvjjhw6IfGuxarM6ct09MpwysP10US729dy07gg8y+ofVifezvP3BNsWZg=="], - "@astrojs/mdx": ["@astrojs/mdx@4.3.13", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.10", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.15.0", "es-module-lexer": "^1.7.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "piccolore": "^0.1.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-IHDHVKz0JfKBy3//52JSiyWv089b7GVSChIXLrlUOoTLWowG3wr2/8hkaEgEyd/vysvNQvGk+QhysXpJW5ve6Q=="], + "@astrojs/mdx": ["@astrojs/mdx@4.3.12", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.9", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.15.0", "es-module-lexer": "^1.7.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "piccolore": "^0.1.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-pL3CVPtuQrPnDhWjy7zqbOibNyPaxP4VpQS8T8spwKqKzauJ4yoKyNkVTD8jrP7EAJHmBhZ7PTmUGZqOpKKp8g=="], "@astrojs/prism": ["@astrojs/prism@3.2.0", "", { "dependencies": { "prismjs": "^1.29.0" } }, "sha512-GilTHKGCW6HMq7y3BUv9Ac7GMe/MO9gi9GW62GzKtth0SwukCu/qp2wLiGpEujhY+VVhaG9v7kv/5vFzvf4NYw=="], - "@astrojs/sitemap": ["@astrojs/sitemap@3.7.0", "", { "dependencies": { "sitemap": "^8.0.2", "stream-replace-string": "^2.0.0", "zod": "^3.25.76" } }, "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA=="], + "@astrojs/sitemap": ["@astrojs/sitemap@3.6.0", "", { "dependencies": { "sitemap": "^8.0.0", "stream-replace-string": "^2.0.0", "zod": "^3.25.76" } }, "sha512-4aHkvcOZBWJigRmMIAJwRQXBS+ayoP5z40OklTXYXhUDhwusz+DyDl+nSshY6y9DvkVEavwNcFO8FD81iGhXjg=="], "@astrojs/solid-js": ["@astrojs/solid-js@5.1.0", "", { "dependencies": { "vite": "^6.3.5", "vite-plugin-solid": "^2.11.6" }, "peerDependencies": { "solid-devtools": "^0.30.1", "solid-js": "^1.8.5" }, "optionalPeers": ["solid-devtools"] }, "sha512-VmPHOU9k7m6HHCT2Y1mNzifilUnttlowBM36frGcfj5wERJE9Ci0QtWJbzdf6AlcoIirb7xVw+ByupU011Di9w=="], @@ -697,7 +719,7 @@ "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.930.0", "", { "dependencies": { "@aws-sdk/types": "3.930.0", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-endpoints": "^3.2.5", "tslib": "^2.6.2" } }, "sha512-M2oEKBzzNAYr136RRc6uqw3aWlwCxqTP1Lawps9E1d2abRPvl1p1ztQmmXp1Ak4rv8eByIZ+yQyKQ3zPdRG5dw=="], - "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.965.4", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-H1onv5SkgPBK2P6JR2MjGgbOnttoNzSPIRoeZTNPZYyaplwGg50zS3amXvXqF0/qfXpWEC9rLWU564QTB9bSog=="], + "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.893.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg=="], "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.930.0", "", { "dependencies": { "@aws-sdk/types": "3.930.0", "@smithy/types": "^4.9.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-q6lCRm6UAe+e1LguM5E4EqM9brQlDem4XDcQ87NzEvlTW6GzmNCO0w1jS0XgCFXQHjDxjdlNFX+5sRbHijwklg=="], @@ -705,7 +727,7 @@ "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA=="], - "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.3", "", {}, "sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw=="], + "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.1", "", {}, "sha512-sIyFcoPZkTtNu9xFeEoynMef3bPJIAbOfUh+ueYcfhVl6xm2VRtMcMclSxmZCMnHHd4hlYKJeq/aggmBEWynww=="], "@azure/abort-controller": ["@azure/abort-controller@2.1.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA=="], @@ -731,37 +753,37 @@ "@azure/logger": ["@azure/logger@1.3.0", "", { "dependencies": { "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA=="], - "@azure/storage-blob": ["@azure/storage-blob@12.30.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-client": "^1.9.3", "@azure/core-http-compat": "^2.2.0", "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.6.2", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/core-xml": "^1.4.5", "@azure/logger": "^1.1.4", "@azure/storage-common": "^12.2.0", "events": "^3.0.0", "tslib": "^2.8.1" } }, "sha512-peDCR8blSqhsAKDbpSP/o55S4sheNwSrblvCaHUZ5xUI73XA7ieUGGwrONgD/Fng0EoDe1VOa3fAQ7+WGB3Ocg=="], + "@azure/storage-blob": ["@azure/storage-blob@12.29.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-client": "^1.9.3", "@azure/core-http-compat": "^2.2.0", "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.6.2", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/core-xml": "^1.4.5", "@azure/logger": "^1.1.4", "@azure/storage-common": "^12.1.1", "events": "^3.0.0", "tslib": "^2.8.1" } }, "sha512-7ktyY0rfTM0vo7HvtK6E3UvYnI9qfd6Oz6z/+92VhGRveWng3kJwMKeUpqmW/NmwcDNbxHpSlldG+vsUnRFnBg=="], - "@azure/storage-common": ["@azure/storage-common@12.2.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-http-compat": "^2.2.0", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/logger": "^1.1.4", "events": "^3.3.0", "tslib": "^2.8.1" } }, "sha512-YZLxiJ3vBAAnFbG3TFuAMUlxZRexjQX5JDQxOkFGb6e2TpoxH3xyHI6idsMe/QrWtj41U/KoqBxlayzhS+LlwA=="], + "@azure/storage-common": ["@azure/storage-common@12.1.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-http-compat": "^2.2.0", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/logger": "^1.1.4", "events": "^3.3.0", "tslib": "^2.8.1" } }, "sha512-eIOH1pqFwI6UmVNnDQvmFeSg0XppuzDLFeUNO/Xht7ODAzRLgGDh7h550pSxoA+lPDxBl1+D2m/KG3jWzCUjTg=="], - "@babel/code-frame": ["@babel/code-frame@7.28.6", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q=="], + "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], - "@babel/compat-data": ["@babel/compat-data@7.28.6", "", {}, "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg=="], + "@babel/compat-data": ["@babel/compat-data@7.28.5", "", {}, "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA=="], "@babel/core": ["@babel/core@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.4", "@babel/types": "^7.28.4", "@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-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA=="], - "@babel/generator": ["@babel/generator@7.28.6", "", { "dependencies": { "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw=="], + "@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="], "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="], - "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "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-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="], - "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow=="], + "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="], "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="], - "@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="], + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="], - "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "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-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="], "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="], - "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.28.6", "", {}, "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug=="], + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="], - "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.28.6", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg=="], + "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="], "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="], @@ -771,35 +793,35 @@ "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], - "@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="], + "@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="], - "@babel/parser": ["@babel/parser@7.28.6", "", { "dependencies": { "@babel/types": "^7.28.6" }, "bin": "./bin/babel-parser.js" }, "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ=="], + "@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": "./bin/babel-parser.js" }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], - "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w=="], + "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w=="], - "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A=="], + "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ=="], - "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.28.6", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA=="], + "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="], "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="], "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="], - "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw=="], + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="], "@babel/preset-typescript": ["@babel/preset-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ=="], - "@babel/runtime": ["@babel/runtime@7.28.6", "", {}, "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA=="], + "@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], - "@babel/template": ["@babel/template@7.28.6", "", { "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/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], - "@babel/traverse": ["@babel/traverse@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.6", "@babel/template": "^7.28.6", "@babel/types": "^7.28.6", "debug": "^4.3.1" } }, "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg=="], + "@babel/traverse": ["@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.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], - "@babel/types": ["@babel/types@7.28.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg=="], + "@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], - "@bufbuild/protobuf": ["@bufbuild/protobuf@2.11.0", "", {}, "sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ=="], + "@bufbuild/protobuf": ["@bufbuild/protobuf@2.10.1", "", {}, "sha512-ckS3+vyJb5qGpEYv/s1OebUHDi/xSNtfgw1wqKZo7MR9F2z+qXr0q5XagafAG/9O0QPVIUfST0smluYSTpYFkg=="], - "@bufbuild/protoplugin": ["@bufbuild/protoplugin@2.11.0", "", { "dependencies": { "@bufbuild/protobuf": "2.11.0", "@typescript/vfs": "^1.6.2", "typescript": "5.4.5" } }, "sha512-lyZVNFUHArIOt4W0+dwYBe5GBwbKzbOy8ObaloEqsw9Mmiwv2O48TwddDoHN4itylC+BaEGqFdI1W8WQt2vWJQ=="], + "@bufbuild/protoplugin": ["@bufbuild/protoplugin@2.10.1", "", { "dependencies": { "@bufbuild/protobuf": "2.10.1", "@typescript/vfs": "^1.6.2", "typescript": "5.4.5" } }, "sha512-imB8dKEjrOnG5+XqVS+CeYn924WGLU/g3wogKhk11XtX9y9NJ7432OS6h24asuBbLrQcPdEZ6QkfM7KeOCeeyQ=="], "@capsizecss/unpack": ["@capsizecss/unpack@2.4.0", "", { "dependencies": { "blob-to-buffer": "^1.2.8", "cross-fetch": "^3.0.4", "fontkit": "^2.0.2" } }, "sha512-GrSU71meACqcmIUxPYOJvGKF0yryjN/L1aCuE9DViCTJI7bfkjgYDPD1zbNDcINJwSSP6UaBZY9GAbYDO7re0Q=="], @@ -837,9 +859,9 @@ "@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="], - "@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="], + "@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="], - "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], + "@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="], "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], @@ -851,73 +873,73 @@ "@esbuild-kit/esm-loader": ["@esbuild-kit/esm-loader@2.6.5", "", { "dependencies": { "@esbuild-kit/core-utils": "^3.3.2", "get-tsconfig": "^4.7.0" } }, "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.25.5", "", { "os": "android", "cpu": "arm" }, "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.5", "", { "os": "android", "cpu": "arm64" }, "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.25.5", "", { "os": "android", "cpu": "x64" }, "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.5", "", { "os": "linux", "cpu": "arm" }, "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.5", "", { "os": "linux", "cpu": "x64" }, "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw=="], - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.5", "", { "os": "none", "cpu": "arm64" }, "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.5", "", { "os": "none", "cpu": "x64" }, "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ=="], - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.5", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg=="], "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g=="], - "@expressive-code/core": ["@expressive-code/core@0.41.6", "", { "dependencies": { "@ctrl/tinycolor": "^4.0.4", "hast-util-select": "^6.0.2", "hast-util-to-html": "^9.0.1", "hast-util-to-text": "^4.0.1", "hastscript": "^9.0.0", "postcss": "^8.4.38", "postcss-nested": "^6.0.1", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1" } }, "sha512-FvJQP+hG0jWi/FLBSmvHInDqWR7jNANp9PUDjdMqSshHb0y7sxx3vHuoOr6SgXjWw+MGLqorZyPQ0aAlHEok6g=="], + "@expressive-code/core": ["@expressive-code/core@0.41.3", "", { "dependencies": { "@ctrl/tinycolor": "^4.0.4", "hast-util-select": "^6.0.2", "hast-util-to-html": "^9.0.1", "hast-util-to-text": "^4.0.1", "hastscript": "^9.0.0", "postcss": "^8.4.38", "postcss-nested": "^6.0.1", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1" } }, "sha512-9qzohqU7O0+JwMEEgQhnBPOw5DtsQRBXhW++5fvEywsuX44vCGGof1SL5OvPElvNgaWZ4pFZAFSlkNOkGyLwSQ=="], - "@expressive-code/plugin-frames": ["@expressive-code/plugin-frames@0.41.6", "", { "dependencies": { "@expressive-code/core": "^0.41.6" } }, "sha512-d+hkSYXIQot6fmYnOmWAM+7TNWRv/dhfjMsNq+mIZz8Tb4mPHOcgcfZeEM5dV9TDL0ioQNvtcqQNuzA1sRPjxg=="], + "@expressive-code/plugin-frames": ["@expressive-code/plugin-frames@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3" } }, "sha512-rFQtmf/3N2CK3Cq/uERweMTYZnBu+CwxBdHuOftEmfA9iBE7gTVvwpbh82P9ZxkPLvc40UMhYt7uNuAZexycRQ=="], - "@expressive-code/plugin-shiki": ["@expressive-code/plugin-shiki@0.41.6", "", { "dependencies": { "@expressive-code/core": "^0.41.6", "shiki": "^3.2.2" } }, "sha512-Y6zmKBmsIUtWTzdefqlzm/h9Zz0Rc4gNdt2GTIH7fhHH2I9+lDYCa27BDwuBhjqcos6uK81Aca9dLUC4wzN+ng=="], + "@expressive-code/plugin-shiki": ["@expressive-code/plugin-shiki@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3", "shiki": "^3.2.2" } }, "sha512-RlTARoopzhFJIOVHLGvuXJ8DCEme/hjV+ZnRJBIxzxsKVpGPW4Oshqg9xGhWTYdHstTsxO663s0cdBLzZj9TQA=="], - "@expressive-code/plugin-text-markers": ["@expressive-code/plugin-text-markers@0.41.6", "", { "dependencies": { "@expressive-code/core": "^0.41.6" } }, "sha512-PBFa1wGyYzRExMDzBmAWC6/kdfG1oLn4pLpBeTfIRrALPjcGA/59HP3e7q9J0Smk4pC7U+lWkA2LHR8FYV8U7Q=="], + "@expressive-code/plugin-text-markers": ["@expressive-code/plugin-text-markers@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3" } }, "sha512-SN8tkIzDpA0HLAscEYD2IVrfLiid6qEdE9QLlGVSxO1KEw7qYvjpbNBQjUjMr5/jvTJ7ys6zysU2vLPHE0sb2g=="], "@fastify/busboy": ["@fastify/busboy@2.1.1", "", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="], - "@floating-ui/core": ["@floating-ui/core@1.7.4", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg=="], + "@floating-ui/core": ["@floating-ui/core@1.7.3", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="], - "@floating-ui/dom": ["@floating-ui/dom@1.7.5", "", { "dependencies": { "@floating-ui/core": "^1.7.4", "@floating-ui/utils": "^0.2.10" } }, "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg=="], + "@floating-ui/dom": ["@floating-ui/dom@1.7.4", "", { "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA=="], - "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.7", "", { "dependencies": { "@floating-ui/dom": "^1.7.5" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg=="], + "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.6", "", { "dependencies": { "@floating-ui/dom": "^1.7.4" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw=="], "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="], @@ -925,21 +947,19 @@ "@fontsource/inter": ["@fontsource/inter@5.2.8", "", {}, "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg=="], - "@gitlab/gitlab-ai-provider": ["@gitlab/gitlab-ai-provider@3.3.1", "", { "dependencies": { "@anthropic-ai/sdk": "^0.71.0", "@anycable/core": "^0.9.2", "graphql-request": "^6.1.0", "isomorphic-ws": "^5.0.0", "openai": "^6.16.0", "socket.io-client": "^4.8.1", "vscode-jsonrpc": "^8.2.1", "zod": "^3.25.76" }, "peerDependencies": { "@ai-sdk/provider": ">=2.0.0", "@ai-sdk/provider-utils": ">=3.0.0" } }, "sha512-J4/LfVcxOKbR2gfoBWRKp1BpWppprC2Cz/Ff5E0B/0lS341CDtZwzkgWvHfkM/XU6q83JRs059dS0cR8VOODOQ=="], + "@gitlab/gitlab-ai-provider": ["@gitlab/gitlab-ai-provider@3.1.2", "", { "dependencies": { "@anthropic-ai/sdk": "^0.71.0", "@anycable/core": "^0.9.2", "graphql-request": "^6.1.0", "isomorphic-ws": "^5.0.0", "socket.io-client": "^4.8.1", "vscode-jsonrpc": "^8.2.1", "zod": "^3.25.76" }, "peerDependencies": { "@ai-sdk/provider": ">=2.0.0", "@ai-sdk/provider-utils": ">=3.0.0" } }, "sha512-p0NZhZJSavWDX9r/Px/mOK2YIC803GZa8iRzcg3f1C6S0qfea/HBTe4/NWvT2+2kWIwhCePGuI4FN2UFiUWXUg=="], "@graphql-typed-document-node/core": ["@graphql-typed-document-node/core@3.2.0", "", { "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ=="], "@happy-dom/global-registrator": ["@happy-dom/global-registrator@20.0.11", "", { "dependencies": { "@types/node": "^20.0.0", "happy-dom": "^20.0.11" } }, "sha512-GqNqiShBT/lzkHTMC/slKBrvN0DsD4Di8ssBk4aDaVgEn+2WMzE6DXxq701ndSXj7/0cJ8mNT71pM7Bnrr6JRw=="], - "@hey-api/codegen-core": ["@hey-api/codegen-core@0.5.5", "", { "dependencies": { "@hey-api/types": "0.1.2", "ansi-colors": "4.1.3", "c12": "3.3.3", "color-support": "1.1.3" }, "peerDependencies": { "typescript": ">=5.5.3" } }, "sha512-f2ZHucnA2wBGAY8ipB4wn/mrEYW+WUxU2huJmUvfDO6AE2vfILSHeF3wCO39Pz4wUYPoAWZByaauftLrOfC12Q=="], + "@hey-api/codegen-core": ["@hey-api/codegen-core@0.5.2", "", { "dependencies": { "ansi-colors": "4.1.3", "color-support": "1.1.3" }, "peerDependencies": { "typescript": ">=5.5.3" } }, "sha512-88cqrrB2cLXN8nMOHidQTcVOnZsJ5kebEbBefjMCifaUCwTA30ouSSWvTZqrOX4O104zjJyu7M8Gcv/NNYQuaA=="], "@hey-api/json-schema-ref-parser": ["@hey-api/json-schema-ref-parser@1.2.2", "", { "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", "js-yaml": "^4.1.1", "lodash": "^4.17.21" } }, "sha512-oS+5yAdwnK20lSeFO1d53Ku+yaGCsY8PcrmSq2GtSs3bsBfRnHAbpPKSVzQcaxAOrzj5NB+f34WhZglVrNayBA=="], - "@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.90.10", "", { "dependencies": { "@hey-api/codegen-core": "^0.5.5", "@hey-api/json-schema-ref-parser": "1.2.2", "@hey-api/types": "0.1.2", "ansi-colors": "4.1.3", "color-support": "1.1.3", "commander": "14.0.2", "open": "11.0.0", "semver": "7.7.3" }, "peerDependencies": { "typescript": ">=5.5.3" }, "bin": { "openapi-ts": "bin/run.js" } }, "sha512-o0wlFxuLt1bcyIV/ZH8DQ1wrgODTnUYj/VfCHOOYgXUQlLp9Dm2PjihOz+WYrZLowhqUhSKeJRArOGzvLuOTsg=="], - - "@hey-api/types": ["@hey-api/types@0.1.2", "", {}, "sha512-uNNtiVAWL7XNrV/tFXx7GLY9lwaaDazx1173cGW3+UEaw4RUPsHEmiB4DSpcjNxMIcrctfz2sGKLnVx5PBG2RA=="], + "@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.90.4", "", { "dependencies": { "@hey-api/codegen-core": "^0.5.2", "@hey-api/json-schema-ref-parser": "1.2.2", "ansi-colors": "4.1.3", "c12": "3.3.3", "color-support": "1.1.3", "commander": "14.0.2", "open": "11.0.0", "semver": "7.7.3" }, "peerDependencies": { "typescript": ">=5.5.3" }, "bin": { "openapi-ts": "bin/run.js" } }, "sha512-9l++kjcb0ui4JqPlueZ6OZ9zKn6eK/8//Z2jHcIXb5MRwDRgubOOSpTU5llEv3uvWfT10VzcMp99dySWq0AASw=="], - "@hono/node-server": ["@hono/node-server@1.19.9", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw=="], + "@hono/node-server": ["@hono/node-server@1.19.7", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw=="], "@hono/standard-validator": ["@hono/standard-validator@0.1.5", "", { "peerDependencies": { "@standard-schema/spec": "1.0.0", "hono": ">=3.9.0" } }, "sha512-EIyZPPwkyLn6XKwFj5NBEWHXhXbgmnVh2ceIFo5GO7gKI9WmzTjPDKnppQB0KrqKeAkq3kpoW4SIbu5X1dgx3w=="], @@ -947,7 +967,7 @@ "@ibm/plex": ["@ibm/plex@6.4.1", "", { "dependencies": { "@ibm/telemetry-js": "^1.5.1" } }, "sha512-fnsipQywHt3zWvsnlyYKMikcVI7E2fEwpiPnIHFqlbByXVfQfANAAeJk1IV4mNnxhppUIDlhU0TzwYwL++Rn2g=="], - "@ibm/telemetry-js": ["@ibm/telemetry-js@1.11.0", "", { "bin": { "ibmtelemetry": "dist/collect.js" } }, "sha512-RO/9j+URJnSfseWg9ZkEX9p+a3Ousd33DBU7rOafoZB08RqdzxFVYJ2/iM50dkBuD0o7WX7GYt1sLbNgCoE+pA=="], + "@ibm/telemetry-js": ["@ibm/telemetry-js@1.10.2", "", { "bin": { "ibmtelemetry": "dist/collect.js" } }, "sha512-F8+/NNUwtm8BuFz18O9KPvIFTFDo8GUSoyhPxPjEpk7nEyEzWGfhIiEPhL00B2NdHRLDSljh3AiCfSnL/tutiQ=="], "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], @@ -987,10 +1007,12 @@ "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.33.5", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="], - "@internationalized/date": ["@internationalized/date@3.10.1", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-oJrXtQiAXLvT9clCf1K4kxp3eKsQhIaZqxEyowkBcsvZDdZkbWrVmnGknxs5flTD0VGsxrxKgBCZty1EzoiMzA=="], + "@internationalized/date": ["@internationalized/date@3.10.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw=="], "@internationalized/number": ["@internationalized/number@3.6.5", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g=="], + "@ioredis/commands": ["@ioredis/commands@1.4.0", "", {}, "sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ=="], + "@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="], "@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="], @@ -1137,7 +1159,7 @@ "@motionone/utils": ["@motionone/utils@10.18.0", "", { "dependencies": { "@motionone/types": "^10.17.1", "hey-listen": "^1.0.8", "tslib": "^2.3.1" } }, "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" } }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="], "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], @@ -1221,27 +1243,27 @@ "@opencode-ai/web": ["@opencode-ai/web@workspace:packages/web"], - "@openrouter/ai-sdk-provider": ["@openrouter/ai-sdk-provider@1.5.4", "", { "dependencies": { "@openrouter/sdk": "^0.1.27" }, "peerDependencies": { "ai": "^5.0.0", "zod": "^3.24.1 || ^v4" } }, "sha512-xrSQPUIH8n9zuyYZR0XK7Ba0h2KsjJcMkxnwaYfmv13pKs3sDkjPzVPPhlhzqBGddHb5cFEwJ9VFuFeDcxCDSw=="], + "@openrouter/ai-sdk-provider": ["@openrouter/ai-sdk-provider@1.5.2", "", { "dependencies": { "@openrouter/sdk": "^0.1.27" }, "peerDependencies": { "@toon-format/toon": "^2.0.0", "ai": "^5.0.0", "zod": "^3.24.1 || ^v4" }, "optionalPeers": ["@toon-format/toon"] }, "sha512-3Th0vmJ9pjnwcPc2H1f59Mb0LFvwaREZAScfOQIpUxAHjZ7ZawVKDP27qgsteZPmMYqccNMy4r4Y3kgUnNcKAg=="], "@openrouter/sdk": ["@openrouter/sdk@0.1.27", "", { "dependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-RH//L10bSmc81q25zAZudiI4kNkLgxF2E+WU42vghp3N6TEvZ6F0jK7uT3tOxkEn91gzmMw9YVmDENy7SJsajQ=="], "@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], - "@opentui/core": ["@opentui/core@0.1.75", "", { "dependencies": { "bun-ffi-structs": "0.1.2", "diff": "8.0.2", "jimp": "1.6.0", "marked": "17.0.1", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.75", "@opentui/core-darwin-x64": "0.1.75", "@opentui/core-linux-arm64": "0.1.75", "@opentui/core-linux-x64": "0.1.75", "@opentui/core-win32-arm64": "0.1.75", "@opentui/core-win32-x64": "0.1.75", "bun-webgpu": "0.1.4", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-8ARRZxSG+BXkJmEVtM2DQ4se7DAF1ZCKD07d+AklgTr2mxCzmdxxPbOwRzboSQ6FM7qGuTVPVbV4O2W9DpUmoA=="], + "@opentui/core": ["@opentui/core@0.1.74", "", { "dependencies": { "bun-ffi-structs": "0.1.2", "diff": "8.0.2", "jimp": "1.6.0", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.74", "@opentui/core-darwin-x64": "0.1.74", "@opentui/core-linux-arm64": "0.1.74", "@opentui/core-linux-x64": "0.1.74", "@opentui/core-win32-arm64": "0.1.74", "@opentui/core-win32-x64": "0.1.74", "bun-webgpu": "0.1.4", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-g4W16ymv12JdgZ+9B4t7mpIICvzWy2+eHERfmDf80ALduOQCUedKQdULcBFhVCYUXIkDRtIy6CID5thMAah3FA=="], - "@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.75", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gGaGZjkFpqcXJk6321JzhRl66pM2VxBlI470L8W4DQUW4S6iDT1R9L7awSzGB4Cn9toUl7DTV8BemaXZYXV4SA=="], + "@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.74", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rfmlDLtm/u17CnuhJgCxPeYMvOST+A2MOdVOk46IurtHO849bdYqK6iudKNlFRs1FOrymgSKF9GlWBHAOKeRjg=="], - "@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.75", "", { "os": "darwin", "cpu": "x64" }, "sha512-tPlvqQI0whZ76amHydpJs5kN+QeWAIcFbI8RAtlAo9baj2EbxTDC+JGwgb9Fnt0/YQx831humbtaNDhV2Jt1bw=="], + "@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.74", "", { "os": "darwin", "cpu": "x64" }, "sha512-WAD8orsDV0ZdW/5GwjOOB4FY96772xbkz+rcV7WRzEFUVaqoBaC04IuqYzS9d5s+cjkbT5Cpj47hrVYkkVQKng=="], - "@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.75", "", { "os": "linux", "cpu": "arm64" }, "sha512-nVxIQ4Hqf84uBergDpWiVzU6pzpjy6tqBHRQpySxZ2flkJ/U6/aMEizVrQ1jcgIdxZtvqWDETZhzxhG0yDx+cw=="], + "@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.74", "", { "os": "linux", "cpu": "arm64" }, "sha512-lgmHzrzLy4e+rgBS+lhtsMLLgIMLbtLNMm6EzVPyYVDlLDGjM7+ulXMem7AtpaRrWrUUl4REiG9BoQUsCFDwYA=="], - "@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.75", "", { "os": "linux", "cpu": "x64" }, "sha512-1CnApef4kxA+ORyLfbuCLgZfEjp4wr3HjFnt7FAfOb73kIZH82cb7JYixeqRyy9eOcKfKqxLmBYy3o8IDkc4Rg=="], + "@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.74", "", { "os": "linux", "cpu": "x64" }, "sha512-8Mn2WbdBQ29xCThuPZezjDhd1N3+fXwKkGvCBOdTI0le6h2A/vCNbfUVjwfr/EGZSRXxCG+Yapol34BAULGpOA=="], - "@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.75", "", { "os": "win32", "cpu": "arm64" }, "sha512-j0UB95nmkYGNzmOrs6GqaddO1S90R0YC6IhbKnbKBdjchFPNVLz9JpexAs6MBDXPZwdKAywMxtwG2h3aTJtxng=="], + "@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.74", "", { "os": "win32", "cpu": "arm64" }, "sha512-dvYUXz03avnI6ZluyLp00HPmR0UT/IE/6QS97XBsgJlUTtpnbKkBtB5jD1NHwWkElaRj1Qv2QP36ngFoJqbl9g=="], - "@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.75", "", { "os": "win32", "cpu": "x64" }, "sha512-ESpVZVGewe3JkB2TwrG3VRbkxT909iPdtvgNT7xTCIYH2VB4jqZomJfvERPTE0tvqAZJm19mHECzJFI8asSJgQ=="], + "@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.74", "", { "os": "win32", "cpu": "x64" }, "sha512-3wfWXaAKOIlDQz6ZZIESf2M+YGZ7uFHijjTEM8w/STRlLw8Y6+QyGYi1myHSM4d6RSO+/s2EMDxvjDf899W9vQ=="], - "@opentui/solid": ["@opentui/solid@0.1.75", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.1.75", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.9", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.9" } }, "sha512-WjKsZIfrm29znfRlcD9w3uUn/+uvoy2MmeoDwTvg1YOa0OjCTCmjZ43L9imp0m9S4HmVU8ma6o2bR4COzcyDdg=="], + "@opentui/solid": ["@opentui/solid@0.1.74", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.1.74", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.9", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.9" } }, "sha512-Vz82cI8T9YeJjGsVg4ULp6ral4N+xyt1j9A6Tbu3aaQgEKiB74LW03EXREehfjPr1irOFxtKfWPbx5NKH0Upag=="], "@oslojs/asn1": ["@oslojs/asn1@1.0.0", "", { "dependencies": { "@oslojs/binary": "1.0.0" } }, "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA=="], @@ -1365,11 +1387,13 @@ "@playwright/test": ["@playwright/test@1.57.0", "", { "dependencies": { "playwright": "1.57.0" }, "bin": { "playwright": "cli.js" } }, "sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA=="], - "@poppinss/colors": ["@poppinss/colors@4.1.6", "", { "dependencies": { "kleur": "^4.1.5" } }, "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg=="], + "@poppinss/colors": ["@poppinss/colors@4.1.5", "", { "dependencies": { "kleur": "^4.1.5" } }, "sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw=="], "@poppinss/dumper": ["@poppinss/dumper@0.6.5", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@sindresorhus/is": "^7.0.2", "supports-color": "^10.0.0" } }, "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw=="], - "@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="], + "@poppinss/exception": ["@poppinss/exception@1.2.2", "", {}, "sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg=="], + + "@prokube/app-prefixable": ["@prokube/app-prefixable@workspace:prokube/app-prefixable"], "@protobuf-ts/plugin": ["@protobuf-ts/plugin@2.11.1", "", { "dependencies": { "@bufbuild/protobuf": "^2.4.0", "@bufbuild/protoplugin": "^2.4.0", "@protobuf-ts/protoc": "^2.11.1", "@protobuf-ts/runtime": "^2.11.1", "@protobuf-ts/runtime-rpc": "^2.11.1", "typescript": "^3.9" }, "bin": { "protoc-gen-ts": "bin/protoc-gen-ts", "protoc-gen-dump": "bin/protoc-gen-dump" } }, "sha512-HyuprDcw0bEEJqkOWe1rnXUP0gwYLij8YhPuZyZk6cJbIgc/Q0IFgoHQxOXNIXAcXM4Sbehh6kjVnCzasElw1A=="], @@ -1447,55 +1471,49 @@ "@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.57.0", "", { "os": "android", "cpu": "arm" }, "sha512-tPgXB6cDTndIe1ah7u6amCI1T0SsnlOuKgg10Xh3uizJk4e5M1JGaUMk7J4ciuAUcFpbOiNhm2XIjP9ON0dUqA=="], - - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.57.0", "", { "os": "android", "cpu": "arm64" }, "sha512-sa4LyseLLXr1onr97StkU1Nb7fWcg6niokTwEVNOO7awaKaoRObQ54+V/hrF/BP1noMEaaAW6Fg2d/CfLiq3Mg=="], - - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.57.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-/NNIj9A7yLjKdmkx5dC2XQ9DmjIECpGpwHoGmA5E1AhU0fuICSqSWScPhN1yLCkEdkCwJIDu2xIeLPs60MNIVg=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.53.3", "", { "os": "android", "cpu": "arm" }, "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.57.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-xoh8abqgPrPYPr7pTYipqnUi1V3em56JzE/HgDgitTqZBZ3yKCWI+7KUkceM6tNweyUKYru1UMi7FC060RyKwA=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.53.3", "", { "os": "android", "cpu": "arm64" }, "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.57.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-PCkMh7fNahWSbA0OTUQ2OpYHpjZZr0hPr8lId8twD7a7SeWrvT3xJVyza+dQwXSSq4yEQTMoXgNOfMCsn8584g=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.53.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.57.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1j3stGx+qbhXql4OCDZhnK7b01s6rBKNybfsX+TNrEe9JNq4DLi1yGiR1xW+nL+FNVvI4D02PUnl6gJ/2y6WJA=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.53.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.57.0", "", { "os": "linux", "cpu": "arm" }, "sha512-eyrr5W08Ms9uM0mLcKfM/Uzx7hjhz2bcjv8P2uynfj0yU8GGPdz8iYrBPhiLOZqahoAMB8ZiolRZPbbU2MAi6Q=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.53.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.57.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Xds90ITXJCNyX9pDhqf85MKWUI4lqjiPAipJ8OLp8xqI2Ehk+TCVhF9rvOoN8xTbcafow3QOThkNnrM33uCFQA=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.53.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.57.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Xws2KA4CLvZmXjy46SQaXSejuKPhwVdaNinldoYfqruZBaJHqVo6hnRa8SDo9z7PBW5x84SH64+izmldCgbezw=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.53.3", "", { "os": "linux", "cpu": "arm" }, "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.57.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-hrKXKbX5FdaRJj7lTMusmvKbhMJSGWJ+w++4KmjiDhpTgNlhYobMvKfDoIWecy4O60K6yA4SnztGuNTQF+Lplw=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.53.3", "", { "os": "linux", "cpu": "arm" }, "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg=="], - "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-6A+nccfSDGKsPm00d3xKcrsBcbqzCTAukjwWK6rbuAnB2bHaL3r9720HBVZ/no7+FhZLz/U3GwwZZEh6tOSI8Q=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.53.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w=="], - "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-4P1VyYUe6XAJtQH1Hh99THxr0GKMMwIXsRNOceLrJnaHTDgk1FTcTimDgneRJPvB3LqDQxUmroBclQ1S0cIJwQ=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.53.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A=="], - "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.57.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-8Vv6pLuIZCMcgXre6c3nOPhE0gjz1+nZP6T+hwWjr7sVH8k0jRkH+XnfjjOTglyMBdSKBPPz54/y1gToSKwrSQ=="], + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.53.3", "", { "os": "linux", "cpu": "none" }, "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g=="], - "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.57.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-r1te1M0Sm2TBVD/RxBPC6RZVwNqUTwJTA7w+C/IW5v9Ssu6xmxWEi+iJQlpBhtUiT1raJ5b48pI8tBvEjEFnFA=="], + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.53.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-say0uMU/RaPm3CDQLxUUTF2oNWL8ysvHkAjcCzV2znxBr23kFfaxocS9qJm+NdkRhF8wtdEEAJuYcLPhSPbjuQ=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.53.3", "", { "os": "linux", "cpu": "none" }, "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g=="], - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-/MU7/HizQGsnBREtRpcSbSV1zfkoxSTR7wLsRmBPQ8FwUj5sykrP1MyJTvsxP5KBq9SyE6kH8UQQQwa0ASeoQQ=="], + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.53.3", "", { "os": "linux", "cpu": "none" }, "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.57.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Q9eh+gUGILIHEaJf66aF6a414jQbDnn29zeu0eX3dHMuysnhTvsUvZTCAyZ6tJhUjnvzBKE4FtuaYxutxRZpOg=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.53.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.57.0", "", { "os": "linux", "cpu": "x64" }, "sha512-OR5p5yG5OKSxHReWmwvM0P+VTPMwoBS45PXTMYaskKQqybkS3Kmugq1W+YbNWArF8/s7jQScgzXUhArzEQ7x0A=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.53.3", "", { "os": "linux", "cpu": "x64" }, "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.57.0", "", { "os": "linux", "cpu": "x64" }, "sha512-XeatKzo4lHDsVEbm1XDHZlhYZZSQYym6dg2X/Ko0kSFgio+KXLsxwJQprnR48GvdIKDOpqWqssC3iBCjoMcMpw=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.53.3", "", { "os": "linux", "cpu": "x64" }, "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q=="], - "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.57.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-Lu71y78F5qOfYmubYLHPcJm74GZLU6UJ4THkf/a1K7Tz2ycwC2VUbsqbJAXaR6Bx70SRdlVrt2+n5l7F0agTUw=="], + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.53.3", "", { "os": "none", "cpu": "arm64" }, "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw=="], - "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.57.0", "", { "os": "none", "cpu": "arm64" }, "sha512-v5xwKDWcu7qhAEcsUubiav7r+48Uk/ENWdr82MBZZRIm7zThSxCIVDfb3ZeRRq9yqk+oIzMdDo6fCcA5DHfMyA=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.53.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.57.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-XnaaaSMGSI6Wk8F4KK3QP7GfuuhjGchElsVerCplUuxRIzdvZ7hRBpLR0omCmw+kI2RFJB80nenhOoGXlJ5TfQ=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.53.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.57.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-3K1lP+3BXY4t4VihLw5MEg6IZD3ojSYzqzBG571W3kNQe4G4CcFpSUQVgurYgib5d+YaCjeFow8QivWp8vuSvA=="], + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.53.3", "", { "os": "win32", "cpu": "x64" }, "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg=="], - "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.57.0", "", { "os": "win32", "cpu": "x64" }, "sha512-MDk610P/vJGc5L5ImE4k5s+GZT3en0KoK1MKPXCRgzmksAMk79j4h3k1IerxTNqwDLxsGxStEZVBqG0gIqZqoA=="], - - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.57.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Zv7v6q6aV+VslnpwzqKAmrk5JdVkLUzok2208ZXGipjb+msxBr/fJPZyeEXiFgH7k62Ak0SLIfxQRZQvTuf7rQ=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.53.3", "", { "os": "win32", "cpu": "x64" }, "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ=="], "@selderee/plugin-htmlparser2": ["@selderee/plugin-htmlparser2@0.11.0", "", { "dependencies": { "domhandler": "^5.0.3", "selderee": "^0.11.0" } }, "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ=="], @@ -1515,7 +1533,7 @@ "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], - "@sindresorhus/is": ["@sindresorhus/is@7.2.0", "", {}, "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw=="], + "@sindresorhus/is": ["@sindresorhus/is@7.1.1", "", {}, "sha512-rO92VvpgMc3kfiTjGT52LEtJ8Yc5kCWhZjLQ3LwlA4pSgPpQO7bVpYXParOD8Jwf+cVQECJo3yP/4I8aZtUQTQ=="], "@slack/bolt": ["@slack/bolt@3.22.0", "", { "dependencies": { "@slack/logger": "^4.0.0", "@slack/oauth": "^2.6.3", "@slack/socket-mode": "^1.3.6", "@slack/types": "^2.13.0", "@slack/web-api": "^6.13.0", "@types/express": "^4.16.1", "@types/promise.allsettled": "^1.0.3", "@types/tsscmp": "^1.0.0", "axios": "^1.7.4", "express": "^4.21.0", "path-to-regexp": "^8.1.0", "promise.allsettled": "^1.0.2", "raw-body": "^2.3.3", "tsscmp": "^1.0.6" } }, "sha512-iKDqGPEJDnrVwxSVlFW6OKTkijd7s4qLBeSufoBsTM0reTyfdp/5izIQVkxNfzjHi3o6qjdYbRXkYad5HBsBog=="], @@ -1529,75 +1547,75 @@ "@slack/web-api": ["@slack/web-api@6.13.0", "", { "dependencies": { "@slack/logger": "^3.0.0", "@slack/types": "^2.11.0", "@types/is-stream": "^1.1.0", "@types/node": ">=12.0.0", "axios": "^1.7.4", "eventemitter3": "^3.1.0", "form-data": "^2.5.0", "is-electron": "2.2.2", "is-stream": "^1.1.0", "p-queue": "^6.6.1", "p-retry": "^4.0.0" } }, "sha512-dv65crIgdh9ZYHrevLU6XFHTQwTyDmNqEqzuIrV+Vqe/vgiG6w37oex5ePDU1RGm2IJ90H8iOvHFvzdEO/vB+g=="], - "@smithy/abort-controller": ["@smithy/abort-controller@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw=="], + "@smithy/abort-controller": ["@smithy/abort-controller@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA=="], "@smithy/chunked-blob-reader": ["@smithy/chunked-blob-reader@5.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA=="], "@smithy/chunked-blob-reader-native": ["@smithy/chunked-blob-reader-native@4.2.1", "", { "dependencies": { "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ=="], - "@smithy/config-resolver": ["@smithy/config-resolver@4.4.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ=="], + "@smithy/config-resolver": ["@smithy/config-resolver@4.4.3", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "tslib": "^2.6.2" } }, "sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw=="], - "@smithy/core": ["@smithy/core@3.22.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.9", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-stream": "^4.5.10", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-6vjCHD6vaY8KubeNw2Fg3EK0KLGQYdldG4fYgQmA0xSW0dJ8G2xFhSOdrlUakWVoP5JuWHtFODg3PNd/DN3FDA=="], + "@smithy/core": ["@smithy/core@3.18.5", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.6", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-stream": "^4.5.6", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-6gnIz3h+PEPQGDj8MnRSjDvKBah042jEoPgjFGJ4iJLBE78L4lY/n98x14XyPF4u3lN179Ub/ZKFY5za9GeLQw=="], - "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw=="], + "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.5", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "tslib": "^2.6.2" } }, "sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ=="], "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.7", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.11.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-DrpkEoM3j9cBBWhufqBwnbbn+3nf1N9FP6xuVJ+e220jbactKuQgaZwjwP5CP1t+O94brm2JgVMD2atMGX3xIQ=="], - "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.8", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-MTfQT/CRQz5g24ayXdjg53V0mhucZth4PESoA5IhvaWVDTOQLfo8qI9vzqHcPsdd2v6sqfTYqF5L/l+pea5Uyw=="], + "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.5", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-HohfmCQZjppVnKX2PnXlf47CW3j92Ki6T/vkAT2DhBR47e89pen3s4fIa7otGTtrVxmj7q+IhH0RnC5kpR8wtw=="], - "@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-ah12+luBiDGzBruhu3efNy1IlbwSEdNiw8fOZksoKoWW1ZHvO/04MQsdnws/9Aj+5b0YXSSN2JXKy/ClIsW8MQ=="], + "@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-ibjQjM7wEXtECiT6my1xfiMH9IcEczMOS6xiCQXoUIYSj5b1CpBbJ3VYbdwDy8Vcg5JHN7eFpOCGk8nyZAltNQ=="], - "@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.8", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-cYpCpp29z6EJHa5T9WL0KAlq3SOKUQkcgSoeRfRVwjGgSFl7Uh32eYGt7IDYCX20skiEdRffyDpvF2efEZPC0A=="], + "@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.5", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-+elOuaYx6F2H6x1/5BQP5ugv12nfJl66GhxON8+dWVUEDJ9jah/A0tayVdkLRP0AeSac0inYkDz5qBFKfVp2Gg=="], - "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.8", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-iJ6YNJd0bntJYnX6s52NC4WFYcZeKrPUr1Kmmr5AwZcwCSzVpS7oavAmxMR7pMq7V+D1G4s9F5NJK0xwOsKAlQ=="], + "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.5", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-G9WSqbST45bmIFaeNuP/EnC19Rhp54CcVdX9PDL1zyEB514WsDVXhlyihKlGXnRycmHNmVv88Bvvt4EYxWef/Q=="], - "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.9", "", { "dependencies": { "@smithy/protocol-http": "^5.3.8", "@smithy/querystring-builder": "^4.2.8", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA=="], + "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.6", "", { "dependencies": { "@smithy/protocol-http": "^5.3.5", "@smithy/querystring-builder": "^4.2.5", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg=="], - "@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.2.9", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.2.0", "@smithy/chunked-blob-reader-native": "^4.2.1", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-m80d/iicI7DlBDxyQP6Th7BW/ejDGiF0bgI754+tiwK0lgMkcaIBgvwwVc7OFbY4eUzpGtnig52MhPAEJ7iNYg=="], + "@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.2.6", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.2.0", "@smithy/chunked-blob-reader-native": "^4.2.1", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-8P//tA8DVPk+3XURk2rwcKgYwFvwGwmJH/wJqQiSKwXZtf/LiZK+hbUZmPj/9KzM+OVSwe4o85KTp5x9DUZTjw=="], - "@smithy/hash-node": ["@smithy/hash-node@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA=="], + "@smithy/hash-node": ["@smithy/hash-node@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA=="], - "@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-v0FLTXgHrTeheYZFGhR+ehX5qUm4IQsjAiL9qehad2cyjMWcN2QG6/4mSwbSgEQzI7jwfoXj7z4fxZUx/Mhj2w=="], + "@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-6+do24VnEyvWcGdHXomlpd0m8bfZePpUKBy7m311n+JuRwug8J4dCanJdTymx//8mi0nlkflZBvJe+dEO/O12Q=="], - "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ=="], + "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A=="], "@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="], - "@smithy/md5-js": ["@smithy/md5-js@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-oGMaLj4tVZzLi3itBa9TCswgMBr7k9b+qKYowQ6x1rTyTuO1IU2YHdHUa+891OsOH+wCsH7aTPRsTJO3RMQmjQ=="], + "@smithy/md5-js": ["@smithy/md5-js@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Bt6jpSTMWfjCtC0s79gZ/WZ1w90grfmopVOWqkI2ovhjpD5Q2XRXuecIPB9689L2+cCySMbaXDhBPU56FKNDNg=="], - "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.8", "", { "dependencies": { "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A=="], + "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A=="], - "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.12", "", { "dependencies": { "@smithy/core": "^3.22.0", "@smithy/middleware-serde": "^4.2.9", "@smithy/node-config-provider": "^4.3.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-9JMKHVJtW9RysTNjcBZQHDwB0p3iTP6B1IfQV4m+uCevkVd/VuLgwfqk5cnI4RHcp4cPwoIvxQqN4B1sxeHo8Q=="], + "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.12", "", { "dependencies": { "@smithy/core": "^3.18.5", "@smithy/middleware-serde": "^4.2.6", "@smithy/node-config-provider": "^4.3.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-middleware": "^4.2.5", "tslib": "^2.6.2" } }, "sha512-9pAX/H+VQPzNbouhDhkW723igBMLgrI8OtX+++M7iKJgg/zY/Ig3i1e6seCcx22FWhE6Q/S61BRdi2wXBORT+A=="], - "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.29", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/protocol-http": "^5.3.8", "@smithy/service-error-classification": "^4.2.8", "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-bmTn75a4tmKRkC5w61yYQLb3DmxNzB8qSVu9SbTYqW6GAL0WXO2bDZuMAn/GJSbOdHEdjZvWxe+9Kk015bw6Cg=="], + "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.5", "@smithy/protocol-http": "^5.3.5", "@smithy/service-error-classification": "^4.2.5", "@smithy/smithy-client": "^4.9.8", "@smithy/types": "^4.9.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-S4kWNKFowYd0lID7/DBqWHOQxmxlsf0jBaos9chQZUWTVOjSW1Ogyh8/ib5tM+agFDJ/TCxuCTvrnlc+9cIBcQ=="], - "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.9", "", { "dependencies": { "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ=="], + "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.6", "", { "dependencies": { "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-VkLoE/z7e2g8pirwisLz8XJWedUSY8my/qrp81VmAdyrhi94T+riBfwP+AOEEFR9rFTSonC/5D2eWNmFabHyGQ=="], - "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA=="], + "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-bYrutc+neOyWxtZdbB2USbQttZN0mXaOyYLIsaTbJhFsfpXyGWUxJpEuO1rJ8IIJm2qH4+xJT0mxUSsEDTYwdQ=="], - "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.8", "", { "dependencies": { "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg=="], + "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.5", "", { "dependencies": { "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-UTurh1C4qkVCtqggI36DGbLB2Kv8UlcFdMXDcWMbqVY2uRg0XmT9Pb4Vj6oSQ34eizO1fvR0RnFV4Axw4IrrAg=="], - "@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.8", "", { "dependencies": { "@smithy/abort-controller": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/querystring-builder": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-q9u+MSbJVIJ1QmJ4+1u+cERXkrhuILCBDsJUBAW1MPE6sFonbCNaegFuwW9ll8kh5UdyY3jOkoOGlc7BesoLpg=="], + "@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.5", "", { "dependencies": { "@smithy/abort-controller": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/querystring-builder": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-CMnzM9R2WqlqXQGtIlsHMEZfXKJVTIrqCNoSd/QpAyp+Dw0a1Vps13l6ma1fH8g7zSPNsA59B/kWgeylFuA/lw=="], - "@smithy/property-provider": ["@smithy/property-provider@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w=="], + "@smithy/property-provider": ["@smithy/property-provider@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-8iLN1XSE1rl4MuxvQ+5OSk/Zb5El7NJZ1td6Tn+8dQQHIjp59Lwl6bd0+nzw6SKm2wSSriH2v/I9LPzUic7EOg=="], - "@smithy/protocol-http": ["@smithy/protocol-http@5.3.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ=="], + "@smithy/protocol-http": ["@smithy/protocol-http@5.3.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-RlaL+sA0LNMp03bf7XPbFmT5gN+w3besXSWMkA8rcmxLSVfiEXElQi4O2IWwPfxzcHkxqrwBFMbngB8yx/RvaQ=="], - "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw=="], + "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-y98otMI1saoajeik2kLfGyRp11e5U/iJYH/wLCh3aTV/XutbGT9nziKGkgCaMD1ghK7p6htHMm6b6scl9JRUWg=="], - "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA=="], + "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-031WCTdPYgiQRYNPXznHXof2YM0GwL6SeaSyTH/P72M1Vz73TvCNH2Nq8Iu2IEPq9QP2yx0/nrw5YmSeAi/AjQ=="], - "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0" } }, "sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ=="], + "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0" } }, "sha512-8fEvK+WPE3wUAcDvqDQG1Vk3ANLR8Px979te96m84CbKAjBVf25rPYSzb4xU4hlTyho7VhOGnh5i62D/JVF0JQ=="], - "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.3", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg=="], + "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-5WmZ5+kJgJDjwXXIzr1vDTG+RhF9wzSODQBfkrQ2VVkYALKGvZX1lgVSxEkgicSAFnFhPj5rudJV0zoinqS0bA=="], - "@smithy/signature-v4": ["@smithy/signature-v4@5.3.8", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg=="], + "@smithy/signature-v4": ["@smithy/signature-v4@5.3.5", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w=="], - "@smithy/smithy-client": ["@smithy/smithy-client@4.11.1", "", { "dependencies": { "@smithy/core": "^3.22.0", "@smithy/middleware-endpoint": "^4.4.12", "@smithy/middleware-stack": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-stream": "^4.5.10", "tslib": "^2.6.2" } }, "sha512-SERgNg5Z1U+jfR6/2xPYjSEHY1t3pyTHC/Ma3YQl6qWtmiL42bvNId3W/oMUWIwu7ekL2FMPdqAmwbQegM7HeQ=="], + "@smithy/smithy-client": ["@smithy/smithy-client@4.9.8", "", { "dependencies": { "@smithy/core": "^3.18.5", "@smithy/middleware-endpoint": "^4.3.12", "@smithy/middleware-stack": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-stream": "^4.5.6", "tslib": "^2.6.2" } }, "sha512-8xgq3LgKDEFoIrLWBho/oYKyWByw9/corz7vuh1upv7ZBm0ZMjGYBhbn6v643WoIqA9UTcx5A5htEp/YatUwMA=="], - "@smithy/types": ["@smithy/types@4.12.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw=="], + "@smithy/types": ["@smithy/types@4.9.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA=="], - "@smithy/url-parser": ["@smithy/url-parser@4.2.8", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA=="], + "@smithy/url-parser": ["@smithy/url-parser@4.2.5", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-VaxMGsilqFnK1CeBX+LXnSuaMx4sTL/6znSZh2829txWieazdVxr54HmiyTsIbpOTLcf5nYpq9lpzmwRdxj6rQ=="], "@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="], @@ -1609,25 +1627,25 @@ "@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="], - "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.28", "", { "dependencies": { "@smithy/property-provider": "^4.2.8", "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-/9zcatsCao9h6g18p/9vH9NIi5PSqhCkxQ/tb7pMgRFnqYp9XUOyOlGPDMHzr8n5ih6yYgwJEY2MLEobUgi47w=="], + "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.11", "", { "dependencies": { "@smithy/property-provider": "^4.2.5", "@smithy/smithy-client": "^4.9.8", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-yHv+r6wSQXEXTPVCIQTNmXVWs7ekBTpMVErjqZoWkYN75HIFN5y9+/+sYOejfAuvxWGvgzgxbTHa/oz61YTbKw=="], - "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.31", "", { "dependencies": { "@smithy/config-resolver": "^4.4.6", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-JTvoApUXA5kbpceI2vuqQzRjeTbLpx1eoa5R/YEZbTgtxvIB7AQZxFJ0SEyfCpgPCyVV9IT7we+ytSeIB3CyWA=="], + "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.14", "", { "dependencies": { "@smithy/config-resolver": "^4.4.3", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/smithy-client": "^4.9.8", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-ljZN3iRvaJUgulfvobIuG97q1iUuCMrvXAlkZ4msY+ZuVHQHDIqn7FKZCEj+bx8omz6kF5yQXms/xhzjIO5XiA=="], - "@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw=="], + "@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.5", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A=="], "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="], - "@smithy/util-middleware": ["@smithy/util-middleware@4.2.8", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A=="], + "@smithy/util-middleware": ["@smithy/util-middleware@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-6Y3+rvBF7+PZOc40ybeZMcGln6xJGVeY60E7jy9Mv5iKpMJpHgRE6dKy9ScsVxvfAYuEX4Q9a65DQX90KaQ3bA=="], - "@smithy/util-retry": ["@smithy/util-retry@4.2.8", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg=="], + "@smithy/util-retry": ["@smithy/util-retry@4.2.5", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-GBj3+EZBbN4NAqJ/7pAhsXdfzdlznOh8PydUijy6FpNIMnHPSMO2/rP4HKu+UFeikJxShERk528oy7GT79YiJg=="], - "@smithy/util-stream": ["@smithy/util-stream@4.5.10", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.9", "@smithy/node-http-handler": "^4.4.8", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-jbqemy51UFSZSp2y0ZmRfckmrzuKww95zT9BYMmuJ8v3altGcqjwoV1tzpOwuHaKrwQrCjIzOib499ymr2f98g=="], + "@smithy/util-stream": ["@smithy/util-stream@4.5.6", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.6", "@smithy/node-http-handler": "^4.4.5", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-qWw/UM59TiaFrPevefOZ8CNBKbYEP6wBAIlLqxn3VAIo9rgnTNc4ASbVrqDmhuwI87usnjhdQrxodzAGFFzbRQ=="], "@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="], "@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="], - "@smithy/util-waiter": ["@smithy/util-waiter@4.2.8", "", { "dependencies": { "@smithy/abort-controller": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-n+lahlMWk+aejGuax7DPWtqav8HYnWxQwR+LCG2BgCUmaGcTe9qZCFsmw8TMg9iG75HOwhrJCX9TCJRLH+Yzqg=="], + "@smithy/util-waiter": ["@smithy/util-waiter@4.2.5", "", { "dependencies": { "@smithy/abort-controller": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Dbun99A3InifQdIrsXZ+QLcC0PGBPAdrl4cj1mTgJvyc9N2zf7QSxg8TBkzsCmGJdE3TLbO9ycwpY0EkWahQ/g=="], "@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="], @@ -1645,7 +1663,7 @@ "@solid-primitives/i18n": ["@solid-primitives/i18n@2.2.1", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-TnTnE2Ku11MGYZ1JzhJ8pYscwg1fr9MteoYxPwsfxWfh9Jp5K7RRJncJn9BhOHvNLwROjqOHZ46PT7sPHqbcXw=="], - "@solid-primitives/keyed": ["@solid-primitives/keyed@1.5.3", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-zNadtyYBhJSOjXtogkGHmRxjGdz9KHc8sGGVAGlUABkE8BED2tbIZoxkwSqzOwde8OcUEH0bb5DLZUWIMvyBSA=="], + "@solid-primitives/keyed": ["@solid-primitives/keyed@1.5.2", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-BgoEdqPw48URnI+L5sZIHdF4ua4Las1eWEBBPaoSFs42kkhnHue+rwCBPL2Z9ebOyQ75sUhUfOETdJfmv0D6Kg=="], "@solid-primitives/map": ["@solid-primitives/map@0.4.13", "", { "dependencies": { "@solid-primitives/trigger": "^1.1.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-B1zyFbsiTQvqPr+cuPCXO72sRuczG9Swncqk5P74NCGw1VE8qa/Ry9GlfI1e/VdeQYHjan+XkbE3rO2GW/qKew=="], @@ -1679,7 +1697,7 @@ "@solidjs/start": ["@solidjs/start@https://pkg.pr.new/@solidjs/start@dfb2020", { "dependencies": { "@babel/core": "^7.28.3", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.5", "@solidjs/meta": "^0.29.4", "@tanstack/server-functions-plugin": "1.134.5", "@types/babel__traverse": "^7.28.0", "@types/micromatch": "^4.0.9", "cookie-es": "^2.0.0", "defu": "^6.1.4", "error-stack-parser": "^2.1.4", "es-module-lexer": "^1.7.0", "esbuild": "^0.25.3", "fast-glob": "^3.3.3", "h3": "npm:h3@2.0.1-rc.4", "html-to-image": "^1.11.13", "micromatch": "^4.0.8", "path-to-regexp": "^8.2.0", "pathe": "^2.0.3", "radix3": "^1.1.2", "seroval": "^1.3.2", "seroval-plugins": "^1.2.1", "shiki": "^1.26.1", "solid-js": "^1.9.9", "source-map-js": "^1.2.1", "srvx": "^0.9.1", "terracotta": "^1.0.6", "vite": "7.1.10", "vite-plugin-solid": "^2.11.9", "vitest": "^4.0.10" } }], - "@speed-highlight/core": ["@speed-highlight/core@1.2.14", "", {}, "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA=="], + "@speed-highlight/core": ["@speed-highlight/core@1.2.12", "", {}, "sha512-uilwrK0Ygyri5dToHYdZSjcvpS2ZwX0w5aSt3GCEN9hrjxWCoeV4Z2DTXuxjwbntaLQIEEAlCeNQss5SoHvAEA=="], "@standard-community/standard-json": ["@standard-community/standard-json@0.3.5", "", { "peerDependencies": { "@standard-schema/spec": "^1.0.0", "@types/json-schema": "^7.0.15", "@valibot/to-json-schema": "^1.3.0", "arktype": "^2.1.20", "effect": "^3.16.8", "quansync": "^0.2.11", "sury": "^10.0.0", "typebox": "^1.0.17", "valibot": "^1.1.0", "zod": "^3.25.0 || ^4.0.0", "zod-to-json-schema": "^3.24.5" }, "optionalPeers": ["@valibot/to-json-schema", "arktype", "effect", "sury", "typebox", "valibot", "zod", "zod-to-json-schema"] }, "sha512-4+ZPorwDRt47i+O7RjyuaxHRK/37QY/LmgxlGrRrSTLYoFatEOzvqIc85GTlM18SFZ5E91C+v0o/M37wZPpUHA=="], @@ -1689,7 +1707,7 @@ "@stripe/stripe-js": ["@stripe/stripe-js@8.6.1", "", {}, "sha512-UJ05U2062XDgydbUcETH1AoRQLNhigQ2KmDn1BG8sC3xfzu6JKg95Qt6YozdzFpxl1Npii/02m2LEWFt1RYjVA=="], - "@swc/helpers": ["@swc/helpers@0.5.18", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ=="], + "@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="], "@tailwindcss/node": ["@tailwindcss/node@4.1.11", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.11" } }, "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q=="], @@ -1727,49 +1745,47 @@ "@tanstack/server-functions-plugin": ["@tanstack/server-functions-plugin@1.134.5", "", { "dependencies": { "@babel/code-frame": "7.27.1", "@babel/core": "^7.27.7", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@tanstack/directive-functions-plugin": "1.134.5", "babel-dead-code-elimination": "^1.0.9", "tiny-invariant": "^1.3.3" } }, "sha512-2sWxq70T+dOEUlE3sHlXjEPhaFZfdPYlWTSkHchWXrFGw2YOAa+hzD6L9wHMjGDQezYd03ue8tQlHG+9Jzbzgw=="], - "@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], - - "@tauri-apps/cli": ["@tauri-apps/cli@2.9.6", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.9.6", "@tauri-apps/cli-darwin-x64": "2.9.6", "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.6", "@tauri-apps/cli-linux-arm64-gnu": "2.9.6", "@tauri-apps/cli-linux-arm64-musl": "2.9.6", "@tauri-apps/cli-linux-riscv64-gnu": "2.9.6", "@tauri-apps/cli-linux-x64-gnu": "2.9.6", "@tauri-apps/cli-linux-x64-musl": "2.9.6", "@tauri-apps/cli-win32-arm64-msvc": "2.9.6", "@tauri-apps/cli-win32-ia32-msvc": "2.9.6", "@tauri-apps/cli-win32-x64-msvc": "2.9.6" }, "bin": { "tauri": "tauri.js" } }, "sha512-3xDdXL5omQ3sPfBfdC8fCtDKcnyV7OqyzQgfyT5P3+zY6lcPqIYKQBvUasNvppi21RSdfhy44ttvJmftb0PCDw=="], + "@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], - "@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.9.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gf5no6N9FCk1qMrti4lfwP77JHP5haASZgVbBgpZG7BUepB3fhiLCXGUK8LvuOjP36HivXewjg72LTnPDScnQQ=="], + "@tauri-apps/cli": ["@tauri-apps/cli@2.9.4", "", { "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" }, "bin": { "tauri": "tauri.js" } }, "sha512-pvylWC9QckrOS9ATWXIXcgu7g2hKK5xTL5ZQyZU/U0n9l88SEFGcWgLQNa8WZmd+wWIOWhkxOFcOl3i6ubDNNw=="], - "@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.9.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-oWh74WmqbERwwrwcueJyY6HYhgCksUc6NT7WKeXyrlY/FPmNgdyQAgcLuTSkhRFuQ6zh4Np1HZpOqCTpeZBDcw=="], + "@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.9.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-9rHkMVtbMhe0AliVbrGpzMahOBg3rwV46JYRELxR9SN6iu1dvPOaMaiC4cP6M/aD1424ziXnnMdYU06RAH8oIw=="], - "@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.9.6", "", { "os": "linux", "cpu": "arm" }, "sha512-/zde3bFroFsNXOHN204DC2qUxAcAanUjVXXSdEGmhwMUZeAQalNj5cz2Qli2elsRjKN/hVbZOJj0gQ5zaYUjSg=="], + "@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.9.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-VT9ymNuT06f5TLjCZW2hfSxbVtZDhORk7CDUDYiq5TiSYQdxkl8MVBy0CCFFcOk4QAkUmqmVUA9r3YZ/N/vPRQ=="], - "@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.9.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-pvbljdhp9VOo4RnID5ywSxgBs7qiylTPlK56cTk7InR3kYSTJKYMqv/4Q/4rGo/mG8cVppesKIeBMH42fw6wjg=="], + "@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.9.4", "", { "os": "linux", "cpu": "arm" }, "sha512-tTWkEPig+2z3Rk0zqZYfjUYcgD+aSm72wdrIhdYobxbQZOBw0zfn50YtWv+av7bm0SHvv75f0l7JuwgZM1HFow=="], - "@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.9.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-02TKUndpodXBCR0oP//6dZWGYcc22Upf2eP27NvC6z0DIqvkBBFziQUcvi2n6SrwTRL0yGgQjkm9K5NIn8s6jw=="], + "@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-ql6vJ611qoqRYHxkKPnb2vHa27U+YRKRmIpLMMBeZnfFtZ938eao7402AQCH1mO2+/8ioUhbpy9R/ZcLTXVmkg=="], - "@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.9.6", "", { "os": "linux", "cpu": "none" }, "sha512-fmp1hnulbqzl1GkXl4aTX9fV+ubHw2LqlLH1PE3BxZ11EQk+l/TmiEongjnxF0ie4kV8DQfDNJ1KGiIdWe1GvQ=="], + "@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-vg7yNn7ICTi6hRrcA/6ff2UpZQP7un3xe3SEld5QM0prgridbKAiXGaCKr3BnUBx/rGXegQlD/wiLcWdiiraSw=="], - "@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.9.6", "", { "os": "linux", "cpu": "x64" }, "sha512-vY0le8ad2KaV1PJr+jCd8fUF9VOjwwQP/uBuTJvhvKTloEwxYA/kAjKK9OpIslGA9m/zcnSo74czI6bBrm2sYA=="], + "@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.9.4", "", { "os": "linux", "cpu": "none" }, "sha512-l8L+3VxNk6yv5T/Z/gv5ysngmIpsai40B9p6NQQyqYqxImqYX37pqREoEBl1YwG7szGnDibpWhidPrWKR59OJA=="], - "@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.9.6", "", { "os": "linux", "cpu": "x64" }, "sha512-TOEuB8YCFZTWVDzsO2yW0+zGcoMiPPwcUgdnW1ODnmgfwccpnihDRoks+ABT1e3fHb1ol8QQWsHSCovb3o2ENQ=="], + "@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-PepPhCXc/xVvE3foykNho46OmCyx47E/aG676vKTVp+mqin5d+IBqDL6wDKiGNT5OTTxKEyNlCQ81Xs2BQhhqA=="], - "@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.9.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-ujmDGMRc4qRLAnj8nNG26Rlz9klJ0I0jmZs2BPpmNNf0gM/rcVHhqbEkAaHPTBVIrtUdf7bGvQAD2pyIiUrBHQ=="], + "@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-zcd1QVffh5tZs1u1SCKUV/V7RRynebgYUNWHuV0FsIF1MjnULUChEXhAhug7usCDq4GZReMJOoXa6rukEozWIw=="], - "@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.9.6", "", { "os": "win32", "cpu": "ia32" }, "sha512-S4pT0yAJgFX8QRCyKA1iKjZ9Q/oPjCZf66A/VlG5Yw54Nnr88J1uBpmenINbXxzyhduWrIXBaUbEY1K80ZbpMg=="], + "@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.9.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-/7ZhnP6PY04bEob23q8MH/EoDISdmR1wuNm0k9d5HV7TDMd2GGCDa8dPXA4vJuglJKXIfXqxFmZ4L+J+MO42+w=="], - "@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.9.6", "", { "os": "win32", "cpu": "x64" }, "sha512-ldWuWSSkWbKOPjQMJoYVj9wLHcOniv7diyI5UAJ4XsBdtaFB0pKHQsqw/ItUma0VXGC7vB4E9fZjivmxur60aw=="], + "@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.9.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-1LmAfaC4Cq+3O1Ir1ksdhczhdtFSTIV51tbAGtbV/mr348O+M52A/xwCCXQank0OcdBxy5BctqkMtuZnQvA8uQ=="], - "@tauri-apps/plugin-deep-link": ["@tauri-apps/plugin-deep-link@2.4.6", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-UUOSt0U5juK20uhO2MoHZX/IPblkrhUh+VPtIeu3RwtzI0R9Em3Auzfg/PwcZ9Pv8mLne3cQ4p9CFXD6WxqCZA=="], + "@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-EdYd4c9wGvtPB95kqtEyY+bUR+k4kRw3IA30mAQ1jPH6z57AftT8q84qwv0RDp6kkEqOBKxeInKfqi4BESYuqg=="], - "@tauri-apps/plugin-dialog": ["@tauri-apps/plugin-dialog@2.6.0", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg=="], + "@tauri-apps/plugin-dialog": ["@tauri-apps/plugin-dialog@2.4.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-lNIn5CZuw8WZOn8zHzmFmDSzg5zfohWoa3mdULP0YFh/VogVdMVWZPcWSHlydsiJhRQYaTNSYKN7RmZKE2lCYQ=="], - "@tauri-apps/plugin-http": ["@tauri-apps/plugin-http@2.5.6", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-KhCK3TDNDF4vdz75/j+KNQipYKf+295Visa8r32QcXScg0+D3JwShcCM6D+FN8WuDF24X3KSiAB8QtRxW6jKRA=="], + "@tauri-apps/plugin-http": ["@tauri-apps/plugin-http@2.5.4", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-/i4U/9za3mrytTgfRn5RHneKubZE/dwRmshYwyMvNRlkWjvu1m4Ma72kcbVJMZFGXpkbl+qLyWMGrihtWB76Zg=="], "@tauri-apps/plugin-notification": ["@tauri-apps/plugin-notification@2.3.3", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-Zw+ZH18RJb41G4NrfHgIuofJiymusqN+q8fGUIIV7vyCH+5sSn5coqRv/MWB9qETsUs97vmU045q7OyseCV3Qg=="], - "@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.5.3", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ=="], + "@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.5.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-ei/yRRoCklWHImwpCcDK3VhNXx+QXM9793aQ64YxpqVF0BDuuIlXhZgiAkc15wnPVav+IbkYhmDJIv5R326Mew=="], "@tauri-apps/plugin-os": ["@tauri-apps/plugin-os@2.3.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-n+nXWeuSeF9wcEsSPmRnBEGrRgOy6jjkSU+UVCOV8YUGKb2erhDOxis7IqRXiRVHhY8XMKks00BJ0OAdkpf6+A=="], "@tauri-apps/plugin-process": ["@tauri-apps/plugin-process@2.3.1", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA=="], - "@tauri-apps/plugin-shell": ["@tauri-apps/plugin-shell@2.3.4", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-ktsRWf8wHLD17aZEyqE8c5x98eNAuTizR1FSX475zQ4TxaiJnhwksLygQz+AGwckJL5bfEP13nWrlTNQJUpKpA=="], + "@tauri-apps/plugin-shell": ["@tauri-apps/plugin-shell@2.3.3", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-Xod+pRcFxmOWFWEnqH5yZcA7qwAMuaaDkMR1Sply+F8VfBj++CGnj2xf5UoialmjZ2Cvd8qrvSCbU+7GgNVsKQ=="], - "@tauri-apps/plugin-store": ["@tauri-apps/plugin-store@2.4.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-0ClHS50Oq9HEvLPhNzTNFxbWVOqoAp3dRvtewQBeqfIQ0z5m3JRnOISIn2ZVPCrQC0MyGyhTS9DWhHjpigQE7A=="], + "@tauri-apps/plugin-store": ["@tauri-apps/plugin-store@2.4.1", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-ckGSEzZ5Ii4Hf2D5x25Oqnm2Zf9MfDWAzR+volY0z/OOBz6aucPKEY0F649JvQ0Vupku6UJo7ugpGRDOFOunkA=="], "@tauri-apps/plugin-updater": ["@tauri-apps/plugin-updater@2.9.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-j++sgY8XpeDvzImTrzWA08OqqGqgkNyxczLD7FjNJJx/uXxMZFz5nDcfkyoI/rCjYuj2101Tci/r/HFmOmoxCg=="], @@ -1813,7 +1829,7 @@ "@types/express": ["@types/express@4.17.25", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "^1" } }, "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw=="], - "@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.8", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA=="], + "@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.7", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg=="], "@types/fontkit": ["@types/fontkit@2.0.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-wN+8bYxIpJf+5oZdrdtaX04qUuWHcKxcDEgRS9Qm9ZClSHjzEn13SxUC+5eRM+4yXIeTYk8mTzLAWGF64847ew=="], @@ -1881,7 +1897,7 @@ "@types/whatwg-mimetype": ["@types/whatwg-mimetype@3.0.2", "", {}, "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA=="], - "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + "@types/ws": ["@types/ws@7.4.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww=="], "@types/yargs": ["@types/yargs@17.0.33", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA=="], @@ -1909,23 +1925,23 @@ "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], - "@vercel/oidc": ["@vercel/oidc@3.1.0", "", {}, "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w=="], + "@vercel/oidc": ["@vercel/oidc@3.0.5", "", {}, "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw=="], "@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="], - "@vitest/expect": ["@vitest/expect@4.0.18", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.0.18", "@vitest/utils": "4.0.18", "chai": "^6.2.1", "tinyrainbow": "^3.0.3" } }, "sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ=="], + "@vitest/expect": ["@vitest/expect@4.0.16", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.0.16", "@vitest/utils": "4.0.16", "chai": "^6.2.1", "tinyrainbow": "^3.0.3" } }, "sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA=="], - "@vitest/mocker": ["@vitest/mocker@4.0.18", "", { "dependencies": { "@vitest/spy": "4.0.18", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ=="], + "@vitest/mocker": ["@vitest/mocker@4.0.16", "", { "dependencies": { "@vitest/spy": "4.0.16", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg=="], - "@vitest/pretty-format": ["@vitest/pretty-format@4.0.18", "", { "dependencies": { "tinyrainbow": "^3.0.3" } }, "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw=="], + "@vitest/pretty-format": ["@vitest/pretty-format@4.0.16", "", { "dependencies": { "tinyrainbow": "^3.0.3" } }, "sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA=="], - "@vitest/runner": ["@vitest/runner@4.0.18", "", { "dependencies": { "@vitest/utils": "4.0.18", "pathe": "^2.0.3" } }, "sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw=="], + "@vitest/runner": ["@vitest/runner@4.0.16", "", { "dependencies": { "@vitest/utils": "4.0.16", "pathe": "^2.0.3" } }, "sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q=="], - "@vitest/snapshot": ["@vitest/snapshot@4.0.18", "", { "dependencies": { "@vitest/pretty-format": "4.0.18", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA=="], + "@vitest/snapshot": ["@vitest/snapshot@4.0.16", "", { "dependencies": { "@vitest/pretty-format": "4.0.16", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA=="], - "@vitest/spy": ["@vitest/spy@4.0.18", "", {}, "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw=="], + "@vitest/spy": ["@vitest/spy@4.0.16", "", {}, "sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw=="], - "@vitest/utils": ["@vitest/utils@4.0.18", "", { "dependencies": { "@vitest/pretty-format": "4.0.18", "tinyrainbow": "^3.0.3" } }, "sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA=="], + "@vitest/utils": ["@vitest/utils@4.0.16", "", { "dependencies": { "@vitest/pretty-format": "4.0.16", "tinyrainbow": "^3.0.3" } }, "sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA=="], "@webgpu/types": ["@webgpu/types@0.1.54", "", {}, "sha512-81oaalC8LFrXjhsczomEQ0u3jG+TqE6V9QHLA8GNZq/Rnot0KDugu3LhSYSlie8tSdooAN1Hov05asrUUp9qgg=="], @@ -1947,7 +1963,7 @@ "agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="], - "ai": ["ai@5.0.124", "", { "dependencies": { "@ai-sdk/gateway": "2.0.30", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Li6Jw9F9qsvFJXZPBfxj38ddP2iURCnMs96f9Q3OeQzrDVcl1hvtwSEAuxA/qmfh6SDV2ERqFUOFzigvr0697g=="], + "ai": ["ai@5.0.119", "", { "dependencies": { "@ai-sdk/gateway": "2.0.25", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-HUOwhc17fl2SZTJGZyA/99aNu706qKfXaUBCy9vgZiXBwrxg2eTzn2BCz7kmYDsfx6Fg2ACBy2icm41bsDXCTw=="], "ajv": ["ajv@8.17.1", "", { "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=="], @@ -2001,7 +2017,7 @@ "astro": ["astro@5.7.13", "", { "dependencies": { "@astrojs/compiler": "^2.11.0", "@astrojs/internal-helpers": "0.6.1", "@astrojs/markdown-remark": "6.3.1", "@astrojs/telemetry": "3.2.1", "@capsizecss/unpack": "^2.4.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.4", "acorn": "^8.14.1", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.2.0", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.0.2", "cssesc": "^3.0.0", "debug": "^4.4.0", "deterministic-object-hash": "^2.0.2", "devalue": "^5.1.1", "diff": "^5.2.0", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.6.0", "esbuild": "^0.25.0", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.3.0", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.1.1", "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.17", "magicast": "^0.3.5", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.0", "package-manager-detector": "^1.1.0", "picomatch": "^4.0.2", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.1", "shiki": "^3.2.1", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.12", "tsconfck": "^3.1.5", "ultrahtml": "^1.6.0", "unifont": "~0.5.0", "unist-util-visit": "^5.0.0", "unstorage": "^1.15.0", "vfile": "^6.0.3", "vite": "^6.3.4", "vitefu": "^1.0.6", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.1", "zod": "^3.24.2", "zod-to-json-schema": "^3.24.5", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.33.3" }, "bin": { "astro": "astro.js" } }, "sha512-cRGq2llKOhV3XMcYwQpfBIUcssN6HEK5CRbcMxAfd9OcFhvWE7KUy50zLioAZVVl3AqgUTJoNTlmZfD2eG0G1w=="], - "astro-expressive-code": ["astro-expressive-code@0.41.6", "", { "dependencies": { "rehype-expressive-code": "^0.41.6" }, "peerDependencies": { "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" } }, "sha512-l47tb1uhmVIebHUkw+HEPtU/av0G4O8Q34g2cbkPvC7/e9ZhANcjUUciKt9Hp6gSVDdIuXBBLwJQn2LkeGMOAw=="], + "astro-expressive-code": ["astro-expressive-code@0.41.3", "", { "dependencies": { "rehype-expressive-code": "^0.41.3" }, "peerDependencies": { "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0" } }, "sha512-u+zHMqo/QNLE2eqYRCrK3+XMlKakv33Bzuz+56V1gs8H0y6TZ0hIi3VNbIxeTn51NLn+mJfUV/A0kMNfE4rANw=="], "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], @@ -2009,7 +2025,7 @@ "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], - "autoprefixer": ["autoprefixer@10.4.23", "", { "dependencies": { "browserslist": "^4.28.1", "caniuse-lite": "^1.0.30001760", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA=="], + "autoprefixer": ["autoprefixer@10.4.22", "", { "dependencies": { "browserslist": "^4.27.0", "caniuse-lite": "^1.0.30001754", "fraction.js": "^5.3.4", "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-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg=="], "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], @@ -2021,13 +2037,13 @@ "aws4fetch": ["aws4fetch@1.0.20", "", {}, "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g=="], - "axios": ["axios@1.13.4", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg=="], + "axios": ["axios@1.13.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA=="], "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], "b4a": ["b4a@1.7.3", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q=="], - "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="], + "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.10", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA=="], "babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.40.3", "", { "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=="], @@ -2045,7 +2061,7 @@ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.9.19", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.8.30", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA=="], "bcp-47": ["bcp-47@2.1.0", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w=="], @@ -2065,7 +2081,7 @@ "bmp-ts": ["bmp-ts@1.0.9", "", {}, "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw=="], - "body-parser": ["body-parser@1.20.4", "", { "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "~1.2.0", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.14.0", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA=="], + "body-parser": ["body-parser@1.20.3", "", { "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" } }, "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g=="], "bonjour-service": ["bonjour-service@1.3.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA=="], @@ -2073,7 +2089,7 @@ "bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="], - "bowser": ["bowser@2.13.1", "", {}, "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw=="], + "bowser": ["bowser@2.12.1", "", {}, "sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw=="], "boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="], @@ -2083,7 +2099,7 @@ "brotli": ["brotli@1.3.3", "", { "dependencies": { "base64-js": "^1.1.2" } }, "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg=="], - "browserslist": ["browserslist@4.28.1", "", { "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=="], + "browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" } }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="], "buffer": ["buffer@4.9.2", "", { "dependencies": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", "isarray": "^1.0.0" } }, "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg=="], @@ -2129,11 +2145,11 @@ "camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="], - "caniuse-lite": ["caniuse-lite@1.0.30001766", "", {}, "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA=="], + "caniuse-lite": ["caniuse-lite@1.0.30001756", "", {}, "sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], - "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], + "chai": ["chai@6.2.1", "", {}, "sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg=="], "chainsaw": ["chainsaw@0.1.0", "", { "dependencies": { "traverse": ">=0.3.0 <0.4" } }, "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ=="], @@ -2157,7 +2173,7 @@ "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], - "ci-info": ["ci-info@4.4.0", "", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], + "ci-info": ["ci-info@4.3.1", "", {}, "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA=="], "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], @@ -2167,7 +2183,7 @@ "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], - "cli-spinners": ["cli-spinners@3.4.0", "", {}, "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw=="], + "cli-spinners": ["cli-spinners@3.3.0", "", {}, "sha512-/+40ljC3ONVnYIttjMWrlL51nItDAbBrq2upN8BPyvGU/2n5Oxw3tbNwORCaNuNqLJnxGqOfjUuhsv7l5Q4IsQ=="], "clipboardy": ["clipboardy@4.0.0", "", { "dependencies": { "execa": "^8.0.1", "is-wsl": "^3.1.0", "is64bit": "^2.0.0" } }, "sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w=="], @@ -2179,6 +2195,8 @@ "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + "cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="], + "collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="], "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], @@ -2215,15 +2233,15 @@ "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], + "cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="], "cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="], - "cookie-signature": ["cookie-signature@1.0.7", "", {}, "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA=="], + "cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="], "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], - "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], + "cors": ["cors@2.8.5", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="], "crc-32": ["crc-32@1.2.2", "", { "bin": { "crc32": "bin/crc32.njs" } }, "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="], @@ -2233,11 +2251,11 @@ "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], - "crossws": ["crossws@0.4.4", "", { "peerDependencies": { "srvx": ">=0.7.1" }, "optionalPeers": ["srvx"] }, "sha512-w6c4OdpRNnudVmcgr7brb/+/HmYjMQvYToO/oTrprTwxRUiom3LYWU1PMWuD006okbUWpII1Ea9/+kwpUfmyRg=="], + "crossws": ["crossws@0.4.1", "", { "peerDependencies": { "srvx": ">=0.7.1" }, "optionalPeers": ["srvx"] }, "sha512-E7WKBcHVhAVrY6JYD5kteNqVq1GSZxqGrdSiwXR9at+XHi43HJoCQKXcCczR5LBnBquFZPsB3o7HklulKoBU5w=="], "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], - "css-selector-parser": ["css-selector-parser@3.3.0", "", {}, "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g=="], + "css-selector-parser": ["css-selector-parser@3.2.0", "", {}, "sha512-L1bdkNKUP5WYxiW5dW6vA2hd3sL8BdRNLy2FCX0rLVise4eNw9nBdeBuJHxlELieSE2H1f6bYQFfwVUwWCV9rQ=="], "css-tree": ["css-tree@3.1.0", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="], @@ -2261,7 +2279,7 @@ "decimal.js": ["decimal.js@10.5.0", "", {}, "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw=="], - "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], + "decode-named-character-reference": ["decode-named-character-reference@1.2.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q=="], "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], @@ -2297,7 +2315,7 @@ "deterministic-object-hash": ["deterministic-object-hash@2.0.2", "", { "dependencies": { "base-64": "^1.0.0" } }, "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ=="], - "devalue": ["devalue@5.6.2", "", {}, "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg=="], + "devalue": ["devalue@5.5.0", "", {}, "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w=="], "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], @@ -2347,7 +2365,7 @@ "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], - "electron-to-chromium": ["electron-to-chromium@1.5.282", "", {}, "sha512-FCPkJtpst28UmFzd903iU7PdeVTfY0KAeJy+Lk0GLZRwgwYHn/irRcaCbQQOmr5Vytc/7rcavsYLvTM8RiHYhQ=="], + "electron-to-chromium": ["electron-to-chromium@1.5.259", "", {}, "sha512-I+oLXgpEJzD6Cwuwt1gYjxsDmu/S/Kd41mmLA3O+/uH2pFRO/DvOjUyGozL8j3KeLV6WyZ7ssPwELMsXCcsJAQ=="], "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], @@ -2359,7 +2377,7 @@ "engine.io-parser": ["engine.io-parser@5.2.3", "", {}, "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q=="], - "enhanced-resolve": ["enhanced-resolve@5.18.4", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q=="], + "enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="], "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], @@ -2369,7 +2387,7 @@ "error-stack-parser-es": ["error-stack-parser-es@1.0.5", "", {}, "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA=="], - "es-abstract": ["es-abstract@1.24.1", "", { "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" } }, "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw=="], + "es-abstract": ["es-abstract@1.24.0", "", { "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" } }, "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg=="], "es-array-method-boxes-properly": ["es-array-method-boxes-properly@1.0.0", "", {}, "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA=="], @@ -2391,10 +2409,12 @@ "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], - "esbuild": ["esbuild@0.25.12", "", { "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=="], + "esbuild": ["esbuild@0.25.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.5", "@esbuild/android-arm": "0.25.5", "@esbuild/android-arm64": "0.25.5", "@esbuild/android-x64": "0.25.5", "@esbuild/darwin-arm64": "0.25.5", "@esbuild/darwin-x64": "0.25.5", "@esbuild/freebsd-arm64": "0.25.5", "@esbuild/freebsd-x64": "0.25.5", "@esbuild/linux-arm": "0.25.5", "@esbuild/linux-arm64": "0.25.5", "@esbuild/linux-ia32": "0.25.5", "@esbuild/linux-loong64": "0.25.5", "@esbuild/linux-mips64el": "0.25.5", "@esbuild/linux-ppc64": "0.25.5", "@esbuild/linux-riscv64": "0.25.5", "@esbuild/linux-s390x": "0.25.5", "@esbuild/linux-x64": "0.25.5", "@esbuild/netbsd-arm64": "0.25.5", "@esbuild/netbsd-x64": "0.25.5", "@esbuild/openbsd-arm64": "0.25.5", "@esbuild/openbsd-x64": "0.25.5", "@esbuild/sunos-x64": "0.25.5", "@esbuild/win32-arm64": "0.25.5", "@esbuild/win32-ia32": "0.25.5", "@esbuild/win32-x64": "0.25.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ=="], "esbuild-plugin-copy": ["esbuild-plugin-copy@2.1.1", "", { "dependencies": { "chalk": "^4.1.2", "chokidar": "^3.5.3", "fs-extra": "^10.0.1", "globby": "^11.0.3" }, "peerDependencies": { "esbuild": ">= 0.14.0" } }, "sha512-Bk66jpevTcV8KMFzZI1P7MZKZ+uDcrZm2G2egZ2jNIvVnivDpodZI+/KnpL3Jnap0PBdIHU7HwFGB8r+vV5CVw=="], + "esbuild-plugin-solid": ["esbuild-plugin-solid@0.6.0", "", { "dependencies": { "@babel/core": "^7.20.12", "@babel/preset-typescript": "^7.18.6", "babel-preset-solid": "^1.6.9" }, "peerDependencies": { "esbuild": ">=0.20", "solid-js": ">= 1.0" } }, "sha512-V1FvDALwLDX6K0XNYM9CMRAnMzA0+Ecu55qBUT9q/eAJh1KIDsTMFoOzMSgyHqbOfvrVfO3Mws3z7TW2GVnIZA=="], + "esbuild-register": ["esbuild-register@3.6.0", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "esbuild": ">=0.12 <1" } }, "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg=="], "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], @@ -2423,7 +2443,7 @@ "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], - "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], + "eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], "events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], @@ -2441,11 +2461,11 @@ "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], - "express": ["express@4.22.1", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "~1.20.3", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.3.1", "fresh": "~0.5.2", "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", "serve-static": "~1.16.2", "setprototypeof": "1.2.0", "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g=="], + "express": ["express@4.21.2", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.19.0", "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA=="], "express-rate-limit": ["express-rate-limit@7.5.1", "", { "peerDependencies": { "express": ">= 4.11" } }, "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw=="], - "expressive-code": ["expressive-code@0.41.6", "", { "dependencies": { "@expressive-code/core": "^0.41.6", "@expressive-code/plugin-frames": "^0.41.6", "@expressive-code/plugin-shiki": "^0.41.6", "@expressive-code/plugin-text-markers": "^0.41.6" } }, "sha512-W/5+IQbrpCIM5KGLjO35wlp1NCwDOOVQb+PAvzEoGkW1xjGM807ZGfBKptNWH6UECvt6qgmLyWolCMYKh7eQmA=="], + "expressive-code": ["expressive-code@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3", "@expressive-code/plugin-frames": "^0.41.3", "@expressive-code/plugin-shiki": "^0.41.3", "@expressive-code/plugin-text-markers": "^0.41.3" } }, "sha512-YLnD62jfgBZYrXIPQcJ0a51Afv9h8VlWqEGK9uU2T5nL/5rb8SnA86+7+mgCZe5D34Tff5RNEA5hjNVJYHzrFg=="], "exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="], @@ -2465,7 +2485,7 @@ "fast-xml-parser": ["fast-xml-parser@4.4.1", "", { "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw=="], - "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], + "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], @@ -2475,7 +2495,7 @@ "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], - "finalhandler": ["finalhandler@1.3.2", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "statuses": "~2.0.2", "unpipe": "~1.0.0" } }, "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg=="], + "finalhandler": ["finalhandler@1.3.1", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", "statuses": "2.0.1", "unpipe": "~1.0.0" } }, "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ=="], "find-babel-config": ["find-babel-config@2.1.2", "", { "dependencies": { "json5": "^2.2.3" } }, "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg=="], @@ -2565,7 +2585,7 @@ "glob": ["glob@11.1.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": { "glob": "dist/esm/bin.mjs" } }, "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw=="], - "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], "glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="], @@ -2591,7 +2611,7 @@ "h3": ["h3@2.0.1-rc.4", "", { "dependencies": { "rou3": "^0.7.8", "srvx": "^0.9.1" }, "peerDependencies": { "crossws": "^0.4.1" }, "optionalPeers": ["crossws"] }, "sha512-vZq8pEUp6THsXKXrUXX44eOqfChic2wVQ1GlSzQCBr7DeFBkfIZAo2WyNND4GSv54TAa0E4LYIK73WSPdgKUgw=="], - "happy-dom": ["happy-dom@20.4.0", "", { "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", "entities": "^4.5.0", "whatwg-mimetype": "^3.0.0", "ws": "^8.18.3" } }, "sha512-RDeQm3dT9n0A5f/TszjUmNCLEuPnMGv3Tv4BmNINebz/h17PA6LMBcxJ5FrcqltNBMh9jA/8ufgDdBYUdBt+eg=="], + "happy-dom": ["happy-dom@20.0.11", "", { "dependencies": { "@types/node": "^20.0.0", "@types/whatwg-mimetype": "^3.0.2", "whatwg-mimetype": "^3.0.0" } }, "sha512-QsCdAUHAmiDeKeaNojb1OHOPF7NjcWPBR7obdu3NwH2a/oyQaLg5d0aaCy/9My6CdPChYF07dvz5chaXBGaD4g=="], "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="], @@ -2639,7 +2659,7 @@ "hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="], - "hast-util-to-parse5": ["hast-util-to-parse5@8.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA=="], + "hast-util-to-parse5": ["hast-util-to-parse5@8.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^6.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw=="], "hast-util-to-string": ["hast-util-to-string@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A=="], @@ -2675,7 +2695,7 @@ "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], - "http-errors": ["http-errors@2.0.1", "", { "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=="], + "http-errors": ["http-errors@2.0.0", "", { "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", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], @@ -2689,7 +2709,7 @@ "i18next": ["i18next@23.16.8", "", { "dependencies": { "@babel/runtime": "^7.23.2" } }, "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg=="], - "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], + "iconv-lite": ["iconv-lite@0.7.0", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ=="], "ieee754": ["ieee754@1.1.13", "", {}, "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="], @@ -2709,6 +2729,8 @@ "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="], + "ioredis": ["ioredis@5.8.2", "", { "dependencies": { "@ioredis/commands": "1.4.0", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-C6uC+kleiIMmjViJINWk80sOQw5lEzse1ZmvD+S/s8p8CWapftSaC+kocGTx6xrbrJ4WmYQGC08ffHLr6ToR6Q=="], + "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], "iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="], @@ -2837,7 +2859,7 @@ "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], @@ -2857,11 +2879,11 @@ "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], - "jsonwebtoken": ["jsonwebtoken@9.0.3", "", { "dependencies": { "jws": "^4.0.1", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g=="], + "jsonwebtoken": ["jsonwebtoken@9.0.2", "", { "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ=="], "jwa": ["jwa@2.0.1", "", { "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", "", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="], + "jws": ["jws@4.0.0", "", { "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg=="], "jwt-decode": ["jwt-decode@3.1.2", "", {}, "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="], @@ -2903,16 +2925,20 @@ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="], - "lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="], + "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], "locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], - "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="], + "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], + + "lodash.defaults": ["lodash.defaults@4.2.0", "", {}, "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="], "lodash.includes": ["lodash.includes@4.3.0", "", {}, "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="], + "lodash.isarguments": ["lodash.isarguments@3.1.0", "", {}, "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="], + "lodash.isboolean": ["lodash.isboolean@3.0.3", "", {}, "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="], "lodash.isinteger": ["lodash.isinteger@4.0.4", "", {}, "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="], @@ -2991,7 +3017,7 @@ "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], - "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "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=="], + "mdast-util-to-hast": ["mdast-util-to-hast@13.2.0", "", { "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-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA=="], "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], @@ -3105,8 +3131,6 @@ "mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="], - "morphdom": ["morphdom@2.7.8", "", {}, "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg=="], - "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], @@ -3119,7 +3143,7 @@ "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], - "named-placeholders": ["named-placeholders@1.1.6", "", { "dependencies": { "lru.min": "^1.1.0" } }, "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w=="], + "named-placeholders": ["named-placeholders@1.1.3", "", { "dependencies": { "lru-cache": "^7.14.1" } }, "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w=="], "nanoevents": ["nanoevents@7.0.1", "", {}, "sha512-o6lpKiCxLeijK4hgsqfR6CNToPyRU3keKyyI6uwuHRvpRTbZ0wXw51WRgyldVugZqoJfkGFrjrIenYH3bfEO3Q=="], @@ -3147,9 +3171,9 @@ "node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="], - "node-html-parser": ["node-html-parser@7.0.2", "", { "dependencies": { "css-select": "^5.1.0", "he": "1.2.0" } }, "sha512-DxodLVh7a6JMkYzWyc8nBX9MaF4M0lLFYkJHlWOiu7+9/I6mwNK9u5TbAMC7qfqDJEPX9OIoWA2A9t4C2l1mUQ=="], + "node-html-parser": ["node-html-parser@7.0.1", "", { "dependencies": { "css-select": "^5.1.0", "he": "1.2.0" } }, "sha512-KGtmPY2kS0thCWGK0VuPyOS+pBKhhe8gXztzA2ilAOhbUbxa9homF1bOyKvhGzMLXUoRds9IOmr/v5lr/lqNmA=="], - "node-mock-http": ["node-mock-http@1.0.4", "", {}, "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ=="], + "node-mock-http": ["node-mock-http@1.0.3", "", {}, "sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog=="], "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="], @@ -3157,15 +3181,17 @@ "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], + "npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="], "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], - "nypm": ["nypm@0.6.4", "", { "dependencies": { "citty": "^0.2.0", "pathe": "^2.0.3", "tinyexec": "^1.0.2" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-1TvCKjZyyklN+JJj2TS3P4uSQEInrM/HkkuSXsEzm1ApPgBffOn8gFguNnZf07r/1X6vlryfIqMUkJKQMzlZiw=="], + "nypm": ["nypm@0.6.2", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.2", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "tinyexec": "^1.0.1" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g=="], "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], - "object-hash": ["object-hash@2.2.0", "", {}, "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw=="], + "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], @@ -3231,7 +3257,7 @@ "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], - "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], + "package-manager-detector": ["package-manager-detector@1.5.0", "", {}, "sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw=="], "pagefind": ["pagefind@1.4.0", "", { "optionalDependencies": { "@pagefind/darwin-arm64": "1.4.0", "@pagefind/darwin-x64": "1.4.0", "@pagefind/freebsd-x64": "1.4.0", "@pagefind/linux-arm64": "1.4.0", "@pagefind/linux-x64": "1.4.0", "@pagefind/windows-x64": "1.4.0" }, "bin": { "pagefind": "lib/runner/bin.cjs" } }, "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g=="], @@ -3279,7 +3305,7 @@ "peek-readable": ["peek-readable@4.1.0", "", {}, "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="], - "perfect-debounce": ["perfect-debounce@2.1.0", "", {}, "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g=="], + "perfect-debounce": ["perfect-debounce@2.0.0", "", {}, "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow=="], "piccolore": ["piccolore@0.1.3", "", {}, "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw=="], @@ -3355,7 +3381,7 @@ "punycode": ["punycode@1.3.2", "", {}, "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="], - "qs": ["qs@6.14.1", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ=="], + "qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="], "quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="], @@ -3367,7 +3393,7 @@ "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], - "raw-body": ["raw-body@2.5.3", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "unpipe": "~1.0.0" } }, "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA=="], + "raw-body": ["raw-body@2.5.2", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA=="], "rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], @@ -3405,9 +3431,13 @@ "recma-stringify": ["recma-stringify@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-to-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g=="], + "redis-errors": ["redis-errors@1.2.0", "", {}, "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="], + + "redis-parser": ["redis-parser@3.0.0", "", { "dependencies": { "redis-errors": "^1.0.0" } }, "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A=="], + "reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "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" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="], - "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], + "regex": ["regex@6.0.1", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA=="], "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], @@ -3419,7 +3449,7 @@ "rehype-autolink-headings": ["rehype-autolink-headings@7.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-heading-rank": "^3.0.0", "hast-util-is-element": "^3.0.0", "unified": "^11.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw=="], - "rehype-expressive-code": ["rehype-expressive-code@0.41.6", "", { "dependencies": { "expressive-code": "^0.41.6" } }, "sha512-aBMX8kxPtjmDSFUdZlAWJkMvsQ4ZMASfee90JWIAV8tweltXLzkWC3q++43ToTelI8ac5iC0B3/S/Cl4Ql1y2g=="], + "rehype-expressive-code": ["rehype-expressive-code@0.41.3", "", { "dependencies": { "expressive-code": "^0.41.3" } }, "sha512-8d9Py4c/V6I/Od2VIXFAdpiO2kc0SV2qTJsRAaqSIcM9aruW4ASLNe2kOEo1inXAAkIhpFzAHTc358HKbvpNUg=="], "rehype-format": ["rehype-format@5.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-format": "^1.0.0" } }, "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ=="], @@ -3477,9 +3507,9 @@ "rimraf": ["rimraf@5.0.10", "", { "dependencies": { "glob": "^10.3.7" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ=="], - "rollup": ["rollup@4.57.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.0", "@rollup/rollup-android-arm64": "4.57.0", "@rollup/rollup-darwin-arm64": "4.57.0", "@rollup/rollup-darwin-x64": "4.57.0", "@rollup/rollup-freebsd-arm64": "4.57.0", "@rollup/rollup-freebsd-x64": "4.57.0", "@rollup/rollup-linux-arm-gnueabihf": "4.57.0", "@rollup/rollup-linux-arm-musleabihf": "4.57.0", "@rollup/rollup-linux-arm64-gnu": "4.57.0", "@rollup/rollup-linux-arm64-musl": "4.57.0", "@rollup/rollup-linux-loong64-gnu": "4.57.0", "@rollup/rollup-linux-loong64-musl": "4.57.0", "@rollup/rollup-linux-ppc64-gnu": "4.57.0", "@rollup/rollup-linux-ppc64-musl": "4.57.0", "@rollup/rollup-linux-riscv64-gnu": "4.57.0", "@rollup/rollup-linux-riscv64-musl": "4.57.0", "@rollup/rollup-linux-s390x-gnu": "4.57.0", "@rollup/rollup-linux-x64-gnu": "4.57.0", "@rollup/rollup-linux-x64-musl": "4.57.0", "@rollup/rollup-openbsd-x64": "4.57.0", "@rollup/rollup-openharmony-arm64": "4.57.0", "@rollup/rollup-win32-arm64-msvc": "4.57.0", "@rollup/rollup-win32-ia32-msvc": "4.57.0", "@rollup/rollup-win32-x64-gnu": "4.57.0", "@rollup/rollup-win32-x64-msvc": "4.57.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA=="], + "rollup": ["rollup@4.53.3", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.53.3", "@rollup/rollup-android-arm64": "4.53.3", "@rollup/rollup-darwin-arm64": "4.53.3", "@rollup/rollup-darwin-x64": "4.53.3", "@rollup/rollup-freebsd-arm64": "4.53.3", "@rollup/rollup-freebsd-x64": "4.53.3", "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", "@rollup/rollup-linux-arm-musleabihf": "4.53.3", "@rollup/rollup-linux-arm64-gnu": "4.53.3", "@rollup/rollup-linux-arm64-musl": "4.53.3", "@rollup/rollup-linux-loong64-gnu": "4.53.3", "@rollup/rollup-linux-ppc64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-musl": "4.53.3", "@rollup/rollup-linux-s390x-gnu": "4.53.3", "@rollup/rollup-linux-x64-gnu": "4.53.3", "@rollup/rollup-linux-x64-musl": "4.53.3", "@rollup/rollup-openharmony-arm64": "4.53.3", "@rollup/rollup-win32-arm64-msvc": "4.53.3", "@rollup/rollup-win32-ia32-msvc": "4.53.3", "@rollup/rollup-win32-x64-gnu": "4.53.3", "@rollup/rollup-win32-x64-msvc": "4.53.3", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA=="], - "rou3": ["rou3@0.7.12", "", {}, "sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg=="], + "rou3": ["rou3@0.7.10", "", {}, "sha512-aoFj6f7MJZ5muJ+Of79nrhs9N3oLGqi2VEMe94Zbkjb6Wupha46EuoYgpWSOZlXww3bbd8ojgXTAA2mzimX5Ww=="], "router": ["router@2.2.0", "", { "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=="], @@ -3509,7 +3539,7 @@ "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - "send": ["send@0.19.2", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "~0.5.2", "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.4.1", "range-parser": "~1.2.1", "statuses": "~2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="], + "send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="], "seq-queue": ["seq-queue@0.0.5", "", {}, "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="], @@ -3517,7 +3547,7 @@ "seroval-plugins": ["seroval-plugins@1.3.3", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w=="], - "serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="], + "serve-static": ["serve-static@1.16.2", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.19.0" } }, "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw=="], "set-function-length": ["set-function-length@1.2.2", "", { "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" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], @@ -3561,7 +3591,7 @@ "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], - "smol-toml": ["smol-toml@1.6.0", "", {}, "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw=="], + "smol-toml": ["smol-toml@1.5.2", "", {}, "sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ=="], "socket.io-client": ["socket.io-client@4.8.3", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.4.1", "engine.io-client": "~6.6.1", "socket.io-parser": "~4.2.4" } }, "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g=="], @@ -3593,7 +3623,7 @@ "sqlstring": ["sqlstring@2.3.3", "", {}, "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg=="], - "srvx": ["srvx@0.9.8", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-RZaxTKJEE/14HYn8COLuUOJAt0U55N9l1Xf6jj+T0GoA01EUH1Xz5JtSUOI+EHn+AEgPCVn7gk6jHJffrr06fQ=="], + "srvx": ["srvx@0.9.6", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-5L4rT6qQqqb+xcoDoklUgCNdmzqJ6vbcDRwPVGRXewF55IJH0pqh0lQlrJ266ZWTKJ4mfeioqHQJeAYesS+RrQ=="], "sst": ["sst@3.17.23", "", { "dependencies": { "aws-sdk": "2.1692.0", "aws4fetch": "1.0.18", "jose": "5.2.3", "opencontrol": "0.0.6", "openid-client": "5.6.4" }, "optionalDependencies": { "sst-darwin-arm64": "3.17.23", "sst-darwin-x64": "3.17.23", "sst-linux-arm64": "3.17.23", "sst-linux-x64": "3.17.23", "sst-linux-x86": "3.17.23", "sst-win32-arm64": "3.17.23", "sst-win32-x64": "3.17.23", "sst-win32-x86": "3.17.23" }, "bin": { "sst": "bin/sst.mjs" } }, "sha512-TwKgUgDnZdc1Swe+bvCNeyO4dQnYz5cTodMpYj3jlXZdK9/KNz0PVxT1f0u5E76i1pmilXrUBL/f7iiMPw4RDg=="], @@ -3617,9 +3647,11 @@ "stackframe": ["stackframe@1.3.4", "", {}, "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="], - "stage-js": ["stage-js@1.0.0-alpha.18", "", {}, "sha512-Mh+pbkfxA6NXlDrcutP8vp1Zg04pDRcC8D39UXKZzEcQeBPOZ4SRUSkIsF26aoODUZ4CSQRY7shXc1Avb0wZKA=="], + "stage-js": ["stage-js@1.0.0-alpha.17", "", {}, "sha512-AzlMO+t51v6cFvKZ+Oe9DJnL1OXEH5s9bEy6di5aOrUpcP7PCzI/wIeXF0u3zg0L89gwnceoKxrLId0ZpYnNXw=="], + + "standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="], - "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + "statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], @@ -3677,13 +3709,13 @@ "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], - "tar": ["tar@7.5.7", "", { "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=="], + "tar": ["tar@7.5.2", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg=="], "tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="], - "terracotta": ["terracotta@1.1.0", "", { "dependencies": { "solid-use": "^0.9.1" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-kfQciWUBUBgYkXu7gh3CK3FAJng/iqZslAaY08C+k1Hdx17aVEpcFFb/WPaysxAfcupNH3y53s/pc53xxZauww=="], + "terracotta": ["terracotta@1.0.6", "", { "dependencies": { "solid-use": "^0.9.0" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-yVrmT/Lg6a3tEbeYEJH8ksb1PYkR5FA9k5gr1TchaSNIiA2ZWs5a+koEbePXwlBP0poaV7xViZ/v50bQFcMgqw=="], - "terser": ["terser@5.46.0", "", { "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" } }, "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg=="], + "terser": ["terser@5.44.1", "", { "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" } }, "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw=="], "text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="], @@ -3775,7 +3807,7 @@ "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], - "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], + "ufo": ["ufo@1.6.1", "", {}, "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA=="], "ulid": ["ulid@3.0.1", "", { "bin": { "ulid": "dist/cli.js" } }, "sha512-dPJyqPzx8preQhqq24bBG1YNkvigm87K8kVEHCD+ruZg24t6IFEFv00xMWfxcC4djmFtiTLdFuADn4+DOz6R7Q=="], @@ -3785,7 +3817,7 @@ "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="], - "undici": ["undici@7.19.2", "", {}, "sha512-4VQSpGEGsWzk0VYxyB/wVX/Q7qf9t5znLRgs0dzszr9w9Fej/8RVNQ+S20vdXSAyra/bJ7ZQfGv6ZMj7UEbzSg=="], + "undici": ["undici@7.16.0", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="], "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], @@ -3813,7 +3845,7 @@ "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], - "unist-util-visit": ["unist-util-visit@5.1.0", "", { "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": ["unist-util-visit@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="], "unist-util-visit-children": ["unist-util-visit-children@3.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA=="], @@ -3827,11 +3859,11 @@ "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], - "unstorage": ["unstorage@2.0.0-alpha.5", "", { "peerDependencies": { "@azure/app-configuration": "^1.9.0", "@azure/cosmos": "^4.7.0", "@azure/data-tables": "^13.3.1", "@azure/identity": "^4.13.0", "@azure/keyvault-secrets": "^4.10.0", "@azure/storage-blob": "^12.29.1", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.12.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.35.6", "@vercel/blob": ">=0.27.3", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "chokidar": "^4 || ^5", "db0": ">=0.3.4", "idb-keyval": "^6.2.2", "ioredis": "^5.8.2", "lru-cache": "^11.2.2", "mongodb": "^6 || ^7", "ofetch": "*", "uploadthing": "^7.7.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "chokidar", "db0", "idb-keyval", "ioredis", "lru-cache", "mongodb", "ofetch", "uploadthing"] }, "sha512-Sj8btci21Twnd6M+N+MHhjg3fVn6lAPElPmvFTe0Y/wR0WImErUdA1PzlAaUavHylJ7uDiFwlZDQKm0elG4b7g=="], + "unstorage": ["unstorage@2.0.0-alpha.4", "", { "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "chokidar": "^4.0.3", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "lru-cache": "^11.2.2", "mongodb": "^6.20.0", "ofetch": "*", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "chokidar", "db0", "idb-keyval", "ioredis", "lru-cache", "mongodb", "ofetch", "uploadthing"] }, "sha512-ywXZMZRfrvmO1giJeMTCw6VUn0ALYxVl8pFqJPStiyQUvgJImejtAHrKvXPj4QGJAoS/iLGcVGF6ljN/lkh1bw=="], "unzip-stream": ["unzip-stream@0.3.4", "", { "dependencies": { "binary": "^0.3.0", "mkdirp": "^0.5.1" } }, "sha512-PyofABPVv+d7fL7GOpusx7eRT9YETY2X04PhwbSipdj6bMxVCFJrr+nm0Mxqbf9hUiTin/UsnuFWBXlDZFy0Cw=="], - "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "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=="], + "update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="], "url": ["url@0.10.3", "", { "dependencies": { "punycode": "1.3.2", "querystring": "0.2.0" } }, "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ=="], @@ -3869,7 +3901,7 @@ "vitefu": ["vitefu@1.1.1", "", { "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@4.0.18", "", { "dependencies": { "@vitest/expect": "4.0.18", "@vitest/mocker": "4.0.18", "@vitest/pretty-format": "4.0.18", "@vitest/runner": "4.0.18", "@vitest/snapshot": "4.0.18", "@vitest/spy": "4.0.18", "@vitest/utils": "4.0.18", "es-module-lexer": "^1.7.0", "expect-type": "^1.2.2", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^3.10.0", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.0.3", "vite": "^6.0.0 || ^7.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.0.18", "@vitest/browser-preview": "4.0.18", "@vitest/browser-webdriverio": "4.0.18", "@vitest/ui": "4.0.18", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ=="], + "vitest": ["vitest@4.0.16", "", { "dependencies": { "@vitest/expect": "4.0.16", "@vitest/mocker": "4.0.16", "@vitest/pretty-format": "4.0.16", "@vitest/runner": "4.0.16", "@vitest/snapshot": "4.0.16", "@vitest/spy": "4.0.16", "@vitest/utils": "4.0.16", "es-module-lexer": "^1.7.0", "expect-type": "^1.2.2", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^3.10.0", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.0.3", "vite": "^6.0.0 || ^7.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.0.16", "@vitest/browser-preview": "4.0.16", "@vitest/browser-webdriverio": "4.0.16", "@vitest/ui": "4.0.16", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q=="], "vscode-jsonrpc": ["vscode-jsonrpc@8.2.1", "", {}, "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ=="], @@ -3897,7 +3929,7 @@ "which-pm-runs": ["which-pm-runs@1.1.0", "", {}, "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA=="], - "which-typed-array": ["which-typed-array@1.1.20", "", { "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" } }, "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg=="], + "which-typed-array": ["which-typed-array@1.1.19", "", { "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" } }, "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw=="], "why-is-node-running": ["why-is-node-running@3.2.2", "", { "bin": { "why-is-node-running": "cli.js" } }, "sha512-NKUzAelcoCXhXL4dJzKIwXeR8iEVqsA0Lq6Vnd0UXvgaKbzVo4ZTHROF2Jidrv+SgxOQ03fMinnNhzZATxOD3A=="], @@ -3915,7 +3947,7 @@ "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], - "wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="], + "wsl-utils": ["wsl-utils@0.3.0", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-3sFIGLiaDP7rTO4xh3g+b3AzhYDIUGGywE/WsmqzJWDxus5aJXVnPTNC/6L+r2WzrwXqVOdD262OaO+cEyPMSQ=="], "xdg-basedir": ["xdg-basedir@5.1.0", "", {}, "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ=="], @@ -3933,7 +3965,7 @@ "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], - "yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="], + "yaml": ["yaml@2.8.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw=="], "yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="], @@ -3961,7 +3993,7 @@ "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], - "@actions/artifact/@actions/core": ["@actions/core@2.0.3", "", { "dependencies": { "@actions/exec": "^2.0.0", "@actions/http-client": "^3.0.2" } }, "sha512-Od9Thc3T1mQJYddvVPM4QGiLUewdh+3txmDYHHxoNdkqysR1MbCT+rFOtNUxYAz+7+6RIsqipVahY2GJqGPyxA=="], + "@actions/artifact/@actions/core": ["@actions/core@2.0.1", "", { "dependencies": { "@actions/exec": "^2.0.0", "@actions/http-client": "^3.0.0" } }, "sha512-oBfqT3GwkvLlo1fjvhQLQxuwZCGTarTE5OuZ2Wg10hvhBj7LRIlF611WT4aZS6fDhO5ZKlY7lCAZTlpmyaHaeg=="], "@actions/core/@actions/http-client": ["@actions/http-client@2.2.3", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^5.25.4" } }, "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA=="], @@ -3973,11 +4005,13 @@ "@actions/github/undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="], - "@actions/http-client/undici": ["undici@6.23.0", "", {}, "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g=="], + "@actions/http-client/undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="], - "@ai-sdk/amazon-bedrock/@ai-sdk/anthropic": ["@ai-sdk/anthropic@2.0.58", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-CkNW5L1Arv8gPtPlEmKd+yf/SG9ucJf0XQdpMG8OiYEtEMc2smuCA+tyCp8zI7IBVg/FE7nUfFHntQFaOjRwJQ=="], + "@agentclientprotocol/sdk/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@ai-sdk/amazon-bedrock/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.8", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.12.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw=="], + "@ai-sdk/amazon-bedrock/@ai-sdk/anthropic": ["@ai-sdk/anthropic@2.0.57", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-DREpYqW2pylgaj69gZ+K8u92bo9DaMgFdictYnY+IwYeY3bawQ4zI7l/o1VkDsBDljAx8iYz5lPURwVZNu+Xpg=="], + + "@ai-sdk/amazon-bedrock/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.5", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.9.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Ogt4Zi9hEbIP17oQMd68qYOHUzmH47UkK7q7Gl55iIm9oKt27MUGrC5JfpMroeHjdkOliOA4Qt3NQ1xMq/nrlA=="], "@ai-sdk/anthropic/@ai-sdk/provider": ["@ai-sdk/provider@2.0.0", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA=="], @@ -3985,11 +4019,11 @@ "@ai-sdk/azure/@ai-sdk/openai": ["@ai-sdk/openai@2.0.89", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-4+qWkBCbL9HPKbgrUO/F2uXZ8GqrYxHa8SWEYIzxEJ9zvWw3ISr3t1/27O1i8MGSym+PzEyHBT48EV4LAwWaEw=="], - "@ai-sdk/cerebras/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.32", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-YspqqyJPzHjqWrjt4y/Wgc2aJgCcQj5uIJgZpq2Ar/lH30cEVhgE+keePDbjKpetD9UwNggCj7u6kO3unS23OQ=="], + "@ai-sdk/cerebras/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.30", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-thubwhRtv9uicAxSWwNpinM7hiL/0CkhL/ymPaHuKvI494J7HIzn8KQZQ2ymRz284WTIZnI7VMyyejxW4RMM6w=="], - "@ai-sdk/deepinfra/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.32", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-YspqqyJPzHjqWrjt4y/Wgc2aJgCcQj5uIJgZpq2Ar/lH30cEVhgE+keePDbjKpetD9UwNggCj7u6kO3unS23OQ=="], + "@ai-sdk/deepinfra/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.30", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-thubwhRtv9uicAxSWwNpinM7hiL/0CkhL/ymPaHuKvI494J7HIzn8KQZQ2ymRz284WTIZnI7VMyyejxW4RMM6w=="], - "@ai-sdk/google-vertex/@ai-sdk/anthropic": ["@ai-sdk/anthropic@2.0.58", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-CkNW5L1Arv8gPtPlEmKd+yf/SG9ucJf0XQdpMG8OiYEtEMc2smuCA+tyCp8zI7IBVg/FE7nUfFHntQFaOjRwJQ=="], + "@ai-sdk/google-vertex/@ai-sdk/anthropic": ["@ai-sdk/anthropic@2.0.57", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-DREpYqW2pylgaj69gZ+K8u92bo9DaMgFdictYnY+IwYeY3bawQ4zI7l/o1VkDsBDljAx8iYz5lPURwVZNu+Xpg=="], "@ai-sdk/openai/@ai-sdk/provider": ["@ai-sdk/provider@2.0.0", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA=="], @@ -3999,17 +4033,19 @@ "@ai-sdk/openai-compatible/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.0", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-BoQZtGcBxkeSH1zK+SRYNDtJPIPpacTeiMZqnG4Rv6xXjEwM0FH4MGs9c+PlhyEWmQCzjRM2HAotEydFhD4dYw=="], - "@ai-sdk/togetherai/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.32", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-YspqqyJPzHjqWrjt4y/Wgc2aJgCcQj5uIJgZpq2Ar/lH30cEVhgE+keePDbjKpetD9UwNggCj7u6kO3unS23OQ=="], + "@ai-sdk/togetherai/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.30", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-thubwhRtv9uicAxSWwNpinM7hiL/0CkhL/ymPaHuKvI494J7HIzn8KQZQ2ymRz284WTIZnI7VMyyejxW4RMM6w=="], - "@ai-sdk/vercel/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.32", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-YspqqyJPzHjqWrjt4y/Wgc2aJgCcQj5uIJgZpq2Ar/lH30cEVhgE+keePDbjKpetD9UwNggCj7u6kO3unS23OQ=="], + "@ai-sdk/vercel/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.30", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-thubwhRtv9uicAxSWwNpinM7hiL/0CkhL/ymPaHuKvI494J7HIzn8KQZQ2ymRz284WTIZnI7VMyyejxW4RMM6w=="], - "@ai-sdk/xai/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.32", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-YspqqyJPzHjqWrjt4y/Wgc2aJgCcQj5uIJgZpq2Ar/lH30cEVhgE+keePDbjKpetD9UwNggCj7u6kO3unS23OQ=="], + "@ai-sdk/xai/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.30", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-thubwhRtv9uicAxSWwNpinM7hiL/0CkhL/ymPaHuKvI494J7HIzn8KQZQ2ymRz284WTIZnI7VMyyejxW4RMM6w=="], "@astrojs/cloudflare/vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "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-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="], "@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="], - "@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.10", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.5", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.19.0", "smol-toml": "^1.5.2", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A=="], + "@astrojs/markdown-remark/shiki": ["shiki@3.15.0", "", { "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" } }, "sha512-kLdkY6iV3dYbtPwS9KXU7mjfmDm25f5m0IPNFnaXO7TBPcvbUOY72PYXSuSqDzwp+vlH/d7MXpHlKO/x+QoLXw=="], + + "@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.9", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.5", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.13.0", "smol-toml": "^1.4.2", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-hX2cLC/KW74Io1zIbn92kI482j9J7LleBLGCVU9EP3BeH5MVrnFawOnqD0t/q6D1Z+ZNeQG2gNKMslCcO36wng=="], "@astrojs/sitemap/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -4019,6 +4055,8 @@ "@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], + "@aws-crypto/sha256-js/@aws-sdk/types": ["@aws-sdk/types@3.775.0", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ZoGKwa4C9fC9Av6bdfqcW6Ix5ot05F/S4VxWR2nHuMv7hzfmAjTOcUiWT7UR4hM/U0whf84VhDtXN/DWAk52KA=="], + "@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], "@aws-sdk/client-sts/@aws-sdk/core": ["@aws-sdk/core@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/core": "^3.2.0", "@smithy/node-config-provider": "^4.0.2", "@smithy/property-provider": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/signature-v4": "^5.0.2", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/util-middleware": "^4.0.2", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-8vpW4WihVfz0DX+7WnnLGm3GuQER++b0IwQG35JlQMlgqnc44M//KbJPsIHA0aJUJVwJAEShgfr5dUbY8WUzaA=="], @@ -4053,7 +4091,7 @@ "@azure/core-http/xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="], - "@azure/core-xml/fast-xml-parser": ["fast-xml-parser@5.3.3", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-2O3dkPAAC6JavuMm8+4+pgTk+5hoAs+CjZ+sWcQLkX9+/tHRuTkQh/Oaifr8qDmZ8iEHb771Ea6G8CdwkrgvYA=="], + "@azure/core-xml/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="], "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], @@ -4071,10 +4109,12 @@ "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], - "@gitlab/gitlab-ai-provider/openai": ["openai@6.17.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-NHRpPEUPzAvFOAFs9+9pC6+HCw/iWsYsKCMPXH5Kw7BpMxqd8g/A07/1o7Gx2TWtCnzevVRyKMRFqyiHyAlqcA=="], + "@expressive-code/plugin-shiki/shiki": ["shiki@3.15.0", "", { "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" } }, "sha512-kLdkY6iV3dYbtPwS9KXU7mjfmDm25f5m0IPNFnaXO7TBPcvbUOY72PYXSuSqDzwp+vlH/d7MXpHlKO/x+QoLXw=="], "@gitlab/gitlab-ai-provider/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@hey-api/json-schema-ref-parser/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "@hey-api/openapi-ts/open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="], "@hono/zod-validator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -4125,7 +4165,7 @@ "@jsx-email/doiuse-email/htmlparser2": ["htmlparser2@9.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "entities": "^4.5.0" } }, "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ=="], - "@modelcontextprotocol/sdk/express": ["express@5.2.1", "", { "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=="], + "@modelcontextprotocol/sdk/express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.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-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="], "@modelcontextprotocol/sdk/jose": ["jose@6.1.3", "", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="], @@ -4215,6 +4255,8 @@ "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], + "@prokube/app-prefixable/tailwindcss": ["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.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=="], + "@protobuf-ts/plugin/typescript": ["typescript@3.9.10", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q=="], "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], @@ -4233,8 +4275,6 @@ "@slack/socket-mode/@slack/logger": ["@slack/logger@3.0.0", "", { "dependencies": { "@types/node": ">=12.0.0" } }, "sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA=="], - "@slack/socket-mode/@types/ws": ["@types/ws@7.4.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww=="], - "@slack/socket-mode/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], "@slack/web-api/@slack/logger": ["@slack/logger@3.0.0", "", { "dependencies": { "@types/node": ">=12.0.0" } }, "sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA=="], @@ -4245,7 +4285,11 @@ "@slack/web-api/p-queue": ["p-queue@6.6.2", "", { "dependencies": { "eventemitter3": "^4.0.4", "p-timeout": "^3.2.0" } }, "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ=="], - "@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.8", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.12.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw=="], + "@smithy/eventstream-codec/@smithy/types": ["@smithy/types@4.11.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-mlrmL0DRDVe3mNrjTcVcZEgkFmufITfUAPBEA+AHYiIeYyJebso/He1qLbP3PssRe22KUzLRpQSdBPbXdgZ2VA=="], + + "@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.5", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.9.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Ogt4Zi9hEbIP17oQMd68qYOHUzmH47UkK7q7Gl55iIm9oKt27MUGrC5JfpMroeHjdkOliOA4Qt3NQ1xMq/nrlA=="], + + "@solidjs/start/esbuild": ["esbuild@0.25.12", "", { "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=="], "@solidjs/start/path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], @@ -4255,9 +4299,9 @@ "@tailwindcss/oxide/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], @@ -4267,10 +4311,6 @@ "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@tanstack/directive-functions-plugin/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], - - "@tanstack/server-functions-plugin/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], - "accepts/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], "ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], @@ -4283,9 +4323,15 @@ "astro/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="], - "astro/diff": ["diff@5.2.2", "", {}, "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A=="], + "astro/diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="], + + "astro/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="], + + "astro/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], - "astro/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "astro/shiki": ["shiki@3.15.0", "", { "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" } }, "sha512-kLdkY6iV3dYbtPwS9KXU7mjfmDm25f5m0IPNFnaXO7TBPcvbUOY72PYXSuSqDzwp+vlH/d7MXpHlKO/x+QoLXw=="], + + "astro/unstorage": ["unstorage@1.17.3", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^4.0.3", "destr": "^2.0.5", "h3": "^1.15.4", "lru-cache": "^10.4.3", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.1" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-i+JYyy0DoKmQ3FximTHbGadmIYb8JEpq7lxUjnjeB702bCPum0vzo6oy5Mfu0lpqISw7hCyMW2yj4nWC8bqJ3Q=="], "astro/vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "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-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="], @@ -4301,7 +4347,9 @@ "body-parser/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], - "bun-webgpu/@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="], + "body-parser/qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="], + + "bun-webgpu/@webgpu/types": ["@webgpu/types@0.1.66", "", {}, "sha512-YA2hLrwLpDsRueNDXIMqN9NTzD6bCDkuXbOSe0heS+f8YE8usA6Gbv1prj81pzVHrbaAma7zObnIC+I6/sXJgA=="], "c12/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], @@ -4321,6 +4369,8 @@ "editorconfig/minimatch": ["minimatch@9.0.1", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w=="], + "editorconfig/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], + "engine.io-client/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], "es-get-iterator/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], @@ -4331,12 +4381,16 @@ "execa/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], - "express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + "express/cookie": ["cookie@0.7.1", "", {}, "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w=="], "express/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], "express/path-to-regexp": ["path-to-regexp@0.1.12", "", {}, "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="], + "express/qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="], + + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "fetch-blob/web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -4345,18 +4399,24 @@ "gaxios/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], + "gel/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], + "glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="], "globby/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], "gray-matter/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], - "happy-dom/ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], + "hast-util-to-parse5/property-information": ["property-information@6.5.0", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="], "html-minifier-terser/commander": ["commander@10.0.1", "", {}, "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="], "js-beautify/glob": ["glob@10.5.0", "", { "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=="], + "jsonwebtoken/jws": ["jws@3.2.2", "", { "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA=="], + + "jsonwebtoken/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], + "katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="], "lazystream/readable-stream": ["readable-stream@2.3.8", "", { "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" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], @@ -4375,19 +4435,19 @@ "miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], + "named-placeholders/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + "nitro/h3": ["h3@2.0.1-rc.5", "", { "dependencies": { "rou3": "^0.7.9", "srvx": "^0.9.1" }, "peerDependencies": { "crossws": "^0.4.1" }, "optionalPeers": ["crossws"] }, "sha512-qkohAzCab0nLzXNm78tBjZDvtKMTmtygS8BJLT3VPczAQofdqlFXDPkXdLMJN4r05+xqneG8snZJ0HgkERCZTg=="], "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], - "nypm/citty": ["citty@0.2.0", "", {}, "sha512-8csy5IBFI2ex2hTVpaHN2j+LNE199AgiI7y4dMintrr8i0lQiFn+0AWMZrWdHKIgMOer65f8IThysYhoReqjWA=="], - "nypm/tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], - "opencode/@ai-sdk/anthropic": ["@ai-sdk/anthropic@2.0.58", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-CkNW5L1Arv8gPtPlEmKd+yf/SG9ucJf0XQdpMG8OiYEtEMc2smuCA+tyCp8zI7IBVg/FE7nUfFHntQFaOjRwJQ=="], + "opencode/@ai-sdk/anthropic": ["@ai-sdk/anthropic@2.0.57", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-DREpYqW2pylgaj69gZ+K8u92bo9DaMgFdictYnY+IwYeY3bawQ4zI7l/o1VkDsBDljAx8iYz5lPURwVZNu+Xpg=="], "opencode/@ai-sdk/openai": ["@ai-sdk/openai@2.0.89", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-4+qWkBCbL9HPKbgrUO/F2uXZ8GqrYxHa8SWEYIzxEJ9zvWw3ISr3t1/27O1i8MGSym+PzEyHBT48EV4LAwWaEw=="], - "opencode/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.32", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-YspqqyJPzHjqWrjt4y/Wgc2aJgCcQj5uIJgZpq2Ar/lH30cEVhgE+keePDbjKpetD9UwNggCj7u6kO3unS23OQ=="], + "opencode/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.30", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-thubwhRtv9uicAxSWwNpinM7hiL/0CkhL/ymPaHuKvI494J7HIzn8KQZQ2ymRz284WTIZnI7VMyyejxW4RMM6w=="], "opencontrol/@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.6.1", "", { "dependencies": { "content-type": "^1.0.5", "cors": "^2.8.5", "eventsource": "^3.0.2", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^4.1.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" } }, "sha512-oxzMzYCkZHMntzuyerehK3fV6A2Kwh5BD6CGEJSVDU2QNEhfLOptf2X7esQgaHZXHZY0oHmMsOtIDLP71UJXgA=="], @@ -4401,6 +4461,8 @@ "openid-client/jose": ["jose@4.15.9", "", {}, "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA=="], + "openid-client/object-hash": ["object-hash@2.2.0", "", {}, "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw=="], + "p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], "parse-bmfont-xml/xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="], @@ -4409,7 +4471,7 @@ "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], - "path-scurry/lru-cache": ["lru-cache@11.2.5", "", {}, "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw=="], + "path-scurry/lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="], "pixelmatch/pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="], @@ -4417,8 +4479,6 @@ "playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], - "postcss-load-config/lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], - "prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], "raw-body/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], @@ -4437,15 +4497,19 @@ "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + "send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="], + "send/mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], "sharp/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "sharp/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], + "shiki/@shikijs/core": ["@shikijs/core@3.20.0", "", { "dependencies": { "@shikijs/types": "3.20.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-f2ED7HYV4JEk827mtMDwe/yQ25pRiXZmtHjWF8uzZKuKiEsJR7Ce1nuQ+HhV9FzDcbIo4ObBCD9GPTzNuy9S1g=="], "shiki/@shikijs/types": ["@shikijs/types@3.20.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw=="], - "sitemap/sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], + "sitemap/sax": ["sax@1.4.3", "", {}, "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ=="], "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], @@ -4479,6 +4543,8 @@ "utif2/pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], + "vite/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="], + "vitest/tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], "vitest/vite": ["vite@7.1.10", "", { "dependencies": { "esbuild": "^0.25.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-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA=="], @@ -4495,6 +4561,8 @@ "wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "xml2js/sax": ["sax@1.4.3", "", {}, "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ=="], + "yargs/yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], "zod-to-json-schema/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -4509,16 +4577,28 @@ "@actions/github/@octokit/plugin-rest-endpoint-methods/@octokit/types": ["@octokit/types@12.6.0", "", { "dependencies": { "@octokit/openapi-types": "^20.0.0" } }, "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw=="], - "@ai-sdk/anthropic/@ai-sdk/provider-utils/zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], + "@astrojs/cloudflare/vite/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="], + + "@astrojs/markdown-remark/shiki/@shikijs/core": ["@shikijs/core@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-8TOG6yG557q+fMsSVa8nkEDOZNTSxjbbR8l6lF2gyr6Np+jrPlslqDxQkN6rMXCECQ3isNPZAGszAfYoJOPGlg=="], + + "@astrojs/markdown-remark/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-ZedbOFpopibdLmvTz2sJPJgns8Xvyabe2QbmqMTz07kt1pTzfEvKZc5IqPVO/XFiEbbNyaOpjPBkkr1vlwS+qg=="], + + "@astrojs/markdown-remark/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-HnqFsV11skAHvOArMZdLBZZApRSYS4LSztk2K3016Y9VCyZISnlYUYsL2hzlS7tPqKHvNqmI5JSUJZprXloMvA=="], + + "@astrojs/markdown-remark/shiki/@shikijs/langs": ["@shikijs/langs@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0" } }, "sha512-WpRvEFvkVvO65uKYW4Rzxs+IG0gToyM8SARQMtGGsH4GDMNZrr60qdggXrFOsdfOVssG/QQGEl3FnJ3EZ+8w8A=="], - "@ai-sdk/openai-compatible/@ai-sdk/provider-utils/zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], + "@astrojs/markdown-remark/shiki/@shikijs/themes": ["@shikijs/themes@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0" } }, "sha512-8ow2zWb1IDvCKjYb0KiLNrK4offFdkfNVPXb1OZykpLCzRU6j+efkY+Y7VQjNlNFXonSw+4AOdGYtmqykDbRiQ=="], - "@ai-sdk/openai/@ai-sdk/provider-utils/zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], + "@astrojs/markdown-remark/shiki/@shikijs/types": ["@shikijs/types@3.15.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw=="], "@astrojs/mdx/@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.5", "", {}, "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA=="], "@astrojs/mdx/@astrojs/markdown-remark/@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="], + "@astrojs/mdx/@astrojs/markdown-remark/shiki": ["shiki@3.15.0", "", { "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" } }, "sha512-kLdkY6iV3dYbtPwS9KXU7mjfmDm25f5m0IPNFnaXO7TBPcvbUOY72PYXSuSqDzwp+vlH/d7MXpHlKO/x+QoLXw=="], + + "@astrojs/solid-js/vite/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="], + "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], @@ -4537,9 +4617,11 @@ "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.782.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/nested-clients": "3.782.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-xCna0opVPaueEbJoclj5C6OpDNi0Gynj+4d7tnuXGgQhTHPyAz8ZyClkVqpi5qvHTgxROdUEDxWqEO5jqRHZHQ=="], - "@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + "@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="], - "@azure/core-xml/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + "@azure/core-http/xml2js/sax": ["sax@1.4.3", "", {}, "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ=="], + + "@azure/core-xml/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="], "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], @@ -4587,6 +4669,18 @@ "@esbuild-kit/core-utils/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.18.20", "", { "os": "win32", "cpu": "x64" }, "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ=="], + "@expressive-code/plugin-shiki/shiki/@shikijs/core": ["@shikijs/core@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-8TOG6yG557q+fMsSVa8nkEDOZNTSxjbbR8l6lF2gyr6Np+jrPlslqDxQkN6rMXCECQ3isNPZAGszAfYoJOPGlg=="], + + "@expressive-code/plugin-shiki/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-ZedbOFpopibdLmvTz2sJPJgns8Xvyabe2QbmqMTz07kt1pTzfEvKZc5IqPVO/XFiEbbNyaOpjPBkkr1vlwS+qg=="], + + "@expressive-code/plugin-shiki/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-HnqFsV11skAHvOArMZdLBZZApRSYS4LSztk2K3016Y9VCyZISnlYUYsL2hzlS7tPqKHvNqmI5JSUJZprXloMvA=="], + + "@expressive-code/plugin-shiki/shiki/@shikijs/langs": ["@shikijs/langs@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0" } }, "sha512-WpRvEFvkVvO65uKYW4Rzxs+IG0gToyM8SARQMtGGsH4GDMNZrr60qdggXrFOsdfOVssG/QQGEl3FnJ3EZ+8w8A=="], + + "@expressive-code/plugin-shiki/shiki/@shikijs/themes": ["@shikijs/themes@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0" } }, "sha512-8ow2zWb1IDvCKjYb0KiLNrK4offFdkfNVPXb1OZykpLCzRU6j+efkY+Y7VQjNlNFXonSw+4AOdGYtmqykDbRiQ=="], + + "@expressive-code/plugin-shiki/shiki/@shikijs/types": ["@shikijs/types@3.15.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw=="], + "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], "@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], @@ -4639,11 +4733,9 @@ "@jsx-email/cli/tailwindcss/chokidar": ["chokidar@3.6.0", "", { "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=="], - "@jsx-email/cli/tailwindcss/glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], - "@jsx-email/cli/tailwindcss/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], - "@jsx-email/cli/tailwindcss/object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], + "@jsx-email/cli/tailwindcss/lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="], "@jsx-email/cli/vite/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], @@ -4651,7 +4743,7 @@ "@modelcontextprotocol/sdk/express/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], - "@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.2", "", { "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=="], + "@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="], "@modelcontextprotocol/sdk/express/content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="], @@ -4659,18 +4751,24 @@ "@modelcontextprotocol/sdk/express/cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], - "@modelcontextprotocol/sdk/express/finalhandler": ["finalhandler@2.1.1", "", { "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=="], + "@modelcontextprotocol/sdk/express/finalhandler": ["finalhandler@2.1.0", "", { "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-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q=="], "@modelcontextprotocol/sdk/express/fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], + "@modelcontextprotocol/sdk/express/http-errors": ["http-errors@2.0.1", "", { "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=="], + "@modelcontextprotocol/sdk/express/merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], - "@modelcontextprotocol/sdk/express/send": ["send@1.2.1", "", { "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=="], + "@modelcontextprotocol/sdk/express/send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], + + "@modelcontextprotocol/sdk/express/serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="], - "@modelcontextprotocol/sdk/express/serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], + "@modelcontextprotocol/sdk/express/statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], "@modelcontextprotocol/sdk/express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], + "@modelcontextprotocol/sdk/raw-body/http-errors": ["http-errors@2.0.1", "", { "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=="], + "@octokit/auth-app/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="], "@octokit/auth-app/@octokit/request/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], @@ -4783,12 +4881,66 @@ "@pierre/diffs/shiki/@shikijs/types": ["@shikijs/types@3.19.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ=="], + "@prokube/app-prefixable/tailwindcss/chokidar": ["chokidar@3.6.0", "", { "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=="], + + "@prokube/app-prefixable/tailwindcss/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], + "@slack/web-api/form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], "@slack/web-api/p-queue/eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="], "@slack/web-api/p-queue/p-timeout": ["p-timeout@3.2.0", "", { "dependencies": { "p-finally": "^1.0.0" } }, "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg=="], + "@solidjs/start/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + + "@solidjs/start/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + + "@solidjs/start/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + + "@solidjs/start/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + + "@solidjs/start/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + + "@solidjs/start/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + + "@solidjs/start/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + + "@solidjs/start/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + + "@solidjs/start/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + + "@solidjs/start/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + + "@solidjs/start/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + + "@solidjs/start/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + + "@solidjs/start/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + + "@solidjs/start/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + + "@solidjs/start/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + + "@solidjs/start/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + + "@solidjs/start/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + + "@solidjs/start/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + + "@solidjs/start/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + + "@solidjs/start/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + + "@solidjs/start/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + + "@solidjs/start/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + + "@solidjs/start/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + + "@solidjs/start/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + + "@solidjs/start/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "@solidjs/start/shiki/@shikijs/core": ["@shikijs/core@1.29.2", "", { "dependencies": { "@shikijs/engine-javascript": "1.29.2", "@shikijs/engine-oniguruma": "1.29.2", "@shikijs/types": "1.29.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ=="], "@solidjs/start/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@1.29.2", "", { "dependencies": { "@shikijs/types": "1.29.2", "@shikijs/vscode-textmate": "^10.0.1", "oniguruma-to-es": "^2.2.0" } }, "sha512-iNEZv4IrLYPv64Q6k7EPpOCE/nuvGiKl7zxdq0WFuRPF5PAE9PRo2JGq/d8crLusM59BRemJ4eOqrFrC4wiQ+A=="], @@ -4815,11 +4967,71 @@ "archiver-utils/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - "astro/unstorage/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + "astro/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], + + "astro/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], + + "astro/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.4", "", { "os": "android", "cpu": "arm64" }, "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A=="], + + "astro/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.4", "", { "os": "android", "cpu": "x64" }, "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ=="], + + "astro/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g=="], + + "astro/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A=="], + + "astro/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ=="], + + "astro/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ=="], + + "astro/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.4", "", { "os": "linux", "cpu": "arm" }, "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ=="], + + "astro/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ=="], + + "astro/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ=="], + + "astro/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA=="], + + "astro/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg=="], + + "astro/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag=="], + + "astro/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA=="], + + "astro/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g=="], + + "astro/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.4", "", { "os": "linux", "cpu": "x64" }, "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA=="], + + "astro/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.4", "", { "os": "none", "cpu": "arm64" }, "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ=="], + + "astro/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.4", "", { "os": "none", "cpu": "x64" }, "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw=="], + + "astro/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A=="], + + "astro/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw=="], + + "astro/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q=="], + + "astro/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ=="], + + "astro/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg=="], + + "astro/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.4", "", { "os": "win32", "cpu": "x64" }, "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ=="], - "astro/unstorage/h3": ["h3@1.15.5", "", { "dependencies": { "cookie-es": "^1.2.2", "crossws": "^0.3.5", "defu": "^6.1.4", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.4", "radix3": "^1.1.2", "ufo": "^1.6.3", "uncrypto": "^0.1.3" } }, "sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg=="], + "astro/shiki/@shikijs/core": ["@shikijs/core@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-8TOG6yG557q+fMsSVa8nkEDOZNTSxjbbR8l6lF2gyr6Np+jrPlslqDxQkN6rMXCECQ3isNPZAGszAfYoJOPGlg=="], - "astro/unstorage/lru-cache": ["lru-cache@11.2.5", "", {}, "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw=="], + "astro/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-ZedbOFpopibdLmvTz2sJPJgns8Xvyabe2QbmqMTz07kt1pTzfEvKZc5IqPVO/XFiEbbNyaOpjPBkkr1vlwS+qg=="], + + "astro/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-HnqFsV11skAHvOArMZdLBZZApRSYS4LSztk2K3016Y9VCyZISnlYUYsL2hzlS7tPqKHvNqmI5JSUJZprXloMvA=="], + + "astro/shiki/@shikijs/langs": ["@shikijs/langs@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0" } }, "sha512-WpRvEFvkVvO65uKYW4Rzxs+IG0gToyM8SARQMtGGsH4GDMNZrr60qdggXrFOsdfOVssG/QQGEl3FnJ3EZ+8w8A=="], + + "astro/shiki/@shikijs/themes": ["@shikijs/themes@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0" } }, "sha512-8ow2zWb1IDvCKjYb0KiLNrK4offFdkfNVPXb1OZykpLCzRU6j+efkY+Y7VQjNlNFXonSw+4AOdGYtmqykDbRiQ=="], + + "astro/shiki/@shikijs/types": ["@shikijs/types@3.15.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw=="], + + "astro/unstorage/h3": ["h3@1.15.4", "", { "dependencies": { "cookie-es": "^1.2.2", "crossws": "^0.3.5", "defu": "^6.1.4", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.2", "radix3": "^1.1.2", "ufo": "^1.6.1", "uncrypto": "^0.1.3" } }, "sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ=="], + + "astro/unstorage/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "astro/unstorage/ofetch": ["ofetch@1.5.1", "", { "dependencies": { "destr": "^2.0.5", "node-fetch-native": "^1.6.7", "ufo": "^1.6.1" } }, "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA=="], @@ -4881,6 +5093,8 @@ "drizzle-kit/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.19.12", "", { "os": "win32", "cpu": "x64" }, "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA=="], + "esbuild-plugin-copy/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "esbuild-plugin-copy/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], "express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], @@ -4897,11 +5111,13 @@ "js-beautify/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + "jsonwebtoken/jws/jwa": ["jwa@1.4.2", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw=="], + "lazystream/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], - "opencontrol/@modelcontextprotocol/sdk/express": ["express@5.2.1", "", { "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=="], + "opencontrol/@modelcontextprotocol/sdk/express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.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-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="], "opencontrol/@modelcontextprotocol/sdk/pkce-challenge": ["pkce-challenge@4.1.0", "", {}, "sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ=="], @@ -4909,7 +5125,9 @@ "opencontrol/@modelcontextprotocol/sdk/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "opencontrol/@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], + "opencontrol/@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.24.5", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g=="], + + "parse-bmfont-xml/xml2js/sax": ["sax@1.4.3", "", {}, "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ=="], "pkg-up/find-up/locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="], @@ -4927,16 +5145,66 @@ "tw-to-css/tailwindcss/chokidar": ["chokidar@3.6.0", "", { "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=="], - "tw-to-css/tailwindcss/glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], - "tw-to-css/tailwindcss/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], - "tw-to-css/tailwindcss/object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], + "tw-to-css/tailwindcss/lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="], "tw-to-css/tailwindcss/postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], "type-is/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], + + "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], + + "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.4", "", { "os": "android", "cpu": "arm64" }, "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A=="], + + "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.4", "", { "os": "android", "cpu": "x64" }, "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ=="], + + "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g=="], + + "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A=="], + + "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ=="], + + "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ=="], + + "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.4", "", { "os": "linux", "cpu": "arm" }, "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ=="], + + "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ=="], + + "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ=="], + + "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA=="], + + "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg=="], + + "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag=="], + + "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA=="], + + "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g=="], + + "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.4", "", { "os": "linux", "cpu": "x64" }, "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA=="], + + "vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.4", "", { "os": "none", "cpu": "arm64" }, "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ=="], + + "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.4", "", { "os": "none", "cpu": "x64" }, "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw=="], + + "vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A=="], + + "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw=="], + + "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q=="], + + "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ=="], + + "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg=="], + + "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.4", "", { "os": "win32", "cpu": "x64" }, "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ=="], + + "vitest/vite/esbuild": ["esbuild@0.25.12", "", { "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=="], + "wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], "wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], @@ -4997,6 +5265,118 @@ "@actions/github/@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@20.0.0", "", {}, "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="], + "@astrojs/cloudflare/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.4", "", { "os": "android", "cpu": "arm64" }, "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.4", "", { "os": "android", "cpu": "x64" }, "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.4", "", { "os": "linux", "cpu": "arm" }, "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.4", "", { "os": "linux", "cpu": "x64" }, "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.4", "", { "os": "none", "cpu": "arm64" }, "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.4", "", { "os": "none", "cpu": "x64" }, "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg=="], + + "@astrojs/cloudflare/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.4", "", { "os": "win32", "cpu": "x64" }, "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ=="], + + "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/core": ["@shikijs/core@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-8TOG6yG557q+fMsSVa8nkEDOZNTSxjbbR8l6lF2gyr6Np+jrPlslqDxQkN6rMXCECQ3isNPZAGszAfYoJOPGlg=="], + + "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-ZedbOFpopibdLmvTz2sJPJgns8Xvyabe2QbmqMTz07kt1pTzfEvKZc5IqPVO/XFiEbbNyaOpjPBkkr1vlwS+qg=="], + + "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-HnqFsV11skAHvOArMZdLBZZApRSYS4LSztk2K3016Y9VCyZISnlYUYsL2hzlS7tPqKHvNqmI5JSUJZprXloMvA=="], + + "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/langs": ["@shikijs/langs@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0" } }, "sha512-WpRvEFvkVvO65uKYW4Rzxs+IG0gToyM8SARQMtGGsH4GDMNZrr60qdggXrFOsdfOVssG/QQGEl3FnJ3EZ+8w8A=="], + + "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/themes": ["@shikijs/themes@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0" } }, "sha512-8ow2zWb1IDvCKjYb0KiLNrK4offFdkfNVPXb1OZykpLCzRU6j+efkY+Y7VQjNlNFXonSw+4AOdGYtmqykDbRiQ=="], + + "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/types": ["@shikijs/types@3.15.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.4", "", { "os": "android", "cpu": "arm64" }, "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.4", "", { "os": "android", "cpu": "x64" }, "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.4", "", { "os": "linux", "cpu": "arm" }, "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.4", "", { "os": "linux", "cpu": "x64" }, "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.4", "", { "os": "none", "cpu": "arm64" }, "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.4", "", { "os": "none", "cpu": "x64" }, "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg=="], + + "@astrojs/solid-js/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.4", "", { "os": "win32", "cpu": "x64" }, "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ=="], + "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], @@ -5061,8 +5441,12 @@ "@modelcontextprotocol/sdk/express/accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + "@modelcontextprotocol/sdk/express/body-parser/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "@modelcontextprotocol/sdk/express/type-is/media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], + "@modelcontextprotocol/sdk/raw-body/http-errors/statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + "@octokit/auth-app/@octokit/request-error/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], "@octokit/auth-app/@octokit/request/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], @@ -5083,6 +5467,10 @@ "@opencode-ai/desktop/@actions/artifact/@actions/http-client/undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="], + "@prokube/app-prefixable/tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "@prokube/app-prefixable/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + "@slack/web-api/form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], "@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es": ["oniguruma-to-es@2.3.0", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^5.1.1", "regex-recursion": "^5.1.1" } }, "sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g=="], @@ -5091,8 +5479,6 @@ "archiver-utils/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "astro/unstorage/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], - "astro/unstorage/h3/cookie-es": ["cookie-es@1.2.2", "", {}, "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg=="], "astro/unstorage/h3/crossws": ["crossws@0.3.5", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA=="], @@ -5107,7 +5493,7 @@ "opencontrol/@modelcontextprotocol/sdk/express/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], - "opencontrol/@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.2", "", { "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=="], + "opencontrol/@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="], "opencontrol/@modelcontextprotocol/sdk/express/content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="], @@ -5115,18 +5501,24 @@ "opencontrol/@modelcontextprotocol/sdk/express/cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], - "opencontrol/@modelcontextprotocol/sdk/express/finalhandler": ["finalhandler@2.1.1", "", { "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=="], + "opencontrol/@modelcontextprotocol/sdk/express/finalhandler": ["finalhandler@2.1.0", "", { "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-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q=="], "opencontrol/@modelcontextprotocol/sdk/express/fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], + "opencontrol/@modelcontextprotocol/sdk/express/http-errors": ["http-errors@2.0.1", "", { "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=="], + "opencontrol/@modelcontextprotocol/sdk/express/merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], - "opencontrol/@modelcontextprotocol/sdk/express/send": ["send@1.2.1", "", { "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=="], + "opencontrol/@modelcontextprotocol/sdk/express/send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], - "opencontrol/@modelcontextprotocol/sdk/express/serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], + "opencontrol/@modelcontextprotocol/sdk/express/serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="], + + "opencontrol/@modelcontextprotocol/sdk/express/statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], "opencontrol/@modelcontextprotocol/sdk/express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], + "opencontrol/@modelcontextprotocol/sdk/raw-body/http-errors": ["http-errors@2.0.1", "", { "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=="], + "pkg-up/find-up/locate-path/p-locate": ["p-locate@3.0.0", "", { "dependencies": { "p-limit": "^2.0.0" } }, "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="], "pkg-up/find-up/locate-path/path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="], @@ -5137,18 +5529,74 @@ "tw-to-css/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + "vitest/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + + "vitest/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + + "vitest/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + + "vitest/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + + "vitest/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + + "vitest/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + + "vitest/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + + "vitest/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + + "vitest/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + + "vitest/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + + "vitest/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + + "vitest/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + + "vitest/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + + "vitest/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + + "vitest/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + + "vitest/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + + "vitest/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + + "vitest/vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + + "vitest/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + + "vitest/vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + + "vitest/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + + "vitest/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + + "vitest/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + + "vitest/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + + "vitest/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.782.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/middleware-host-header": "3.775.0", "@aws-sdk/middleware-logger": "3.775.0", "@aws-sdk/middleware-recursion-detection": "3.775.0", "@aws-sdk/middleware-user-agent": "3.782.0", "@aws-sdk/region-config-resolver": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.782.0", "@aws-sdk/util-user-agent-browser": "3.775.0", "@aws-sdk/util-user-agent-node": "3.782.0", "@smithy/config-resolver": "^4.1.0", "@smithy/core": "^3.2.0", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/hash-node": "^4.0.2", "@smithy/invalid-dependency": "^4.0.2", "@smithy/middleware-content-length": "^4.0.2", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/middleware-retry": "^4.1.0", "@smithy/middleware-serde": "^4.0.3", "@smithy/middleware-stack": "^4.0.2", "@smithy/node-config-provider": "^4.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.8", "@smithy/util-defaults-mode-node": "^4.0.8", "@smithy/util-endpoints": "^3.0.2", "@smithy/util-middleware": "^4.0.2", "@smithy/util-retry": "^4.0.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-QOYC8q7luzHFXrP0xYAqBctoPkynjfV0r9dqntFu4/IWMTyC1vlo1UTxFAjIPyclYw92XJyEkVCVg9v/nQnsUA=="], "@jsx-email/cli/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "@prokube/app-prefixable/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es/regex": ["regex@5.1.1", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw=="], "@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es/regex-recursion": ["regex-recursion@5.1.1", "", { "dependencies": { "regex": "^5.1.1", "regex-utilities": "^2.3.0" } }, "sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w=="], "opencontrol/@modelcontextprotocol/sdk/express/accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + "opencontrol/@modelcontextprotocol/sdk/express/body-parser/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "opencontrol/@modelcontextprotocol/sdk/express/type-is/media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], + "opencontrol/@modelcontextprotocol/sdk/raw-body/http-errors/statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + "pkg-up/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], "tw-to-css/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], diff --git a/package.json b/package.json index e1471d356ac..26862d9d4f8 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "packages/*", "packages/console/*", "packages/sdk/js", - "packages/slack" + "packages/slack", + "prokube/*" ], "catalog": { "@types/bun": "1.3.5", diff --git a/prokube/app-prefixable/AGENTS.md b/prokube/app-prefixable/AGENTS.md new file mode 100644 index 00000000000..4008a5c1540 --- /dev/null +++ b/prokube/app-prefixable/AGENTS.md @@ -0,0 +1,69 @@ +# Prefix-Aware Web UI for OpenCode + +## Quick Start + +### 1. Start the Backend (API Server) + +```bash +cd /Users/henrik/local-repos/prokube/opencode/packages/opencode +bun run src/index.ts serve +``` + +This starts the headless API server on `http://localhost:4096`. + +**Note:** `bun dev` starts the CLI/TUI, not the API server. + +### 2. Start the Frontend (Dev Server) + +```bash +cd /Users/henrik/local-repos/prokube/opencode/prokube/app-prefixable +bun run dev +``` + +Opens at `http://localhost:3000/` + +#### With URL Prefix + +```bash +BASE_PATH=/opencode/ bun run dev +``` + +Opens at `http://localhost:3000/opencode/` + +### 3. Build for Production + +```bash +bun run build +``` + +Output in `./dist/` - can be deployed under any prefix without rebuilding. + +## Architecture + +- **esbuild + esbuild-plugin-solid** for bundling +- **TailwindCSS 3.x** with ProKube `pk-*` component classes +- **Runtime prefix detection** via `window.__OPENCODE__.basePath` +- **SolidJS Router** with dynamic base path + +## Key Files + +| File | Purpose | +| --------------------------- | ----------------------------------- | +| `dev.ts` | Dev server with prefix injection | +| `build.ts` | esbuild + PostCSS build | +| `src/context/base-path.tsx` | Base path context provider | +| `src/utils/path.ts` | Path utilities and prefix detection | + +## Environment Variables + +| Variable | Default | Description | +| ----------- | ----------------------- | ---------------------- | +| `BASE_PATH` | `/` | URL prefix for the app | +| `PORT` | `3000` | Dev server port | +| `API_URL` | `http://localhost:4096` | Backend API URL | + +## Routing Notes + +- SolidJS Router handles the base path automatically +- Use plain paths in `` - no manual prefixing needed +- The router base is set from `window.__OPENCODE__.basePath` diff --git a/prokube/app-prefixable/build.ts b/prokube/app-prefixable/build.ts new file mode 100644 index 00000000000..fe58f0d2908 --- /dev/null +++ b/prokube/app-prefixable/build.ts @@ -0,0 +1,50 @@ +import esbuild from "esbuild" +import { solidPlugin } from "esbuild-plugin-solid" +import postcss from "postcss" +import tailwindcss from "tailwindcss" +import autoprefixer from "autoprefixer" + +console.log("Building for runtime prefix detection...") + +// Build CSS with Tailwind +console.log("Building CSS...") +const cssSource = await Bun.file("./src/index.css").text() +const cssResult = await postcss([tailwindcss("./tailwind.config.js"), autoprefixer()]).process(cssSource, { + from: "./src/index.css", + to: "./dist/styles.css", +}) +await Bun.write("./dist/styles.css", cssResult.css) +console.log("CSS built") + +// Build JS with esbuild +// Use relative paths (./) so assets work with any prefix at runtime +console.log("Building JS...") +const result = await esbuild.build({ + entryPoints: ["./src/entry.tsx"], + outdir: "./dist", + publicPath: "./", // Relative paths - works with any prefix! + bundle: true, + minify: process.env.NODE_ENV === "production", + splitting: true, + format: "esm", + sourcemap: true, + target: "esnext", + plugins: [solidPlugin()], + metafile: true, +}) + +console.log(`JS build completed: ${Object.keys(result.metafile?.outputs || {}).length} files`) + +// Copy index.html to dist +const html = await Bun.file("./src/index.html").text() +await Bun.write("./dist/index.html", html) + +// Copy public assets if they exist +try { + const { $ } = await import("bun") + await $`cp -r ./public/* ./dist/ 2>/dev/null`.quiet() +} catch { + // public folder may be empty, ignore +} + +console.log("Done!") diff --git a/prokube/app-prefixable/dev.ts b/prokube/app-prefixable/dev.ts new file mode 100644 index 00000000000..a45c0a9faf0 --- /dev/null +++ b/prokube/app-prefixable/dev.ts @@ -0,0 +1,163 @@ +import { watch } from "fs" + +const BASE_PATH = process.env.BASE_PATH || "/" +const PORT = parseInt(process.env.PORT || "3000", 10) +const API_URL = process.env.API_URL || "http://127.0.0.1:4096" + +console.log(`Starting dev server...`) +console.log(` BASE_PATH: ${BASE_PATH}`) +console.log(` API_URL: ${API_URL}`) +console.log(` PORT: ${PORT}`) + +// Initial build +await import("./build") + +// Normalize base path for matching +const basePathWithoutTrailing = BASE_PATH.endsWith("/") ? BASE_PATH.slice(0, -1) : BASE_PATH +const basePathWithTrailing = BASE_PATH.endsWith("/") ? BASE_PATH : BASE_PATH + "/" + +const server = Bun.serve({ + port: PORT, + async fetch(req) { + const url = new URL(req.url) + let path = url.pathname + + // Proxy API requests to the OpenCode server + // These paths match the OpenCode API endpoints + const apiPaths = [ + "/api/", + "/event", + "/session", + "/config", + "/provider", + "/project", + "/permission", + "/pty", + "/mcp", + "/file", + "/health", + "/path", + "/command", + ] + const isApiRequest = apiPaths.some((p) => path === p || path.startsWith(p + "/") || path.startsWith(p + "?")) + + if (isApiRequest) { + const target = new URL(path + url.search, API_URL) + const headers = new Headers(req.headers) + + // SSE requests need special handling - stream responses properly + if (path.startsWith("/event")) { + console.log("[Proxy] SSE request to:", target.toString()) + const response = await fetch(target.toString(), { + method: req.method, + headers, + }) + + if (!response.ok) { + console.error("[Proxy] SSE error:", response.status, response.statusText) + return new Response(response.body, { status: response.status }) + } + + // Create a transform stream to pass through SSE data + const { readable, writable } = new TransformStream() + const writer = writable.getWriter() + const reader = response.body?.getReader() + + if (reader) { + ;(async () => { + try { + while (true) { + const { done, value } = await reader.read() + if (done) break + await writer.write(value) + } + } catch (e) { + console.error("[Proxy] SSE stream error:", e) + } finally { + writer.close() + } + })() + } + + return new Response(readable, { + status: response.status, + headers: { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + Connection: "keep-alive", + "X-Accel-Buffering": "no", + }, + }) + } + + return fetch(target.toString(), { + method: req.method, + headers, + body: req.body, + }) + } + + // Strip base path prefix for file lookup + if (basePathWithoutTrailing && path.startsWith(basePathWithoutTrailing)) { + path = path.slice(basePathWithoutTrailing.length) || "/" + } + + // Ensure path starts with / + if (!path.startsWith("/")) { + path = "/" + path + } + + // Try to serve static file + const filePath = `./dist${path}` + const file = Bun.file(filePath) + if (await file.exists()) { + const ext = path.split(".").pop() || "" + const mimeTypes: Record = { + js: "application/javascript", + css: "text/css", + html: "text/html", + json: "application/json", + svg: "image/svg+xml", + png: "image/png", + jpg: "image/jpeg", + ico: "image/x-icon", + woff: "font/woff", + woff2: "font/woff2", + ttf: "font/ttf", + } + return new Response(file, { + headers: { "Content-Type": mimeTypes[ext] || "application/octet-stream" }, + }) + } + + // SPA fallback - serve index.html with injected base path + const indexHtml = await Bun.file("./dist/index.html").text() + const injected = indexHtml + .replace('', ``) + .replace( + "window.__OPENCODE__ = window.__OPENCODE__ || {}", + `window.__OPENCODE__ = { basePath: "${basePathWithTrailing}" }`, + ) + return new Response(injected, { + headers: { "Content-Type": "text/html" }, + }) + }, +}) + +console.log(`\nDev server running at http://localhost:${PORT}${basePathWithTrailing}`) + +// Watch for changes and rebuild +let debounce: Timer | null = null +watch("./src", { recursive: true }, async (event, filename) => { + if (debounce) clearTimeout(debounce) + debounce = setTimeout(async () => { + console.log(`\nFile changed: ${filename}`) + console.log("Rebuilding...") + try { + // Re-import build to trigger rebuild + const mod = await import(`./build?t=${Date.now()}`) + } catch (e) { + console.error("Build error:", e) + } + }, 100) +}) diff --git a/prokube/app-prefixable/package.json b/prokube/app-prefixable/package.json new file mode 100644 index 00000000000..674e5d02d81 --- /dev/null +++ b/prokube/app-prefixable/package.json @@ -0,0 +1,33 @@ +{ + "name": "@prokube/app-prefixable", + "version": "0.0.1", + "description": "Prefix-aware Web UI for OpenCode", + "type": "module", + "scripts": { + "dev": "bun run dev.ts", + "build": "bun run build.ts", + "typecheck": "tsc --noEmit" + }, + "license": "MIT", + "dependencies": { + "@opencode-ai/sdk": "workspace:*", + "@opencode-ai/ui": "workspace:*", + "@opencode-ai/util": "workspace:*", + "@solidjs/router": "catalog:", + "marked": "catalog:", + "solid-js": "catalog:" + }, + "devDependencies": { + "@types/bun": "catalog:", + "autoprefixer": "^10.4.20", + "esbuild": "0.25.5", + "esbuild-plugin-solid": "0.6.0", + "postcss": "^8.5.6", + "tailwindcss": "^3.4.17", + "typescript": "catalog:" + }, + "peerDependencies": { + "@opencode-ai/ui": ">=1.1.0", + "@opencode-ai/sdk": ">=1.1.0" + } +} diff --git a/prokube/app-prefixable/postcss.config.js b/prokube/app-prefixable/postcss.config.js new file mode 100644 index 00000000000..2e7af2b7f1a --- /dev/null +++ b/prokube/app-prefixable/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/prokube/app-prefixable/src/app.tsx b/prokube/app-prefixable/src/app.tsx new file mode 100644 index 00000000000..a93b44ae856 --- /dev/null +++ b/prokube/app-prefixable/src/app.tsx @@ -0,0 +1,31 @@ +import { Router, Route } from "@solidjs/router" +import { BasePathProvider, useBasePath } from "./context/base-path" +import { SDKProvider } from "./context/sdk" +import { EventProvider } from "./context/events" +import { Home } from "./pages/home" +import { Session } from "./pages/session" +import { Layout } from "./pages/layout" + +function AppRoutes() { + const { basePath } = useBasePath() + const base = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath + + return ( + + + + + ) +} + +export function App() { + return ( + + + + + + + + ) +} diff --git a/prokube/app-prefixable/src/components/markdown.tsx b/prokube/app-prefixable/src/components/markdown.tsx new file mode 100644 index 00000000000..25dffa34a6d --- /dev/null +++ b/prokube/app-prefixable/src/components/markdown.tsx @@ -0,0 +1,22 @@ +import { createMemo } from "solid-js" +import { marked } from "marked" + +// Configure marked for safe rendering +marked.setOptions({ + gfm: true, + breaks: true, +}) + +interface MarkdownProps { + content: string + class?: string +} + +export function Markdown(props: MarkdownProps) { + const html = createMemo(() => { + if (!props.content) return "" + return marked.parse(props.content, { async: false }) as string + }) + + return
+} diff --git a/prokube/app-prefixable/src/context/base-path.tsx b/prokube/app-prefixable/src/context/base-path.tsx new file mode 100644 index 00000000000..d165c9209d0 --- /dev/null +++ b/prokube/app-prefixable/src/context/base-path.tsx @@ -0,0 +1,28 @@ +import { createContext, useContext, type ParentProps } from "solid-js" +import { getBasePath, prefixPath, getServerUrl } from "../utils/path" + +interface BasePathContextValue { + basePath: string + prefix: (path: string) => string + serverUrl: string +} + +const BasePathContext = createContext() + +export function BasePathProvider(props: ParentProps & { serverUrl?: string }) { + const basePath = getBasePath() + + const value: BasePathContextValue = { + basePath, + prefix: (path: string) => prefixPath(path, basePath), + serverUrl: props.serverUrl || getServerUrl(), + } + + return {props.children} +} + +export function useBasePath() { + const ctx = useContext(BasePathContext) + if (!ctx) throw new Error("useBasePath must be used within BasePathProvider") + return ctx +} diff --git a/prokube/app-prefixable/src/context/events.tsx b/prokube/app-prefixable/src/context/events.tsx new file mode 100644 index 00000000000..ea4d4d8adfe --- /dev/null +++ b/prokube/app-prefixable/src/context/events.tsx @@ -0,0 +1,89 @@ +import { createContext, useContext, onCleanup, type ParentProps } from "solid-js" +import { createStore } from "solid-js/store" +import type { Event, SessionStatus } from "@opencode-ai/sdk/v2/client" + +type EventHandler = (event: Event) => void + +interface EventContextValue { + subscribe: (handler: EventHandler) => () => void + status: Record +} + +const EventContext = createContext() + +export function EventProvider(props: ParentProps) { + const handlers = new Set() + const [status, setStatus] = createStore>({}) + + // Connect to SSE endpoint - use relative URL so it goes through the proxy + let eventSource: EventSource | null = null + let reconnectTimer: ReturnType | null = null + + function connect() { + if (eventSource) return + + // Use relative path - the dev server will proxy this + eventSource = new EventSource("/event") + console.log("[Events] Connecting to SSE...") + + eventSource.onopen = () => { + console.log("[Events] Connected") + } + + eventSource.onmessage = (e) => { + try { + const wrapper = JSON.parse(e.data) as { directory?: string; payload: Event } + const event = wrapper.payload + console.log("[Events] Received:", event.type) + + // Update session status + if (event.type === "session.status") { + const sessionID = event.properties.sessionID + setStatus(sessionID, event.properties.status) + } + + // Notify all handlers + for (const handler of handlers) { + handler(event) + } + } catch (err) { + console.error("[Events] Parse error:", err) + } + } + + eventSource.onerror = (e) => { + console.error("[Events] Connection error, reconnecting...", e) + eventSource?.close() + eventSource = null + + // Reconnect after delay + if (!reconnectTimer) { + reconnectTimer = setTimeout(() => { + reconnectTimer = null + connect() + }, 3000) + } + } + } + + // Start connection + connect() + + onCleanup(() => { + eventSource?.close() + if (reconnectTimer) clearTimeout(reconnectTimer) + }) + + function subscribe(handler: EventHandler) { + handlers.add(handler) + return () => handlers.delete(handler) + } + + return {props.children} +} + +export function useEvents() { + const ctx = useContext(EventContext) + if (!ctx) throw new Error("useEvents must be used within EventProvider") + return ctx +} diff --git a/prokube/app-prefixable/src/context/sdk.tsx b/prokube/app-prefixable/src/context/sdk.tsx new file mode 100644 index 00000000000..481ec5504ed --- /dev/null +++ b/prokube/app-prefixable/src/context/sdk.tsx @@ -0,0 +1,30 @@ +import { createContext, useContext, type ParentProps } from "solid-js" +import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" +import { useBasePath } from "./base-path" + +type SDKClient = ReturnType + +interface SDKContextValue { + client: SDKClient + url: string +} + +const SDKContext = createContext() + +export function SDKProvider(props: ParentProps & { directory?: string }) { + const { serverUrl } = useBasePath() + + const client = createOpencodeClient({ + baseUrl: serverUrl, + directory: props.directory, + throwOnError: true, + }) + + return {props.children} +} + +export function useSDK() { + const ctx = useContext(SDKContext) + if (!ctx) throw new Error("useSDK must be used within SDKProvider") + return ctx +} diff --git a/prokube/app-prefixable/src/entry.tsx b/prokube/app-prefixable/src/entry.tsx new file mode 100644 index 00000000000..f2b688a29e9 --- /dev/null +++ b/prokube/app-prefixable/src/entry.tsx @@ -0,0 +1,24 @@ +/* @refresh reload */ +import { render } from "solid-js/web" +import { App } from "./app" + +console.log("[OpenCode] Starting app...") + +const root = document.getElementById("root") + +if (!root) { + throw new Error("Root element not found") +} + +// Clear the loading text first +root.innerHTML = "" + +try { + console.log("[OpenCode] Rendering...") + render(() => , root) + console.log("[OpenCode] Rendered successfully") + console.log("[OpenCode] Root innerHTML:", root.innerHTML.slice(0, 200)) +} catch (e) { + console.error("[OpenCode] Render error:", e) + root.innerHTML = `
Error: ${e}
` +} diff --git a/prokube/app-prefixable/src/index.css b/prokube/app-prefixable/src/index.css new file mode 100644 index 00000000000..65040272206 --- /dev/null +++ b/prokube/app-prefixable/src/index.css @@ -0,0 +1,341 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/** + * OpenCode ProKube UI Component Styles + * + * Basiert auf dem pkui Design-System + */ + +@layer components { + /* ============================================ + BUTTONS + ============================================ */ + + .pk-button { + @apply inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium; + @apply transition-colors; + @apply focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-500 focus-visible:ring-offset-2; + @apply disabled:pointer-events-none disabled:opacity-50; + @apply h-10 px-4 py-2; + } + + .pk-button-primary { + @apply pk-button bg-purple-600 text-white hover:bg-purple-700; + } + + .pk-button-outline { + @apply pk-button border border-gray-300 bg-white hover:bg-gray-50 hover:text-gray-900; + } + + .pk-button-destructive { + @apply pk-button text-red-600 hover:text-red-700 hover:border-red-300; + } + + .pk-button-ghost { + @apply pk-button hover:bg-gray-100; + } + + .pk-button-sm { + @apply h-9 rounded-md px-3 text-sm; + } + + .pk-button-lg { + @apply h-11 rounded-md px-8 text-base; + } + + /* ============================================ + CARDS + ============================================ */ + + .pk-card { + @apply bg-white rounded-xl shadow-sm border; + } + + .pk-card-header { + @apply p-6 border-b; + } + + .pk-card-title { + @apply text-lg font-semibold text-gray-900; + } + + .pk-card-content { + @apply p-6; + } + + /* ============================================ + FORMS + ============================================ */ + + .pk-label { + @apply block text-sm font-medium text-gray-700 mb-2; + } + + .pk-input { + @apply w-full px-3 py-2 border border-gray-300 rounded-md; + @apply focus:ring-purple-500 focus:border-purple-500 focus:outline-none; + @apply disabled:bg-gray-50 disabled:text-gray-500; + } + + .pk-textarea { + @apply pk-input resize-none; + } + + .pk-help-text { + @apply text-xs text-gray-500 mt-1; + } + + /* ============================================ + STATUS BADGES + ============================================ */ + + .pk-badge { + @apply px-2 py-1 text-xs font-medium rounded-full; + } + + .pk-badge-success { + @apply pk-badge bg-green-100 text-green-800; + } + + .pk-badge-warning { + @apply pk-badge bg-yellow-100 text-yellow-800; + } + + .pk-badge-error { + @apply pk-badge bg-red-100 text-red-800; + } + + .pk-badge-info { + @apply pk-badge bg-blue-100 text-blue-800; + } + + .pk-badge-neutral { + @apply pk-badge bg-gray-100 text-gray-800; + } + + /* ============================================ + LAYOUT + ============================================ */ + + .pk-page { + @apply min-h-screen bg-gray-50; + } + + .pk-page-content { + @apply p-8 max-w-7xl mx-auto; + } + + .pk-section-spacing { + @apply space-y-6; + } + + .pk-header { + @apply bg-white border-b border-gray-200 px-6 py-4; + } + + .pk-header-title { + @apply text-xl font-semibold text-gray-900; + } + + /* ============================================ + CHAT / SESSION SPECIFIC + ============================================ */ + + .pk-chat-container { + @apply flex flex-col h-[calc(100vh-8rem)]; + } + + .pk-chat-messages { + @apply flex-1 overflow-y-auto space-y-4 p-4; + } + + .pk-chat-message { + @apply p-4 rounded-lg; + } + + .pk-chat-message-user { + @apply pk-chat-message bg-purple-50 border border-purple-100 ml-12; + } + + .pk-chat-message-assistant { + @apply pk-chat-message bg-white border border-gray-200 mr-12 shadow-sm; + } + + .pk-chat-message-role { + @apply text-xs font-medium text-gray-500 mb-2 uppercase tracking-wide; + } + + .pk-chat-message-content { + @apply text-gray-800 whitespace-pre-wrap; + } + + .pk-chat-input-container { + @apply p-4 border-t border-gray-200 bg-white; + } + + .pk-chat-input { + @apply flex gap-3; + } + + .pk-chat-input-field { + @apply flex-1 px-4 py-3 border border-gray-300 rounded-lg; + @apply focus:ring-2 focus:ring-purple-500 focus:border-purple-500 focus:outline-none; + @apply disabled:bg-gray-50 disabled:text-gray-500; + } + + .pk-chat-send-button { + @apply px-6 py-3 bg-purple-600 text-white rounded-lg font-medium; + @apply hover:bg-purple-700 transition-colors; + @apply disabled:opacity-50 disabled:cursor-not-allowed; + } + + /* ============================================ + SESSION LIST + ============================================ */ + + .pk-session-list { + @apply space-y-2; + } + + .pk-session-item { + @apply block p-4 bg-white border border-gray-200 rounded-lg; + @apply hover:border-purple-300 hover:shadow-sm transition-all; + } + + .pk-session-item-title { + @apply font-medium text-gray-900; + } + + .pk-session-item-meta { + @apply text-sm text-gray-500 mt-1; + } + + /* ============================================ + EMPTY STATES + ============================================ */ + + .pk-empty-state { + @apply flex flex-col items-center justify-center py-12 text-center; + } + + .pk-empty-state-icon { + @apply w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center mb-4; + } + + .pk-empty-state-title { + @apply text-lg font-medium text-gray-900 mb-2; + } + + .pk-empty-state-description { + @apply text-gray-500; + } + + /* ============================================ + LOADING STATES + ============================================ */ + + .pk-loading { + @apply flex items-center justify-center py-12; + } + + .pk-loading-spinner { + @apply animate-spin h-8 w-8 border-4 border-purple-600 border-t-transparent rounded-full; + } + + .pk-loading-text { + @apply text-gray-500 ml-3; + } + + .pk-thinking { + @apply p-4 bg-gray-50 border border-gray-200 rounded-lg mr-12; + @apply animate-pulse; + } + + /* ============================================ + MARKDOWN CONTENT + ============================================ */ + + .markdown-content { + @apply text-gray-800 leading-relaxed; + } + + .markdown-content p { + @apply mb-4 last:mb-0; + } + + .markdown-content h1 { + @apply text-2xl font-bold mb-4 mt-6 first:mt-0; + } + + .markdown-content h2 { + @apply text-xl font-bold mb-3 mt-5 first:mt-0; + } + + .markdown-content h3 { + @apply text-lg font-semibold mb-2 mt-4 first:mt-0; + } + + .markdown-content h4, + .markdown-content h5, + .markdown-content h6 { + @apply font-semibold mb-2 mt-3 first:mt-0; + } + + .markdown-content ul { + @apply list-disc list-inside mb-4 space-y-1; + } + + .markdown-content ol { + @apply list-decimal list-inside mb-4 space-y-1; + } + + .markdown-content li { + @apply pl-1; + } + + .markdown-content code { + @apply bg-gray-100 text-purple-700 px-1.5 py-0.5 rounded text-sm font-mono; + } + + .markdown-content pre { + @apply bg-gray-900 text-gray-100 p-4 rounded-lg mb-4 overflow-x-auto; + } + + .markdown-content pre code { + @apply bg-transparent text-gray-100 p-0 text-sm; + } + + .markdown-content blockquote { + @apply border-l-4 border-purple-300 pl-4 italic text-gray-600 mb-4; + } + + .markdown-content a { + @apply text-purple-600 hover:text-purple-800 underline; + } + + .markdown-content hr { + @apply border-gray-200 my-6; + } + + .markdown-content table { + @apply w-full border-collapse mb-4; + } + + .markdown-content th { + @apply bg-gray-100 border border-gray-300 px-3 py-2 text-left font-semibold; + } + + .markdown-content td { + @apply border border-gray-300 px-3 py-2; + } + + .markdown-content strong { + @apply font-semibold; + } + + .markdown-content em { + @apply italic; + } +} diff --git a/prokube/app-prefixable/src/index.html b/prokube/app-prefixable/src/index.html new file mode 100644 index 00000000000..cc934de6831 --- /dev/null +++ b/prokube/app-prefixable/src/index.html @@ -0,0 +1,39 @@ + + + + + + OpenCode + + + + + + + +
+
Loading...
+
+ + + + diff --git a/prokube/app-prefixable/src/pages/home.tsx b/prokube/app-prefixable/src/pages/home.tsx new file mode 100644 index 00000000000..64857ba3299 --- /dev/null +++ b/prokube/app-prefixable/src/pages/home.tsx @@ -0,0 +1,41 @@ +import { useNavigate } from "@solidjs/router" +import { Button } from "@opencode-ai/ui/button" +import { useSDK } from "../context/sdk" + +export function Home() { + const { client } = useSDK() + const navigate = useNavigate() + + async function createNewSession() { + try { + const res = await client.session.create({}) + if (res.data) { + navigate(`/session/${res.data.id}`) + } + } catch (e) { + console.error("Failed to create session:", e) + } + } + + return ( +
+
+
+ + + +
+

Welcome to OpenCode

+

Select a session from the sidebar or start a new one.

+ +
+
+ ) +} diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx new file mode 100644 index 00000000000..801aff7dacf --- /dev/null +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -0,0 +1,184 @@ +import { type ParentProps, createSignal, For, Show, onMount, createEffect } from "solid-js" +import { A, useLocation, useNavigate } from "@solidjs/router" +import { useBasePath } from "../context/base-path" +import { useSDK } from "../context/sdk" +import { useEvents } from "../context/events" +import { Button } from "@opencode-ai/ui/button" +import { Spinner } from "@opencode-ai/ui/spinner" +import type { Session } from "@opencode-ai/sdk/v2/client" + +export function Layout(props: ParentProps) { + const { basePath } = useBasePath() + const { client } = useSDK() + const events = useEvents() + const location = useLocation() + const navigate = useNavigate() + + const [sessions, setSessions] = createSignal([]) + const [loading, setLoading] = createSignal(true) + const [sidebarOpen, setSidebarOpen] = createSignal(true) + + async function loadSessions() { + try { + console.log("[Layout] Loading sessions...") + const res = await client.session.list({ roots: true }) + console.log("[Layout] Sessions response:", res) + if (res.data) { + setSessions(res.data) + } + } catch (e) { + console.error("Failed to load sessions:", e) + } finally { + setLoading(false) + } + } + + onMount(() => { + loadSessions() + + // Subscribe to session events + const unsub = events.subscribe((event) => { + console.log("[Layout] Event received:", event.type) + if (event.type === "session.created" || event.type === "session.updated" || event.type === "session.deleted") { + loadSessions() + } + }) + + return unsub + }) + + async function createNewSession() { + try { + console.log("[Layout] Creating new session...") + const res = await client.session.create({}) + console.log("[Layout] Create response:", res) + if (res.data) { + console.log("[Layout] Navigating to:", `/session/${res.data.id}`) + navigate(`/session/${res.data.id}`) + } + } catch (e) { + console.error("Failed to create session:", e) + } + } + + function isActive(sessionId: string) { + return location.pathname.includes(sessionId) + } + + function formatTime(timestamp: number) { + const date = new Date(timestamp) + const now = new Date() + const diff = now.getTime() - date.getTime() + + if (diff < 60000) return "just now" + if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago` + if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago` + return date.toLocaleDateString() + } + + return ( +
+ {/* Sidebar */} + + + {/* Main Content */} +
{props.children}
+
+ ) +} diff --git a/prokube/app-prefixable/src/pages/session.tsx b/prokube/app-prefixable/src/pages/session.tsx new file mode 100644 index 00000000000..b788687210e --- /dev/null +++ b/prokube/app-prefixable/src/pages/session.tsx @@ -0,0 +1,322 @@ +import { createSignal, createResource, Show, For, onMount, createEffect } from "solid-js" +import { useParams, useNavigate } from "@solidjs/router" +import { Button } from "@opencode-ai/ui/button" +import { Spinner } from "@opencode-ai/ui/spinner" +import { useSDK } from "../context/sdk" +import { useEvents } from "../context/events" +import { Markdown } from "../components/markdown" +import type { Part } from "@opencode-ai/sdk/v2/client" + +interface DisplayMessage { + id: string + role: "user" | "assistant" + parts: Part[] +} + +function extractTextContent(parts: Part[]): string { + return parts + .filter((p): p is Part & { type: "text" } => p.type === "text") + .map((p) => p.text) + .join("") +} + +export function Session() { + const params = useParams<{ id?: string }>() + const navigate = useNavigate() + const { client } = useSDK() + const events = useEvents() + + const [input, setInput] = createSignal("") + const [messages, setMessages] = createSignal([]) + const [loading, setLoading] = createSignal(false) + const [processing, setProcessing] = createSignal(false) + const [sessionId, setSessionId] = createSignal(params.id) + let messagesEndRef: HTMLDivElement | undefined + let inputRef: HTMLInputElement | undefined + + // Fetch existing session + const [session, { refetch: refetchSession }] = createResource( + () => params.id, + async (id) => { + if (!id) return null + try { + const res = await client.session.get({ sessionID: id }) + return res.data ?? null + } catch { + return null + } + }, + ) + + // Load messages + async function loadMessages(id: string) { + try { + console.log("[Session] Loading messages for:", id) + const res = await client.session.messages({ sessionID: id }) + if (res.data) { + const msgs: DisplayMessage[] = res.data.map((msg) => ({ + id: msg.info.id, + role: msg.info.role as "user" | "assistant", + parts: msg.parts, + })) + console.log("[Session] Loaded messages:", msgs.length) + setMessages(msgs) + } + } catch (e) { + console.error("Failed to load messages:", e) + } + } + + // Poll for status and reload messages when done + async function waitForCompletion(id: string) { + console.log("[Session] Waiting for completion...") + setProcessing(true) + + for (let i = 0; i < 120; i++) { + await new Promise((r) => setTimeout(r, 500)) + + try { + const res = await client.session.status({}) + const statuses = res.data as Record | undefined + if (!statuses) continue + + const status = statuses[id] + console.log("[Session] Status:", status?.type) + + if (!status || status.type === "idle") { + console.log("[Session] Complete, reloading messages...") + await loadMessages(id) + setProcessing(false) + return + } + } catch (e) { + console.error("[Session] Status check failed:", e) + } + } + + // Timeout - reload anyway + console.log("[Session] Timeout, reloading messages...") + await loadMessages(id) + setProcessing(false) + } + + // Subscribe to events for real-time updates + onMount(() => { + if (params.id) { + loadMessages(params.id) + } + + const unsub = events.subscribe((event) => { + const id = sessionId() + if (!id) return + + console.log("[Session] Event:", event.type) + + // Handle message part updates + if (event.type === "message.part.updated") { + const part = event.properties.part + if (part.sessionID !== id) return + + setMessages((prev) => { + const msgIndex = prev.findIndex((m) => m.id === part.messageID) + if (msgIndex === -1) { + return [ + ...prev, + { + id: part.messageID, + role: "assistant" as const, + parts: [part], + }, + ] + } + + const msg = prev[msgIndex] + const partIndex = msg.parts.findIndex((p) => p.id === part.id) + const newParts = + partIndex === -1 ? [...msg.parts, part] : msg.parts.map((p, i) => (i === partIndex ? part : p)) + + return prev.map((m, i) => (i === msgIndex ? { ...m, parts: newParts } : m)) + }) + } + + // Handle status changes + if (event.type === "session.status") { + const props = event.properties as { sessionID: string; status: { type: string } } + if (props.sessionID === id && props.status.type === "idle") { + console.log("[Session] Status idle, reloading...") + loadMessages(id) + setProcessing(false) + } else if (props.sessionID === id) { + setProcessing(true) + } + } + + // Handle session updates + if (event.type === "session.updated") { + refetchSession() + } + }) + + return unsub + }) + + // Auto-scroll to bottom + createEffect(() => { + messages() + messagesEndRef?.scrollIntoView({ behavior: "smooth" }) + }) + + // Focus input on mount + onMount(() => { + inputRef?.focus() + }) + + async function sendMessage(e: SubmitEvent) { + e.preventDefault() + const text = input().trim() + if (!text || loading()) return + + setLoading(true) + setInput("") + + // Optimistic update + const userMessage: DisplayMessage = { + id: crypto.randomUUID(), + role: "user", + parts: [{ id: crypto.randomUUID(), sessionID: sessionId() || "", messageID: "", type: "text", text }] as Part[], + } + setMessages((prev) => [...prev, userMessage]) + + try { + let id = sessionId() + + if (!id) { + console.log("[Session] Creating new session...") + const createRes = await client.session.create({}) + console.log("[Session] Create response:", createRes) + if (!createRes.data) throw new Error("Failed to create session") + + id = createRes.data.id + setSessionId(id) + navigate(`/session/${id}`, { replace: true }) + } + + // Send message + console.log("[Session] Sending message to session:", id) + const promptRes = await client.session.promptAsync({ + sessionID: id, + parts: [{ type: "text", text }], + }) + console.log("[Session] Prompt response:", promptRes) + + // Start polling for completion (SSE might not work through proxy) + waitForCompletion(id) + } catch (err) { + console.error("Error sending message:", err) + } finally { + setLoading(false) + } + } + + return ( +
+ {/* Header */} +
+
+

{session()?.title || "New Session"}

+ +

{session()?.id}

+
+
+ +
+ + Processing... +
+
+
+ + {/* Messages */} +
+ +
+
+ + + +
+

Start a conversation

+

Type a message below to begin

+
+
+ + + {(message) => ( +
+
+
{message.role}
+ {extractTextContent(message.parts) || "..."}
+ } + > + + +
+
+ )} + + + +
+
+
+ + Thinking... +
+
+
+
+ +
+
+ + {/* Input */} +
+
+ setInput(e.currentTarget.value)} + placeholder="Type a message..." + class="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 focus:outline-none" + disabled={loading() || processing()} + /> + +
+
+
+ ) +} diff --git a/prokube/app-prefixable/src/utils/path.ts b/prokube/app-prefixable/src/utils/path.ts new file mode 100644 index 00000000000..d82381b382c --- /dev/null +++ b/prokube/app-prefixable/src/utils/path.ts @@ -0,0 +1,67 @@ +declare global { + interface Window { + __OPENCODE__?: { + basePath?: string + serverUrl?: string + } + } +} + +export function getBasePath(): string { + // Priority order: + // 1. Explicit config in window.__OPENCODE__ + // 2. tag + // 3. Build-time injected value + // 4. Default to "/" + + if (typeof window !== "undefined") { + // From global config + if (window.__OPENCODE__?.basePath) { + return normalizeBasePath(window.__OPENCODE__.basePath) + } + + // From tag + const baseTag = document.querySelector("base") + if (baseTag?.href) { + const url = new URL(baseTag.href) + return normalizeBasePath(url.pathname) + } + } + + // Build-time value + // @ts-ignore - injected at build time + if (typeof import.meta.env?.BASE_PATH === "string") { + // @ts-ignore + return normalizeBasePath(import.meta.env.BASE_PATH) + } + + return "/" +} + +export function normalizeBasePath(path: string): string { + // Ensure leading slash, trailing slash + let normalized = path.trim() + if (!normalized.startsWith("/")) normalized = "/" + normalized + if (!normalized.endsWith("/")) normalized = normalized + "/" + return normalized +} + +export function prefixPath(path: string, basePath: string): string { + if (path.startsWith("http://") || path.startsWith("https://")) { + return path // Absolute URLs unchanged + } + const base = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath + const suffix = path.startsWith("/") ? path : "/" + path + return base + suffix +} + +export function getServerUrl(): string { + if (typeof window !== "undefined" && window.__OPENCODE__?.serverUrl) { + return window.__OPENCODE__.serverUrl + } + // Default to same origin + if (typeof window !== "undefined") { + return window.location.origin + } + return "http://localhost:4096" +} diff --git a/prokube/app-prefixable/tailwind.config.js b/prokube/app-prefixable/tailwind.config.js new file mode 100644 index 00000000000..5034f4a979a --- /dev/null +++ b/prokube/app-prefixable/tailwind.config.js @@ -0,0 +1,23 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ["./src/**/*.{js,ts,jsx,tsx}"], + theme: { + extend: { + colors: { + purple: { + 50: "#faf5ff", + 100: "#f3e8ff", + 200: "#e9d5ff", + 300: "#d8b4fe", + 400: "#c084fc", + 500: "#a855f7", + 600: "#9333ea", + 700: "#7e22ce", + 800: "#6b21a8", + 900: "#581c87", + }, + }, + }, + }, + plugins: [], +} diff --git a/prokube/app-prefixable/tsconfig.json b/prokube/app-prefixable/tsconfig.json new file mode 100644 index 00000000000..2553b5127f5 --- /dev/null +++ b/prokube/app-prefixable/tsconfig.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + "allowJs": true, + "resolveJsonModule": true, + "strict": true, + "noEmit": true, + "isolatedModules": true, + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src", "*.ts"], + "exclude": ["dist", "node_modules"] +} From 4d7771e29e24bda275ee4544e2b6a73e847a094a Mon Sep 17 00:00:00 2001 From: hsteude Date: Thu, 22 Jan 2026 08:23:14 +0200 Subject: [PATCH 003/144] feat(prokube): add provider connection, model and agent selection - New ProviderProvider context for state management - Settings page for connecting providers via API key - Model picker dropdown in session header - Agent picker dropdown in session header - Provider status indicator in sidebar - Fix SSE proxy idleTimeout issue --- prokube/app-prefixable/dev.ts | 66 ++---- prokube/app-prefixable/src/app.tsx | 7 +- .../app-prefixable/src/context/providers.tsx | 164 +++++++++++++ prokube/app-prefixable/src/pages/layout.tsx | 99 +++++++- prokube/app-prefixable/src/pages/session.tsx | 134 ++++++++++- prokube/app-prefixable/src/pages/settings.tsx | 224 ++++++++++++++++++ 6 files changed, 634 insertions(+), 60 deletions(-) create mode 100644 prokube/app-prefixable/src/context/providers.tsx create mode 100644 prokube/app-prefixable/src/pages/settings.tsx diff --git a/prokube/app-prefixable/dev.ts b/prokube/app-prefixable/dev.ts index a45c0a9faf0..ce0dc1a9466 100644 --- a/prokube/app-prefixable/dev.ts +++ b/prokube/app-prefixable/dev.ts @@ -18,6 +18,7 @@ const basePathWithTrailing = BASE_PATH.endsWith("/") ? BASE_PATH : BASE_PATH + " const server = Bun.serve({ port: PORT, + idleTimeout: 0, // Disable timeout for SSE connections async fetch(req) { const url = new URL(req.url) let path = url.pathname @@ -45,49 +46,34 @@ const server = Bun.serve({ const target = new URL(path + url.search, API_URL) const headers = new Headers(req.headers) - // SSE requests need special handling - stream responses properly + // SSE requests - just pass through the response body directly if (path.startsWith("/event")) { console.log("[Proxy] SSE request to:", target.toString()) - const response = await fetch(target.toString(), { - method: req.method, - headers, - }) - - if (!response.ok) { - console.error("[Proxy] SSE error:", response.status, response.statusText) - return new Response(response.body, { status: response.status }) + try { + const response = await fetch(target.toString(), { + method: req.method, + headers, + }) + + if (!response.ok) { + console.error("[Proxy] SSE error:", response.status, response.statusText) + return new Response(response.body, { status: response.status }) + } + + // Pass through the body directly - Bun handles streaming + return new Response(response.body, { + status: response.status, + headers: { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + Connection: "keep-alive", + "X-Accel-Buffering": "no", + }, + }) + } catch (e) { + console.error("[Proxy] SSE connection error:", e) + return new Response("SSE proxy error", { status: 502 }) } - - // Create a transform stream to pass through SSE data - const { readable, writable } = new TransformStream() - const writer = writable.getWriter() - const reader = response.body?.getReader() - - if (reader) { - ;(async () => { - try { - while (true) { - const { done, value } = await reader.read() - if (done) break - await writer.write(value) - } - } catch (e) { - console.error("[Proxy] SSE stream error:", e) - } finally { - writer.close() - } - })() - } - - return new Response(readable, { - status: response.status, - headers: { - "Content-Type": "text/event-stream", - "Cache-Control": "no-cache", - Connection: "keep-alive", - "X-Accel-Buffering": "no", - }, - }) } return fetch(target.toString(), { diff --git a/prokube/app-prefixable/src/app.tsx b/prokube/app-prefixable/src/app.tsx index a93b44ae856..413fd3226ea 100644 --- a/prokube/app-prefixable/src/app.tsx +++ b/prokube/app-prefixable/src/app.tsx @@ -2,8 +2,10 @@ import { Router, Route } from "@solidjs/router" import { BasePathProvider, useBasePath } from "./context/base-path" import { SDKProvider } from "./context/sdk" import { EventProvider } from "./context/events" +import { ProviderProvider } from "./context/providers" import { Home } from "./pages/home" import { Session } from "./pages/session" +import { Settings } from "./pages/settings" import { Layout } from "./pages/layout" function AppRoutes() { @@ -14,6 +16,7 @@ function AppRoutes() { + ) } @@ -23,7 +26,9 @@ export function App() { - + + + diff --git a/prokube/app-prefixable/src/context/providers.tsx b/prokube/app-prefixable/src/context/providers.tsx new file mode 100644 index 00000000000..89044d53c08 --- /dev/null +++ b/prokube/app-prefixable/src/context/providers.tsx @@ -0,0 +1,164 @@ +import { createContext, useContext, createResource, type ParentProps } from "solid-js" +import { createStore } from "solid-js/store" +import { useSDK } from "./sdk" + +// Define types locally to avoid SDK type mismatches +interface Model { + id: string + name: string + providerID: string +} + +interface Provider { + id: string + name: string + models: Record +} + +interface Agent { + name: string + mode: string + hidden?: boolean +} + +interface ProviderAuthMethod { + type: "api" | "oauth" + label: string +} + +interface ModelKey { + providerID: string + modelID: string +} + +interface ProviderListData { + all: Provider[] + connected: string[] + default: Record +} + +interface ProviderContextValue { + providers: Provider[] + connected: string[] + defaults: Record + authMethods: Record + agents: Agent[] + loading: boolean + selectedModel: ModelKey | null + selectedAgent: string + setSelectedModel: (model: ModelKey | null) => void + setSelectedAgent: (agent: string) => void + refetch: () => void + connectProvider: (providerID: string, apiKey: string) => Promise +} + +const ProviderContext = createContext() + +export function ProviderProvider(props: ParentProps) { + const { client } = useSDK() + + const [store, setStore] = createStore({ + selectedModel: null as ModelKey | null, + selectedAgent: "code", + }) + + // Fetch providers + const [providerData, { refetch: refetchProviders }] = createResource(async () => { + try { + const res = await client.provider.list() + return res.data as ProviderListData | undefined + } catch (e) { + console.error("Failed to fetch providers:", e) + return undefined + } + }) + + // Fetch auth methods for all providers (returns { [providerID]: ProviderAuthMethod[] }) + const [authData] = createResource(async () => { + try { + const res = await client.provider.auth() + return (res.data as Record) ?? {} + } catch (e) { + console.error("Failed to fetch auth methods:", e) + return {} + } + }) + + // Fetch agents + const [agentsData, { refetch: refetchAgents }] = createResource(async () => { + try { + const res = await client.app.agents() + return (res.data as Agent[]) ?? [] + } catch (e) { + console.error("Failed to fetch agents:", e) + return [] + } + }) + + function setSelectedModel(model: ModelKey | null) { + setStore("selectedModel", model) + } + + function setSelectedAgent(agent: string) { + setStore("selectedAgent", agent) + } + + async function connectProvider(providerID: string, apiKey: string): Promise { + try { + await client.auth.set({ + providerID, + auth: { type: "api", key: apiKey }, + }) + // Refresh provider list + refetchProviders() + return true + } catch (e) { + console.error("Failed to connect provider:", e) + return false + } + } + + function refetch() { + refetchProviders() + refetchAgents() + } + + const value: ProviderContextValue = { + get providers() { + return providerData()?.all ?? [] + }, + get connected() { + return providerData()?.connected ?? [] + }, + get defaults() { + return providerData()?.default ?? {} + }, + get authMethods() { + return authData() ?? {} + }, + get agents() { + return (agentsData() ?? []).filter((a) => a.mode === "primary" && !a.hidden) + }, + get loading() { + return providerData.loading || agentsData.loading + }, + get selectedModel() { + return store.selectedModel + }, + get selectedAgent() { + return store.selectedAgent + }, + setSelectedModel, + setSelectedAgent, + refetch, + connectProvider, + } + + return {props.children} +} + +export function useProviders() { + const ctx = useContext(ProviderContext) + if (!ctx) throw new Error("useProviders must be used within ProviderProvider") + return ctx +} diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index 801aff7dacf..5e89e883a9f 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -1,8 +1,9 @@ -import { type ParentProps, createSignal, For, Show, onMount, createEffect } from "solid-js" +import { type ParentProps, createSignal, For, Show, onMount } from "solid-js" import { A, useLocation, useNavigate } from "@solidjs/router" import { useBasePath } from "../context/base-path" import { useSDK } from "../context/sdk" import { useEvents } from "../context/events" +import { useProviders } from "../context/providers" import { Button } from "@opencode-ai/ui/button" import { Spinner } from "@opencode-ai/ui/spinner" import type { Session } from "@opencode-ai/sdk/v2/client" @@ -11,6 +12,7 @@ export function Layout(props: ParentProps) { const { basePath } = useBasePath() const { client } = useSDK() const events = useEvents() + const providers = useProviders() const location = useLocation() const navigate = useNavigate() @@ -61,8 +63,8 @@ export function Layout(props: ParentProps) { } } - function isActive(sessionId: string) { - return location.pathname.includes(sessionId) + function isActive(path: string) { + return location.pathname.includes(path) } function formatTime(timestamp: number) { @@ -166,15 +168,90 @@ export function Layout(props: ParentProps) {
- {/* Status */} - -
-
- - Connected + {/* Bottom Nav */} +
+ {/* Provider Status */} + +
+ {/* Settings Link */} + + + + + + Settings + + + {/* Provider status indicator */} +
+
+ 0} + fallback={ + <> + + No providers + + } + > + + {providers.connected.length} provider(s) + +
+ +
Agent: {providers.selectedAgent}
+
+
-
- + + + {/* Collapsed state */} + + + +
{/* Main Content */} diff --git a/prokube/app-prefixable/src/pages/session.tsx b/prokube/app-prefixable/src/pages/session.tsx index b788687210e..2b4a692c137 100644 --- a/prokube/app-prefixable/src/pages/session.tsx +++ b/prokube/app-prefixable/src/pages/session.tsx @@ -4,6 +4,7 @@ import { Button } from "@opencode-ai/ui/button" import { Spinner } from "@opencode-ai/ui/spinner" import { useSDK } from "../context/sdk" import { useEvents } from "../context/events" +import { useProviders } from "../context/providers" import { Markdown } from "../components/markdown" import type { Part } from "@opencode-ai/sdk/v2/client" @@ -25,12 +26,15 @@ export function Session() { const navigate = useNavigate() const { client } = useSDK() const events = useEvents() + const providers = useProviders() const [input, setInput] = createSignal("") const [messages, setMessages] = createSignal([]) const [loading, setLoading] = createSignal(false) const [processing, setProcessing] = createSignal(false) const [sessionId, setSessionId] = createSignal(params.id) + const [showModelPicker, setShowModelPicker] = createSignal(false) + const [showAgentPicker, setShowAgentPicker] = createSignal(false) let messagesEndRef: HTMLDivElement | undefined let inputRef: HTMLInputElement | undefined @@ -201,12 +205,27 @@ export function Session() { navigate(`/session/${id}`, { replace: true }) } - // Send message + // Send message with agent and model console.log("[Session] Sending message to session:", id) - const promptRes = await client.session.promptAsync({ + const promptPayload: { + sessionID: string + parts: { type: "text"; text: string }[] + agent?: string + model?: { providerID: string; modelID: string } + } = { sessionID: id, parts: [{ type: "text", text }], - }) + } + + if (providers.selectedAgent) { + promptPayload.agent = providers.selectedAgent + } + + if (providers.selectedModel) { + promptPayload.model = providers.selectedModel + } + + const promptRes = await client.session.promptAsync(promptPayload) console.log("[Session] Prompt response:", promptRes) // Start polling for completion (SSE might not work through proxy) @@ -228,12 +247,111 @@ export function Session() {

{session()?.id}

- -
- - Processing... + + {/* Model & Agent Selectors */} +
+ {/* Agent Selector */} +
+ + + +
+ + {(agent) => ( + + )} + + +
No agents available
+
+
+
- + + {/* Model Selector */} +
+ + + +
+ +
+

No providers connected.

+ + Connect a provider + +
+
+ + providers.connected.includes(p.id))}> + {(provider) => ( +
+
+ {provider.name} +
+ + {(model) => ( + + )} + +
+ )} +
+
+
+
+ + +
+ + Processing... +
+
+
{/* Messages */} diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx new file mode 100644 index 00000000000..ba238242dc7 --- /dev/null +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -0,0 +1,224 @@ +import { createSignal, For, Show } from "solid-js" +import { Button } from "@opencode-ai/ui/button" +import { Spinner } from "@opencode-ai/ui/spinner" +import { useProviders } from "../context/providers" + +export function Settings() { + const providers = useProviders() + const [selectedProvider, setSelectedProvider] = createSignal(null) + const [apiKey, setApiKey] = createSignal("") + const [connecting, setConnecting] = createSignal(false) + const [error, setError] = createSignal(null) + const [success, setSuccess] = createSignal(null) + + async function handleConnect(e: SubmitEvent) { + e.preventDefault() + const providerID = selectedProvider() + const key = apiKey().trim() + + if (!providerID || !key) return + + setConnecting(true) + setError(null) + setSuccess(null) + + const ok = await providers.connectProvider(providerID, key) + + setConnecting(false) + + if (ok) { + setSuccess(`Connected to ${providerID}!`) + setApiKey("") + setSelectedProvider(null) + } else { + setError("Failed to connect. Please check your API key.") + } + } + + function getProviderDisplayName(id: string): string { + const provider = providers.providers.find((p) => p.id === id) + return provider?.name ?? id + } + + return ( +
+
+
+

Settings

+

Configure AI providers and preferences

+
+ + {/* Connected Providers */} +
+
+

Connected Providers

+
+
+ +
+ + Loading... +
+
+ + +

No providers connected yet.

+
+ + 0}> +
    + + {(providerID) => ( +
  • +
    +
    + + + +
    + {getProviderDisplayName(providerID)} +
    + Connected +
  • + )} +
    +
+
+
+
+ + {/* Add Provider */} +
+
+

Add Provider

+
+
+ +
{success()}
+
+ + +
{error()}
+
+ +
+ {/* Provider Selection */} +
+ +
+ !providers.connected.includes(p.id))}> + {(provider) => ( + + )} + +
+ + !providers.connected.includes(p.id)).length === 0}> +

All available providers are connected!

+
+
+ + {/* API Key Input */} + +
+ + setApiKey(e.currentTarget.value)} + placeholder="Enter your API key..." + class="pk-input" + /> +

Your API key is stored securely and never shared.

+
+ + +
+
+
+
+ + {/* Available Models */} +
+
+

Available Models

+
+
+ +

Connect a provider to see available models.

+
+ + 0}> +
+ providers.connected.includes(p.id))}> + {(provider) => ( +
+

{provider.name}

+
+ + {(model) => ( +
{model.name}
+ )} +
+ 5}> +
+ +{Object.keys(provider.models).length - 5} more models +
+
+
+
+ )} +
+
+
+
+
+ + {/* Agents */} +
+
+

Available Agents

+
+
+ +

No agents available.

+
+ +
+ + {(agent) => ( +
providers.setSelectedAgent(agent.name)} + > +
{agent.name}
+
+ )} +
+
+
+
+
+
+ ) +} From 7d450ec0c2c3f5b0b7da9253c9bc8efe4ea588d5 Mon Sep 17 00:00:00 2001 From: hsteude Date: Thu, 22 Jan 2026 09:03:04 +0200 Subject: [PATCH 004/144] feat(prokube): redesign UI with CSS variables for theming - Add CSS design tokens for colors, backgrounds, borders - Redesign sidebar with cleaner, more elegant styling - Redesign settings page with tabs for providers/models/agents - Update session page to use CSS variables throughout - Update home page with consistent theming - Add /agent to dev proxy paths - Add null checks in SSE event handling --- prokube/app-prefixable/dev.ts | 42 +- prokube/app-prefixable/src/app.tsx | 5 +- prokube/app-prefixable/src/context/events.tsx | 12 +- .../app-prefixable/src/context/providers.tsx | 11 +- prokube/app-prefixable/src/index.css | 60 +- prokube/app-prefixable/src/pages/home.tsx | 23 +- prokube/app-prefixable/src/pages/layout.tsx | 146 +++-- prokube/app-prefixable/src/pages/session.tsx | 511 +++++++++++++++--- prokube/app-prefixable/src/pages/settings.tsx | 503 +++++++++++------ 9 files changed, 1013 insertions(+), 300 deletions(-) diff --git a/prokube/app-prefixable/dev.ts b/prokube/app-prefixable/dev.ts index ce0dc1a9466..13e2088e987 100644 --- a/prokube/app-prefixable/dev.ts +++ b/prokube/app-prefixable/dev.ts @@ -21,14 +21,13 @@ const server = Bun.serve({ idleTimeout: 0, // Disable timeout for SSE connections async fetch(req) { const url = new URL(req.url) - let path = url.pathname + const path = url.pathname - // Proxy API requests to the OpenCode server - // These paths match the OpenCode API endpoints + // API requests go directly to the API without base path + // The SDK calls these paths directly on the origin const apiPaths = [ - "/api/", + "/api", "/event", - "/session", "/config", "/provider", "/project", @@ -39,8 +38,23 @@ const server = Bun.serve({ "/health", "/path", "/command", + "/auth", + "/app", + "/agent", ] - const isApiRequest = apiPaths.some((p) => path === p || path.startsWith(p + "/") || path.startsWith(p + "?")) + + // Check if this is an API request (not a frontend route) + // API paths don't have the base path prefix + const isApiPath = apiPaths.some((p) => path === p || path.startsWith(p + "/") || path.startsWith(p + "?")) + + // Special handling for /session - only API if it doesn't have base path prefix + // Frontend routes: /opencode/session, /opencode/session/, /opencode/session/abc123 + // API routes: /session (POST), /session/list, /session/create, etc. + const isSessionApi = + (path === "/session" || path.startsWith("/session/") || path.startsWith("/session?")) && + !path.startsWith(basePathWithoutTrailing) // Not prefixed with base path = API call + + const isApiRequest = isApiPath || isSessionApi if (isApiRequest) { const target = new URL(path + url.search, API_URL) @@ -76,6 +90,7 @@ const server = Bun.serve({ } } + console.log("[Proxy] API:", req.method, path) return fetch(target.toString(), { method: req.method, headers, @@ -83,21 +98,20 @@ const server = Bun.serve({ }) } - // Strip base path prefix for file lookup + // Frontend routes - strip base path prefix for file lookup + let strippedPath = path if (basePathWithoutTrailing && path.startsWith(basePathWithoutTrailing)) { - path = path.slice(basePathWithoutTrailing.length) || "/" + strippedPath = path.slice(basePathWithoutTrailing.length) || "/" } - - // Ensure path starts with / - if (!path.startsWith("/")) { - path = "/" + path + if (!strippedPath.startsWith("/")) { + strippedPath = "/" + strippedPath } // Try to serve static file - const filePath = `./dist${path}` + const filePath = `./dist${strippedPath}` const file = Bun.file(filePath) if (await file.exists()) { - const ext = path.split(".").pop() || "" + const ext = strippedPath.split(".").pop() || "" const mimeTypes: Record = { js: "application/javascript", css: "text/css", diff --git a/prokube/app-prefixable/src/app.tsx b/prokube/app-prefixable/src/app.tsx index 413fd3226ea..61371b5de9f 100644 --- a/prokube/app-prefixable/src/app.tsx +++ b/prokube/app-prefixable/src/app.tsx @@ -3,6 +3,7 @@ import { BasePathProvider, useBasePath } from "./context/base-path" import { SDKProvider } from "./context/sdk" import { EventProvider } from "./context/events" import { ProviderProvider } from "./context/providers" +import { CommandProvider } from "./context/command" import { Home } from "./pages/home" import { Session } from "./pages/session" import { Settings } from "./pages/settings" @@ -27,7 +28,9 @@ export function App() { - + + + diff --git a/prokube/app-prefixable/src/context/events.tsx b/prokube/app-prefixable/src/context/events.tsx index ea4d4d8adfe..abceb75741d 100644 --- a/prokube/app-prefixable/src/context/events.tsx +++ b/prokube/app-prefixable/src/context/events.tsx @@ -33,13 +33,19 @@ export function EventProvider(props: ParentProps) { eventSource.onmessage = (e) => { try { const wrapper = JSON.parse(e.data) as { directory?: string; payload: Event } - const event = wrapper.payload + const event = wrapper?.payload + if (!event || !event.type) { + console.warn("[Events] Received event without type:", wrapper) + return + } console.log("[Events] Received:", event.type) // Update session status if (event.type === "session.status") { - const sessionID = event.properties.sessionID - setStatus(sessionID, event.properties.status) + const props = event.properties + if (props?.sessionID && props?.status) { + setStatus(props.sessionID, props.status) + } } // Notify all handlers diff --git a/prokube/app-prefixable/src/context/providers.tsx b/prokube/app-prefixable/src/context/providers.tsx index 89044d53c08..413c227894b 100644 --- a/prokube/app-prefixable/src/context/providers.tsx +++ b/prokube/app-prefixable/src/context/providers.tsx @@ -88,7 +88,16 @@ export function ProviderProvider(props: ParentProps) { const [agentsData, { refetch: refetchAgents }] = createResource(async () => { try { const res = await client.app.agents() - return (res.data as Agent[]) ?? [] + console.log("[Providers] Agents response:", res) + console.log("[Providers] Agents data:", res.data) + + // The API returns an array directly, SDK wraps it in { data: [...] } + const agents = res.data + if (!Array.isArray(agents)) { + console.error("[Providers] Agents is not an array:", agents) + return [] + } + return agents as Agent[] } catch (e) { console.error("Failed to fetch agents:", e) return [] diff --git a/prokube/app-prefixable/src/index.css b/prokube/app-prefixable/src/index.css index 65040272206..97f7d058b8b 100644 --- a/prokube/app-prefixable/src/index.css +++ b/prokube/app-prefixable/src/index.css @@ -5,9 +5,67 @@ /** * OpenCode ProKube UI Component Styles * - * Basiert auf dem pkui Design-System + * Basiert auf dem OpenCode Design-System mit CSS-Variablen */ +@layer base { + :root { + /* Background colors */ + --background-base: #ffffff; + --background-stronger: #fafafa; + --background-strongest: #f4f4f5; + + /* Surface colors */ + --surface-base: #ffffff; + --surface-inset: #f4f4f5; + --surface-strong: #e4e4e7; + + /* Text colors */ + --text-base: #3f3f46; + --text-strong: #18181b; + --text-weak: #71717a; + --text-interactive-base: #7c3aed; + + /* Icon colors */ + --icon-base: #52525b; + --icon-weak: #a1a1aa; + --icon-strong: #18181b; + + /* Border colors */ + --border-base: #e4e4e7; + --border-strong: #d4d4d8; + + /* Interactive */ + --interactive-base: #7c3aed; + --interactive-hover: #6d28d9; + } + + .dark { + --background-base: #18181b; + --background-stronger: #09090b; + --background-strongest: #27272a; + + --surface-base: #18181b; + --surface-inset: #27272a; + --surface-strong: #3f3f46; + + --text-base: #a1a1aa; + --text-strong: #fafafa; + --text-weak: #71717a; + --text-interactive-base: #a78bfa; + + --icon-base: #a1a1aa; + --icon-weak: #52525b; + --icon-strong: #fafafa; + + --border-base: #27272a; + --border-strong: #3f3f46; + + --interactive-base: #a78bfa; + --interactive-hover: #8b5cf6; + } +} + @layer components { /* ============================================ BUTTONS diff --git a/prokube/app-prefixable/src/pages/home.tsx b/prokube/app-prefixable/src/pages/home.tsx index 64857ba3299..43e807a568c 100644 --- a/prokube/app-prefixable/src/pages/home.tsx +++ b/prokube/app-prefixable/src/pages/home.tsx @@ -18,10 +18,19 @@ export function Home() { } return ( -
+
-
- +
+
-

Welcome to OpenCode

-

Select a session from the sidebar or start a new one.

+

+ Welcome to OpenCode +

+

+ Select a session from the sidebar or start a new one. +

diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index 5e89e883a9f..7f4fd93d16b 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -4,7 +4,6 @@ import { useBasePath } from "../context/base-path" import { useSDK } from "../context/sdk" import { useEvents } from "../context/events" import { useProviders } from "../context/providers" -import { Button } from "@opencode-ai/ui/button" import { Spinner } from "@opencode-ai/ui/spinner" import type { Session } from "@opencode-ai/sdk/v2/client" @@ -79,30 +78,41 @@ export function Layout(props: ParentProps) { } return ( -
+
{/* Sidebar */} - {/* Main Content */} -
- {props.children} -
+ {/* Main Content + Terminal */} +
+ {/* Main Content */} +
+ {props.children} +
+ + {/* Terminal Panel */} + +
+ {/* Terminal Header */} +
+
+ {/* Terminal tabs */} + + {(session) => ( +
terminal.setActive(session.id)} + class="flex items-center gap-1.5 px-2 py-1 text-xs rounded transition-colors cursor-pointer" + style={{ + background: terminal.active() === session.id ? "var(--surface-inset)" : "transparent", + color: terminal.active() === session.id ? "var(--text-strong)" : "var(--text-weak)", + }} + > + + + + {session.title} + +
+ )} +
+ {/* New terminal button */} + +
+ + {/* Close button */} + +
+ + {/* Terminal Content */} +
+ + {(session) => ( + + + + )} + +
+
+
+
) } From 107ad0a59dfa176367b2e26bd7017186a7989e21 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sat, 24 Jan 2026 18:18:01 +0200 Subject: [PATCH 035/144] fix(prokube): prevent terminal remounting on toggle/tab switch - Use CSS display:none instead of Show for tab switching - Keep terminal panel rendered when closed (height: 0) - Add ResizeObserver to handle container size changes - Delay fit() calls to ensure proper sizing - Add smooth height transition on open/close --- .../src/components/terminal.tsx | 46 +++++++++++-------- prokube/app-prefixable/src/pages/layout.tsx | 19 +++++--- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/prokube/app-prefixable/src/components/terminal.tsx b/prokube/app-prefixable/src/components/terminal.tsx index 387839c91c8..06b22ea0d1f 100644 --- a/prokube/app-prefixable/src/components/terminal.tsx +++ b/prokube/app-prefixable/src/components/terminal.tsx @@ -1,4 +1,4 @@ -import { onMount, onCleanup, createSignal } from "solid-js" +import { onMount, onCleanup, createEffect } from "solid-js" import { Terminal as XTerm } from "@xterm/xterm" import { FitAddon } from "@xterm/addon-fit" import "@xterm/xterm/css/xterm.css" @@ -15,8 +15,6 @@ export function Terminal(props: TerminalProps) { let term: XTerm | undefined let fitAddon: FitAddon | undefined let ws: WebSocket | undefined - const [connected, setConnected] = createSignal(false) - const [error, setError] = createSignal(null) onMount(() => { // Create terminal @@ -40,7 +38,9 @@ export function Terminal(props: TerminalProps) { // Open terminal in container term.open(container) - fitAddon.fit() + + // Delay fit to ensure container is sized + setTimeout(() => fitAddon?.fit(), 50) // Connect WebSocket const wsUrl = @@ -48,29 +48,30 @@ export function Terminal(props: TerminalProps) { ws = new WebSocket(wsUrl) ws.addEventListener("open", () => { - setConnected(true) - setError(null) - // Send initial size - client.pty - .update({ - ptyID: props.ptyId, - size: { cols: term!.cols, rows: term!.rows }, - }) - .catch(() => {}) + // Send initial size after a small delay to ensure terminal is fitted + setTimeout(() => { + if (term && ws?.readyState === WebSocket.OPEN) { + client.pty + .update({ + ptyID: props.ptyId, + size: { cols: term.cols, rows: term.rows }, + }) + .catch(() => {}) + } + }, 100) }) ws.addEventListener("message", (event) => { term?.write(event.data) }) - ws.addEventListener("error", () => { - setError("Connection error") + ws.addEventListener("error", (e) => { + console.error("[Terminal] WebSocket error:", e) }) ws.addEventListener("close", (event) => { - setConnected(false) if (event.code !== 1000) { - setError(`Disconnected (${event.code})`) + console.warn("[Terminal] WebSocket closed:", event.code, event.reason) } }) @@ -94,14 +95,23 @@ export function Terminal(props: TerminalProps) { }) // Window resize handler - const handleResize = () => fitAddon?.fit() + const handleResize = () => { + setTimeout(() => fitAddon?.fit(), 10) + } window.addEventListener("resize", handleResize) + // Use ResizeObserver to detect container size changes + const resizeObserver = new ResizeObserver(() => { + setTimeout(() => fitAddon?.fit(), 10) + }) + resizeObserver.observe(container) + // Focus terminal term.focus() onCleanup(() => { window.removeEventListener("resize", handleResize) + resizeObserver.disconnect() ws?.close() term?.dispose() }) diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index fa54c85d97a..34646532457 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -426,14 +426,16 @@ export function Layout(props: ParentProps) { {props.children} - {/* Terminal Panel */} - + {/* Terminal Panel - always rendered when sessions exist, visibility controlled by CSS */} + 0}>
{/* Terminal Header */} @@ -516,9 +518,14 @@ export function Layout(props: ParentProps) {
{(session) => ( - +
- +
)}
From c6ed56572b98a0b449135e2926631cf74af2e2c2 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sat, 24 Jan 2026 18:55:07 +0200 Subject: [PATCH 036/144] feat(prokube): redesign sidebar with project icons and collapsible sessions panel - Add left strip with Prokube logo and project avatars with colored initials - Add collapsible sessions panel with project header and session list - Add ProjectDialog modal for opening projects from anywhere in the app - Support multiple open projects with localStorage persistence - Add keyboard shortcuts (Ctrl+B for sidebar, Ctrl+` for terminal) - Fix terminal WebSocket proxy in dev server --- prokube/app-prefixable/dev.ts | 69 +- .../src/components/project-dialog.tsx | 270 +++++++ .../src/components/terminal.tsx | 113 ++- prokube/app-prefixable/src/index.css | 13 + prokube/app-prefixable/src/pages/layout.tsx | 720 ++++++++++-------- 5 files changed, 822 insertions(+), 363 deletions(-) create mode 100644 prokube/app-prefixable/src/components/project-dialog.tsx diff --git a/prokube/app-prefixable/dev.ts b/prokube/app-prefixable/dev.ts index df07783166f..29c403956c4 100644 --- a/prokube/app-prefixable/dev.ts +++ b/prokube/app-prefixable/dev.ts @@ -16,10 +16,13 @@ await import("./build") const basePathWithoutTrailing = BASE_PATH.endsWith("/") ? BASE_PATH.slice(0, -1) : BASE_PATH const basePathWithTrailing = BASE_PATH.endsWith("/") ? BASE_PATH : BASE_PATH + "/" -const server = Bun.serve({ +// Track WebSocket connections: client ws -> backend ws +const wsConnections = new Map() + +const server = Bun.serve<{ target: string }>({ port: PORT, idleTimeout: 0, // Disable timeout for SSE connections - async fetch(req) { + async fetch(req, server) { const url = new URL(req.url) let path = url.pathname @@ -32,6 +35,19 @@ const server = Bun.serve({ strippedPath = "/" + strippedPath } + // WebSocket upgrade for /pty routes - proxy to backend + if (strippedPath.startsWith("/pty/") && req.headers.get("upgrade") === "websocket") { + const target = API_URL.replace(/^http/, "ws") + strippedPath + url.search + console.log("[Proxy] WebSocket upgrade:", target) + + // Upgrade to WebSocket and proxy to backend + const upgraded = server.upgrade(req, { + data: { target }, + }) + if (upgraded) return undefined + return new Response("WebSocket upgrade failed", { status: 500 }) + } + // API requests go directly to the API const apiPaths = [ "/api", @@ -135,6 +151,55 @@ const server = Bun.serve({ headers: { "Content-Type": "text/html" }, }) }, + websocket: { + open(ws) { + const target = ws.data.target + console.log("[Proxy] WebSocket client connected, connecting to backend:", target) + + // Connect to backend WebSocket + const backend = new WebSocket(target) + + backend.addEventListener("open", () => { + console.log("[Proxy] Backend WebSocket connected") + }) + + backend.addEventListener("message", (event) => { + // Forward backend messages to client + if (ws.readyState === 1) { + ws.send(event.data) + } + }) + + backend.addEventListener("close", (event) => { + console.log("[Proxy] Backend WebSocket closed:", event.code) + wsConnections.delete(ws) + if (ws.readyState === 1) { + ws.close(event.code, event.reason) + } + }) + + backend.addEventListener("error", (e) => { + console.error("[Proxy] Backend WebSocket error:", e) + }) + + wsConnections.set(ws, backend) + }, + message(ws, message) { + // Forward client messages to backend + const backend = wsConnections.get(ws) + if (backend?.readyState === WebSocket.OPEN) { + backend.send(message) + } + }, + close(ws, code, reason) { + console.log("[Proxy] Client WebSocket closed:", code) + const backend = wsConnections.get(ws) + if (backend) { + backend.close(code, reason) + wsConnections.delete(ws) + } + }, + }, }) console.log(`\nDev server running at http://localhost:${PORT}${basePathWithTrailing}`) diff --git a/prokube/app-prefixable/src/components/project-dialog.tsx b/prokube/app-prefixable/src/components/project-dialog.tsx new file mode 100644 index 00000000000..a1f0d6255c9 --- /dev/null +++ b/prokube/app-prefixable/src/components/project-dialog.tsx @@ -0,0 +1,270 @@ +import { createSignal, For, Show, onMount } from "solid-js" +import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" +import { useBasePath } from "../context/base-path" +import { Spinner } from "@opencode-ai/ui/spinner" +import { Button } from "@opencode-ai/ui/button" + +interface ProjectDialogProps { + open: boolean + onClose: () => void + onSelect: (worktree: string) => void +} + +function FolderIcon(props: { class?: string }) { + return ( + + + + ) +} + +function CloseIcon(props: { class?: string }) { + return ( + + + + ) +} + +export function ProjectDialog(props: ProjectDialogProps) { + const { serverUrl } = useBasePath() + + const [homeDirectory, setHomeDirectory] = createSignal(null) + const [folderPath, setFolderPath] = createSignal("") + const [folderSearch, setFolderSearch] = createSignal("") + const [searchResults, setSearchResults] = createSignal([]) + const [searching, setSearching] = createSignal(false) + const [newFolderName, setNewFolderName] = createSignal("") + + const client = createOpencodeClient({ baseUrl: serverUrl, throwOnError: false }) + + onMount(async () => { + try { + const res = await client.path.get() + if (res.data?.home) { + setHomeDirectory(res.data.home) + } + } catch (e) { + console.error("Failed to fetch path info:", e) + } + }) + + async function searchFolders(query: string) { + const home = homeDirectory() + if (!query.trim() || !home) { + setSearchResults([]) + return + } + + setSearching(true) + try { + const res = await client.find.files({ + directory: home, + query: query, + type: "directory", + limit: 20, + }) + const results = res.data ?? [] + setSearchResults(results.map((r) => `${home}/${r}`.replace(/\/+/g, "/"))) + } catch (e) { + console.error("Failed to search folders:", e) + setSearchResults([]) + } finally { + setSearching(false) + } + } + + function selectProject(path: string) { + props.onSelect(path) + props.onClose() + // Reset state + setFolderPath("") + setFolderSearch("") + setSearchResults([]) + setNewFolderName("") + } + + function createFolder() { + const home = homeDirectory() + const name = newFolderName().trim() + if (!name || !home) return + const fullPath = `${home}/${name}`.replace(/\/+/g, "/") + selectProject(fullPath) + } + + function openFolderPath() { + const path = folderPath().trim() + if (path) { + selectProject(path) + } + } + + // Handle escape key + function handleKeyDown(e: KeyboardEvent) { + if (e.key === "Escape") { + props.onClose() + } + } + + return ( + + {/* Backdrop */} +
props.onClose()} + onKeyDown={handleKeyDown} + > + {/* Dialog */} +
e.stopPropagation()} + > + {/* Header */} +
+

+ Open Project +

+ +
+ + {/* Content */} +
+ {/* Search for folder */} +
+ + { + setFolderSearch(e.currentTarget.value) + searchFolders(e.currentTarget.value) + }} + placeholder={`Type to search in ${homeDirectory() ?? "..."}...`} + class="w-full px-3 py-2 rounded-md text-sm" + style={{ + background: "var(--background-stronger)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + /> + + +
+ +
+
+ + 0}> +
+ + {(path) => ( + + )} + +
+
+
+ + {/* Direct path input */} +
+ +
+ setFolderPath(e.currentTarget.value)} + placeholder="/home/jovyan/my-project" + class="flex-1 px-3 py-2 rounded-md text-sm" + style={{ + background: "var(--background-stronger)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + onKeyDown={(e) => e.key === "Enter" && openFolderPath()} + /> + +
+
+ + {/* Create new folder */} +
+ +
+ setNewFolderName(e.currentTarget.value)} + placeholder="my-new-project" + class="flex-1 px-3 py-2 rounded-md text-sm" + style={{ + background: "var(--background-stronger)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + onKeyDown={(e) => e.key === "Enter" && createFolder()} + /> + +
+ +

+ Will open: {homeDirectory()}/{newFolderName()} +

+
+
+ + {/* Quick access to home directory */} + +
+ +
+
+
+
+
+
+ ) +} diff --git a/prokube/app-prefixable/src/components/terminal.tsx b/prokube/app-prefixable/src/components/terminal.tsx index 06b22ea0d1f..9acb1eae69c 100644 --- a/prokube/app-prefixable/src/components/terminal.tsx +++ b/prokube/app-prefixable/src/components/terminal.tsx @@ -1,4 +1,4 @@ -import { onMount, onCleanup, createEffect } from "solid-js" +import { onMount, onCleanup } from "solid-js" import { Terminal as XTerm } from "@xterm/xterm" import { FitAddon } from "@xterm/addon-fit" import "@xterm/xterm/css/xterm.css" @@ -15,8 +15,53 @@ export function Terminal(props: TerminalProps) { let term: XTerm | undefined let fitAddon: FitAddon | undefined let ws: WebSocket | undefined + let reconnectTimer: ReturnType | undefined + let disposed = false + + function connect() { + if (disposed || !term) return + + // Build WebSocket URL + const wsUrl = + url.replace(/^http/, "ws") + `/pty/${props.ptyId}/connect?directory=${encodeURIComponent(directory || "")}` + console.log("[Terminal] Connecting to:", wsUrl) + + ws = new WebSocket(wsUrl) + + ws.addEventListener("open", () => { + console.log("[Terminal] WebSocket connected") + // Send initial size after connection + if (term) { + client.pty + .update({ + ptyID: props.ptyId, + size: { cols: term.cols, rows: term.rows }, + }) + .catch((e) => console.error("[Terminal] Failed to update size:", e)) + } + }) + + ws.addEventListener("message", (event) => { + term?.write(event.data) + }) + + ws.addEventListener("error", (e) => { + console.error("[Terminal] WebSocket error:", e) + }) + + ws.addEventListener("close", (event) => { + console.log("[Terminal] WebSocket closed:", event.code, event.reason) + // Reconnect on abnormal close (but not if we're disposing) + if (!disposed && event.code !== 1000) { + console.log("[Terminal] Scheduling reconnect...") + reconnectTimer = setTimeout(() => connect(), 2000) + } + }) + } onMount(() => { + console.log("[Terminal] Mounting, ptyId:", props.ptyId) + // Create terminal term = new XTerm({ cursorBlink: true, @@ -38,42 +83,7 @@ export function Terminal(props: TerminalProps) { // Open terminal in container term.open(container) - - // Delay fit to ensure container is sized - setTimeout(() => fitAddon?.fit(), 50) - - // Connect WebSocket - const wsUrl = - url.replace(/^http/, "ws") + `/pty/${props.ptyId}/connect?directory=${encodeURIComponent(directory || "")}` - ws = new WebSocket(wsUrl) - - ws.addEventListener("open", () => { - // Send initial size after a small delay to ensure terminal is fitted - setTimeout(() => { - if (term && ws?.readyState === WebSocket.OPEN) { - client.pty - .update({ - ptyID: props.ptyId, - size: { cols: term.cols, rows: term.rows }, - }) - .catch(() => {}) - } - }, 100) - }) - - ws.addEventListener("message", (event) => { - term?.write(event.data) - }) - - ws.addEventListener("error", (e) => { - console.error("[Terminal] WebSocket error:", e) - }) - - ws.addEventListener("close", (event) => { - if (event.code !== 1000) { - console.warn("[Terminal] WebSocket closed:", event.code, event.reason) - } - }) + console.log("[Terminal] Terminal opened in container") // Send terminal input to WebSocket term.onData((data) => { @@ -84,6 +94,7 @@ export function Terminal(props: TerminalProps) { // Handle resize term.onResize((size) => { + console.log("[Terminal] Resize:", size.cols, "x", size.rows) if (ws?.readyState === WebSocket.OPEN) { client.pty .update({ @@ -94,15 +105,33 @@ export function Terminal(props: TerminalProps) { } }) + // Delay fit and connect to ensure container is properly sized + setTimeout(() => { + if (fitAddon && container.offsetWidth > 0 && container.offsetHeight > 0) { + console.log("[Terminal] Container size:", container.offsetWidth, "x", container.offsetHeight) + fitAddon.fit() + console.log("[Terminal] Terminal size after fit:", term?.cols, "x", term?.rows) + } else { + console.warn("[Terminal] Container has no size yet") + } + connect() + }, 100) + // Window resize handler const handleResize = () => { - setTimeout(() => fitAddon?.fit(), 10) + if (fitAddon && container.offsetWidth > 0 && container.offsetHeight > 0) { + fitAddon.fit() + } } window.addEventListener("resize", handleResize) // Use ResizeObserver to detect container size changes - const resizeObserver = new ResizeObserver(() => { - setTimeout(() => fitAddon?.fit(), 10) + const resizeObserver = new ResizeObserver((entries) => { + for (const entry of entries) { + if (entry.contentRect.width > 0 && entry.contentRect.height > 0) { + setTimeout(() => fitAddon?.fit(), 10) + } + } }) resizeObserver.observe(container) @@ -110,6 +139,9 @@ export function Terminal(props: TerminalProps) { term.focus() onCleanup(() => { + console.log("[Terminal] Cleaning up") + disposed = true + if (reconnectTimer) clearTimeout(reconnectTimer) window.removeEventListener("resize", handleResize) resizeObserver.disconnect() ws?.close() @@ -124,6 +156,7 @@ export function Terminal(props: TerminalProps) { style={{ background: "#1a1a1a", padding: "8px", + "min-height": "100px", }} /> ) diff --git a/prokube/app-prefixable/src/index.css b/prokube/app-prefixable/src/index.css index 97f7d058b8b..2c13661094f 100644 --- a/prokube/app-prefixable/src/index.css +++ b/prokube/app-prefixable/src/index.css @@ -396,4 +396,17 @@ .markdown-content em { @apply italic; } + + /* ============================================ + TERMINAL (xterm.js fixes) + ============================================ */ + + /* Hide xterm.js helper/composition elements that appear as white boxes */ + .xterm-helper-textarea { + opacity: 0 !important; + } + + .xterm .composition-view { + display: none !important; + } } diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index 34646532457..6f404cb8d23 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -1,5 +1,5 @@ import { type ParentProps, createSignal, For, Show, onMount, createMemo, onCleanup } from "solid-js" -import { A, useLocation, useNavigate } from "@solidjs/router" +import { A, useLocation, useNavigate, useParams } from "@solidjs/router" import { useBasePath } from "../context/base-path" import { useSDK } from "../context/sdk" import { useEvents } from "../context/events" @@ -7,10 +7,43 @@ import { useProviders } from "../context/providers" import { useTerminal } from "../context/terminal" import { base64Encode } from "../utils/path" import { Spinner } from "@opencode-ai/ui/spinner" +import { Button } from "@opencode-ai/ui/button" import { Terminal } from "../components/terminal" +import { ProjectDialog } from "../components/project-dialog" import type { Session } from "@opencode-ai/sdk/v2/client" -// Prokube icon (PK logo) +// Storage keys +const PROJECTS_STORAGE_KEY = "opencode.projects" +const SIDEBAR_EXPANDED_KEY = "opencode.sidebarExpanded" + +interface Project { + worktree: string + name?: string +} + +function getFilename(path: string): string { + return path.split("/").filter(Boolean).pop() || path +} + +function getInitials(name: string): string { + return name + .split(/[-_\s]/) + .filter(Boolean) + .slice(0, 2) + .map((w) => w[0]?.toUpperCase() || "") + .join("") +} + +function getColorFromString(str: string): string { + let hash = 0 + for (let i = 0; i < str.length; i++) { + hash = str.charCodeAt(i) + ((hash << 5) - hash) + } + const hue = Math.abs(hash) % 360 + return `hsl(${hue}, 60%, 45%)` +} + +// Prokube Logo function PkIcon(props: { class?: string }) { return ( @@ -28,8 +61,96 @@ function PkIcon(props: { class?: string }) { ) } +function ProjectAvatar(props: { project: Project; size?: "small" | "large"; selected?: boolean }) { + const name = () => props.project.name || getFilename(props.project.worktree) + const initials = () => getInitials(name()) + const color = () => getColorFromString(props.project.worktree) + const size = () => (props.size === "large" ? "w-10 h-10" : "w-8 h-8") + + return ( +
+ {initials()} +
+ ) +} + +// Icons +function PlusIcon(props: { class?: string }) { + return ( + + + + ) +} + +function SettingsIcon(props: { class?: string }) { + return ( + + + + + ) +} + +function TerminalIcon(props: { class?: string }) { + return ( + + + + ) +} + +function ChatIcon(props: { class?: string }) { + return ( + + + + ) +} + +function CloseIcon(props: { class?: string }) { + return ( + + + + ) +} + +function ChevronIcon(props: { class?: string; direction: "left" | "right" | "down" }) { + const path = () => { + if (props.direction === "left") return "M15 19l-7-7 7-7" + if (props.direction === "right") return "M9 5l7 7-7 7" + return "M19 9l-7 7-7-7" + } + return ( + + + + ) +} + export function Layout(props: ParentProps) { - const { basePath } = useBasePath() const { client, directory } = useSDK() const events = useEvents() const providers = useProviders() @@ -39,18 +160,84 @@ export function Layout(props: ParentProps) { const [sessions, setSessions] = createSignal([]) const [loading, setLoading] = createSignal(true) - const [sidebarOpen, setSidebarOpen] = createSignal(true) + const [projects, setProjects] = createSignal([]) + const [sidebarExpanded, setSidebarExpanded] = createSignal(true) + const [projectDialogOpen, setProjectDialogOpen] = createSignal(false) - // Current directory's base64-encoded slug for URLs - const dirSlug = createMemo(() => (directory ? base64Encode(directory) : "")) + // Load state from storage + onMount(() => { + // Load projects + try { + const stored = localStorage.getItem(PROJECTS_STORAGE_KEY) + if (stored) { + setProjects(JSON.parse(stored)) + } + } catch (e) { + console.error("Failed to load projects:", e) + } + + // Load sidebar state + try { + const expanded = localStorage.getItem(SIDEBAR_EXPANDED_KEY) + if (expanded !== null) { + setSidebarExpanded(expanded === "true") + } + } catch (e) { + console.error("Failed to load sidebar state:", e) + } + + // Add current directory to projects if not present + if (directory) { + addProject(directory) + } + }) + + function saveProjects(list: Project[]) { + setProjects(list) + try { + localStorage.setItem(PROJECTS_STORAGE_KEY, JSON.stringify(list)) + } catch (e) { + console.error("Failed to save projects:", e) + } + } + + function toggleSidebar() { + const next = !sidebarExpanded() + setSidebarExpanded(next) + try { + localStorage.setItem(SIDEBAR_EXPANDED_KEY, String(next)) + } catch (e) { + console.error("Failed to save sidebar state:", e) + } + } + + function addProject(worktree: string) { + const existing = projects().find((p) => p.worktree === worktree) + if (!existing) { + saveProjects([...projects(), { worktree }]) + } + } + + function removeProject(worktree: string) { + saveProjects(projects().filter((p) => p.worktree !== worktree)) + } + + function handleProjectSelect(worktree: string) { + addProject(worktree) + navigate(`/${base64Encode(worktree)}/session`) + } + + const currentProject = createMemo(() => projects().find((p) => p.worktree === directory)) - // Project name from directory const projectName = createMemo(() => { + const project = currentProject() + if (project?.name) return project.name if (!directory) return "Project" - return directory.split("/").pop() || directory + return getFilename(directory) }) - // Filter sessions to only show current project's sessions, sorted by updated time + const dirSlug = createMemo(() => (directory ? base64Encode(directory) : "")) + const projectSessions = createMemo(() => sessions() .filter((s) => s.directory === directory) @@ -59,12 +246,10 @@ export function Layout(props: ParentProps) { async function loadSessions() { try { - console.log("[Layout] Loading sessions for:", directory) const res = await client.session.list({ roots: true }) const data = res.data if (Array.isArray(data)) { const valid = data.filter((s): s is Session => s && typeof s === "object" && typeof s.id === "string") - console.log("[Layout] Loaded sessions:", valid.length, "for current project:", projectSessions().length) setSessions(valid) } else { setSessions([]) @@ -80,19 +265,21 @@ export function Layout(props: ParentProps) { onMount(() => { loadSessions() - // Subscribe to session events const unsub = events.subscribe((event) => { if (event.type === "session.created" || event.type === "session.updated" || event.type === "session.deleted") { loadSessions() } }) - // Keyboard shortcut: Ctrl+` to toggle terminal function handleKeyDown(e: KeyboardEvent) { if (e.ctrlKey && e.key === "`") { e.preventDefault() terminal.toggle() } + if (e.ctrlKey && e.key === "b") { + e.preventDefault() + toggleSidebar() + } } window.addEventListener("keydown", handleKeyDown) @@ -107,7 +294,6 @@ export function Layout(props: ParentProps) { try { const res = await client.session.create({}) if (res.data) { - // Add new session to list immediately setSessions((prev) => [res.data as Session, ...prev]) navigate(`/${dirSlug()}/session/${res.data.id}`) } @@ -124,62 +310,151 @@ export function Layout(props: ParentProps) { return location.pathname.endsWith("/settings") } + function navigateToProject(worktree: string) { + navigate(`/${base64Encode(worktree)}/session`) + } + return (
- {/* Sidebar */} - +
+ + {/* Expand button when collapsed */} + + + {/* Main Content + Terminal */}
- {/* Main Content */}
{props.children}
- {/* Terminal Panel - always rendered when sessions exist, visibility controlled by CSS */} + {/* Terminal Panel */} 0}>
- {/* Terminal Header */}
- {/* Terminal tabs */} {(session) => (
- - - + {session.title}
)}
- {/* New terminal button */}
- {/* Close button */}
- {/* Terminal Content */}
{(session) => ( -
+
)} From b08187e1a80d45909c958baea96c65b9199e49c3 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sat, 24 Jan 2026 19:01:15 +0200 Subject: [PATCH 037/144] feat(prokube): add sidebar to home screen with accent-colored project avatars - Create HomeLayout component for root route with sidebar strip - Update ProjectPicker to show OpenCode logo and folder selection - Restyle project avatars with purple accent colors (light bg, solid when selected) - Remove random color generation, use consistent brand colors --- prokube/app-prefixable/src/app.tsx | 11 +- .../app-prefixable/src/pages/home-layout.tsx | 202 ++++++++++++ prokube/app-prefixable/src/pages/layout.tsx | 22 +- .../src/pages/project-picker.tsx | 310 ++++++++---------- 4 files changed, 361 insertions(+), 184 deletions(-) create mode 100644 prokube/app-prefixable/src/pages/home-layout.tsx diff --git a/prokube/app-prefixable/src/app.tsx b/prokube/app-prefixable/src/app.tsx index a3cae1a2896..702b43cb51c 100644 --- a/prokube/app-prefixable/src/app.tsx +++ b/prokube/app-prefixable/src/app.tsx @@ -1,11 +1,8 @@ import { Router, Route, Navigate } from "@solidjs/router" import { BasePathProvider, useBasePath } from "./context/base-path" -import { SDKProvider } from "./context/sdk" -import { EventProvider } from "./context/events" -import { ProviderProvider } from "./context/providers" import { CommandProvider } from "./context/command" import { DirectoryLayout } from "./pages/directory-layout" -import { Home } from "./pages/home" +import { HomeLayout } from "./pages/home-layout" import { Session } from "./pages/session" import { Settings } from "./pages/settings" import { ProjectPicker } from "./pages/project-picker" @@ -16,8 +13,10 @@ function AppRoutes() { return ( - {/* Root: Show project picker or redirect to last project */} - + {/* Root: Show project picker with sidebar */} + + + {/* Directory-scoped routes */} diff --git a/prokube/app-prefixable/src/pages/home-layout.tsx b/prokube/app-prefixable/src/pages/home-layout.tsx new file mode 100644 index 00000000000..d555d990674 --- /dev/null +++ b/prokube/app-prefixable/src/pages/home-layout.tsx @@ -0,0 +1,202 @@ +import { type ParentProps, createSignal, For, onMount } from "solid-js" +import { useNavigate } from "@solidjs/router" +import { base64Encode } from "../utils/path" +import { ProjectDialog } from "../components/project-dialog" + +// Storage key +const PROJECTS_STORAGE_KEY = "opencode.projects" + +interface Project { + worktree: string + name?: string +} + +function getFilename(path: string): string { + return path.split("/").filter(Boolean).pop() || path +} + +function getInitials(name: string): string { + return name + .split(/[-_\s]/) + .filter(Boolean) + .slice(0, 2) + .map((w) => w[0]?.toUpperCase() || "") + .join("") +} + +// Prokube Logo +function PkIcon(props: { class?: string }) { + return ( + + + + + + + ) +} + +function ProjectAvatar(props: { project: Project; size?: "small" | "large"; selected?: boolean }) { + const name = () => props.project.name || getFilename(props.project.worktree) + const initials = () => getInitials(name()) + const size = () => (props.size === "large" ? "w-10 h-10" : "w-8 h-8") + + return ( +
+ {initials()} +
+ ) +} + +function PlusIcon(props: { class?: string }) { + return ( + + + + ) +} + +function CloseIcon(props: { class?: string }) { + return ( + + + + ) +} + +/** + * Layout for the home screen (no active project). + * Shows the left sidebar strip with projects, but no sessions panel. + */ +export function HomeLayout(props: ParentProps) { + const navigate = useNavigate() + + const [projects, setProjects] = createSignal([]) + const [projectDialogOpen, setProjectDialogOpen] = createSignal(false) + + onMount(() => { + try { + const stored = localStorage.getItem(PROJECTS_STORAGE_KEY) + if (stored) { + setProjects(JSON.parse(stored)) + } + } catch (e) { + console.error("Failed to load projects:", e) + } + }) + + function saveProjects(list: Project[]) { + setProjects(list) + try { + localStorage.setItem(PROJECTS_STORAGE_KEY, JSON.stringify(list)) + } catch (e) { + console.error("Failed to save projects:", e) + } + } + + function addProject(worktree: string) { + const existing = projects().find((p) => p.worktree === worktree) + if (!existing) { + saveProjects([...projects(), { worktree }]) + } + } + + function removeProject(worktree: string) { + saveProjects(projects().filter((p) => p.worktree !== worktree)) + } + + function handleProjectSelect(worktree: string) { + addProject(worktree) + navigate(`/${base64Encode(worktree)}/session`) + } + + function navigateToProject(worktree: string) { + navigate(`/${base64Encode(worktree)}/session`) + } + + return ( +
+ {/* Project Dialog */} + setProjectDialogOpen(false)} + onSelect={handleProjectSelect} + /> + + {/* Left: Project Icons Strip */} +
+ {/* Prokube Logo */} + + + {/* Project icons */} +
+ + {(project) => ( +
navigateToProject(project.worktree)} + class="group relative cursor-pointer" + title={project.name || getFilename(project.worktree)} + > + + +
+ )} +
+ + {/* Add project button */} + +
+
+ + {/* Main Content */} +
+ {props.children} +
+
+ ) +} diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index 6f404cb8d23..c1db1107cfc 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -34,15 +34,6 @@ function getInitials(name: string): string { .join("") } -function getColorFromString(str: string): string { - let hash = 0 - for (let i = 0; i < str.length; i++) { - hash = str.charCodeAt(i) + ((hash << 5) - hash) - } - const hue = Math.abs(hash) % 360 - return `hsl(${hue}, 60%, 45%)` -} - // Prokube Logo function PkIcon(props: { class?: string }) { return ( @@ -64,15 +55,20 @@ function PkIcon(props: { class?: string }) { function ProjectAvatar(props: { project: Project; size?: "small" | "large"; selected?: boolean }) { const name = () => props.project.name || getFilename(props.project.worktree) const initials = () => getInitials(name()) - const color = () => getColorFromString(props.project.worktree) const size = () => (props.size === "large" ? "w-10 h-10" : "w-8 h-8") + // Use accent color with transparency for background, stronger for selected return (
{initials()} diff --git a/prokube/app-prefixable/src/pages/project-picker.tsx b/prokube/app-prefixable/src/pages/project-picker.tsx index 63d6ad57d5c..8e85b17c2b7 100644 --- a/prokube/app-prefixable/src/pages/project-picker.tsx +++ b/prokube/app-prefixable/src/pages/project-picker.tsx @@ -6,24 +6,34 @@ import { base64Encode } from "../utils/path" import { Spinner } from "@opencode-ai/ui/spinner" import { Button } from "@opencode-ai/ui/button" -// Prokube icon (PK logo) -function PkIcon(props: { class?: string }) { +// OpenCode Logo +function OpenCodeLogo(props: { class?: string }) { return ( - - - - + + + + + + ) +} + +function FolderIcon(props: { class?: string }) { + return ( + ) } +/** + * Project picker content - shown inside HomeLayout. + * Displays OpenCode logo and folder selection options. + */ export function ProjectPicker() { const { serverUrl } = useBasePath() const navigate = useNavigate() @@ -35,10 +45,8 @@ export function ProjectPicker() { const [searching, setSearching] = createSignal(false) const [newFolderName, setNewFolderName] = createSignal("") - // Create a client without directory to fetch global data const client = createOpencodeClient({ baseUrl: serverUrl, throwOnError: false }) - // Fetch home directory from server on mount onMount(async () => { try { const res = await client.path.get() @@ -54,7 +62,6 @@ export function ProjectPicker() { navigate(`/${base64Encode(worktree)}/session`) } - // Search for folders async function searchFolders(query: string) { const home = homeDirectory() if (!query.trim() || !home) { @@ -80,7 +87,6 @@ export function ProjectPicker() { } } - // Create a new folder - just navigate to it function createFolder() { const home = homeDirectory() const name = newFolderName().trim() @@ -89,7 +95,6 @@ export function ProjectPicker() { selectProject(fullPath) } - // Open a specific folder path function openFolderPath() { const path = folderPath().trim() if (path) { @@ -98,170 +103,145 @@ export function ProjectPicker() { } return ( -
- {/* Header */} -
- -

- prokube.ai -

-
- - {/* Main content */} -
-
- {/* Title */} -
-

- Open a Folder -

-

Choose a folder to start working with OpenCode

+
+
+ {/* Logo and Title */} +
+
+
+

+ OpenCode +

+

Choose a folder to start working

+
- {/* Search for folder */} -
- + {/* Search for folder */} +
+ + { + setFolderSearch(e.currentTarget.value) + searchFolders(e.currentTarget.value) + }} + placeholder={`Type to search in ${homeDirectory() ?? "..."}...`} + class="w-full px-3 py-2 rounded-md text-sm" + style={{ + background: "var(--background-stronger)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + /> + + +
+ +
+
+ + 0}> +
+ + {(path) => ( + + )} + +
+
+
+ + {/* Direct path input */} +
+ +
{ - setFolderSearch(e.currentTarget.value) - searchFolders(e.currentTarget.value) - }} - placeholder={`Type to search in ${homeDirectory() ?? "..."}...`} - class="w-full px-3 py-2 rounded-md text-sm" + value={folderPath()} + onInput={(e) => setFolderPath(e.currentTarget.value)} + placeholder="/home/jovyan/my-project" + class="flex-1 px-3 py-2 rounded-md text-sm" style={{ background: "var(--background-stronger)", border: "1px solid var(--border-base)", color: "var(--text-base)", }} + onKeyDown={(e) => e.key === "Enter" && openFolderPath()} /> - - {/* Search results */} - -
- -
-
- - 0}> -
- - {(path) => ( - - )} - -
-
-
- - {/* Direct path input */} -
- -
- setFolderPath(e.currentTarget.value)} - placeholder="/home/jovyan/my-project" - class="flex-1 px-3 py-2 rounded-md text-sm" - style={{ - background: "var(--background-stronger)", - border: "1px solid var(--border-base)", - color: "var(--text-base)", - }} - onKeyDown={(e) => e.key === "Enter" && openFolderPath()} - /> - -
+
+
- {/* Create new folder */} -
- -
- setNewFolderName(e.currentTarget.value)} - placeholder="my-new-project" - class="flex-1 px-3 py-2 rounded-md text-sm" - style={{ - background: "var(--background-stronger)", - border: "1px solid var(--border-base)", - color: "var(--text-base)", - }} - onKeyDown={(e) => e.key === "Enter" && createFolder()} - /> - -
- -

- Will open: {homeDirectory()}/{newFolderName()} -

-
+ {/* Create new folder */} +
+ +
+ setNewFolderName(e.currentTarget.value)} + placeholder="my-new-project" + class="flex-1 px-3 py-2 rounded-md text-sm" + style={{ + background: "var(--background-stronger)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + onKeyDown={(e) => e.key === "Enter" && createFolder()} + /> +
- - {/* Quick access to home directory */} - -
- -
+ +

+ Will open: {homeDirectory()}/{newFolderName()} +

-
+ + {/* Quick access to home directory */} + +
+ +
+
+
) } From 0f2a381d2570666f8f113cd9612c65b13a56158b Mon Sep 17 00:00:00 2001 From: hsteude Date: Sat, 24 Jan 2026 19:06:08 +0200 Subject: [PATCH 038/144] feat(prokube): add 'Powered by Prokube' branding to home screen - Add Prokube logo next to 'Powered by' text - Link to prokube.ai website - Keep OpenCode logo as main branding --- .../src/pages/project-picker.tsx | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/prokube/app-prefixable/src/pages/project-picker.tsx b/prokube/app-prefixable/src/pages/project-picker.tsx index 8e85b17c2b7..6a7ac83b561 100644 --- a/prokube/app-prefixable/src/pages/project-picker.tsx +++ b/prokube/app-prefixable/src/pages/project-picker.tsx @@ -17,6 +17,24 @@ function OpenCodeLogo(props: { class?: string }) { ) } +// Prokube Logo +function ProkubeLogo(props: { class?: string }) { + return ( + + + + + + + ) +} + function FolderIcon(props: { class?: string }) { return ( @@ -113,6 +131,20 @@ export function ProjectPicker() {

OpenCode

+
+ Powered by + + + + Prokube + + +

Choose a folder to start working

From 84201ce301509fb3e9fad4101c9da9b40801a41c Mon Sep 17 00:00:00 2001 From: hsteude Date: Sat, 24 Jan 2026 19:12:28 +0200 Subject: [PATCH 039/144] fix(prokube): use official OpenCode logo and lowercase prokube - Replace terminal-style icon with official OpenCode 'O' mark - Change 'Prokube' to 'prokube' in branding text --- .../app-prefixable/src/pages/project-picker.tsx | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/prokube/app-prefixable/src/pages/project-picker.tsx b/prokube/app-prefixable/src/pages/project-picker.tsx index 6a7ac83b561..a557de738a9 100644 --- a/prokube/app-prefixable/src/pages/project-picker.tsx +++ b/prokube/app-prefixable/src/pages/project-picker.tsx @@ -6,13 +6,18 @@ import { base64Encode } from "../utils/path" import { Spinner } from "@opencode-ai/ui/spinner" import { Button } from "@opencode-ai/ui/button" -// OpenCode Logo +// OpenCode Logo (official mark) function OpenCodeLogo(props: { class?: string }) { return ( - - - - + + + + ) } @@ -141,7 +146,7 @@ export function ProjectPicker() { > - Prokube + prokube
From 56899494a1c9c8f44f01b0174d15dcd0a35016e4 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sat, 24 Jan 2026 19:29:39 +0200 Subject: [PATCH 040/144] feat(prokube): update logos with new OpenCode branding - Replace sidebar icon with OpenCode 'O' logo (opencode-logo-light) - Use OpenCode wordmark on home screen (opencode-wordmark-light) - Remove Prokube logo from sidebar, keep only in 'Powered by' section --- .../app-prefixable/src/pages/home-layout.tsx | 20 +++---- prokube/app-prefixable/src/pages/layout.tsx | 20 +++---- .../src/pages/project-picker.tsx | 54 ++++++++++++++----- 3 files changed, 52 insertions(+), 42 deletions(-) diff --git a/prokube/app-prefixable/src/pages/home-layout.tsx b/prokube/app-prefixable/src/pages/home-layout.tsx index d555d990674..72e00655590 100644 --- a/prokube/app-prefixable/src/pages/home-layout.tsx +++ b/prokube/app-prefixable/src/pages/home-layout.tsx @@ -24,20 +24,12 @@ function getInitials(name: string): string { .join("") } -// Prokube Logo -function PkIcon(props: { class?: string }) { +// OpenCode Logo +function OpenCodeLogo(props: { class?: string }) { return ( - - - - - + + + ) } @@ -152,7 +144,7 @@ export function HomeLayout(props: ParentProps) { style={{ "border-bottom": "1px solid var(--border-base)" }} title="Open Project" > - + {/* Project icons */} diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index c1db1107cfc..f699decbe8c 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -34,20 +34,12 @@ function getInitials(name: string): string { .join("") } -// Prokube Logo -function PkIcon(props: { class?: string }) { +// OpenCode Logo +function OpenCodeLogo(props: { class?: string }) { return ( - - - - - + + + ) } @@ -331,7 +323,7 @@ export function Layout(props: ParentProps) { style={{ "border-bottom": "1px solid var(--border-base)" }} title="Open Project" > - + {/* Project icons */} diff --git a/prokube/app-prefixable/src/pages/project-picker.tsx b/prokube/app-prefixable/src/pages/project-picker.tsx index a557de738a9..b0a9ae78ea3 100644 --- a/prokube/app-prefixable/src/pages/project-picker.tsx +++ b/prokube/app-prefixable/src/pages/project-picker.tsx @@ -6,17 +6,46 @@ import { base64Encode } from "../utils/path" import { Spinner } from "@opencode-ai/ui/spinner" import { Button } from "@opencode-ai/ui/button" -// OpenCode Logo (official mark) -function OpenCodeLogo(props: { class?: string }) { +// OpenCode Wordmark +function OpenCodeWordmark(props: { class?: string }) { return ( - - - + + + + + + + + + + + + + + + + ) @@ -130,12 +159,9 @@ export function ProjectPicker() {
{/* Logo and Title */}
-
- +
+
-

- OpenCode -

Powered by Date: Sat, 24 Jan 2026 19:31:50 +0200 Subject: [PATCH 041/144] fix(prokube): make wordmark larger and fix create folder button - Increase wordmark height from h-12 to h-16 - Disable create button when homeDirectory is not loaded --- prokube/app-prefixable/src/pages/project-picker.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prokube/app-prefixable/src/pages/project-picker.tsx b/prokube/app-prefixable/src/pages/project-picker.tsx index b0a9ae78ea3..3c8c5d2cf95 100644 --- a/prokube/app-prefixable/src/pages/project-picker.tsx +++ b/prokube/app-prefixable/src/pages/project-picker.tsx @@ -160,7 +160,7 @@ export function ProjectPicker() { {/* Logo and Title */}
- +
Powered by @@ -279,7 +279,7 @@ export function ProjectPicker() { }} onKeyDown={(e) => e.key === "Enter" && createFolder()} /> -
From d83247e3a309b3f40ea4560a96bc05c5584c68d9 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 14:55:09 +0200 Subject: [PATCH 042/144] feat(prokube): improve sidebar UX and fix button alignment - Add session archive button (visible on hover) - Terminal opens in project directory (pass cwd to PTY) - OpenCode logo navigates to home screen - Project switching works with full page reload - Selected project shows purple border - Sidebar auto-opens when selecting a project - Fix icon/text alignment in buttons with flex wrapper --- packages/ui/src/components/button.css | 6 + .../app-prefixable/src/context/terminal.tsx | 18 +-- prokube/app-prefixable/src/pages/home.tsx | 46 +++--- prokube/app-prefixable/src/pages/layout.tsx | 143 +++++++++++++----- .../src/pages/project-picker.tsx | 4 +- prokube/app-prefixable/src/pages/session.tsx | 51 ++++--- 6 files changed, 172 insertions(+), 96 deletions(-) diff --git a/packages/ui/src/components/button.css b/packages/ui/src/components/button.css index d9b34592304..096de5de49b 100644 --- a/packages/ui/src/components/button.css +++ b/packages/ui/src/components/button.css @@ -11,6 +11,12 @@ outline: none; white-space: nowrap; + /* Ensure SVG icons are properly aligned */ + svg { + flex-shrink: 0; + display: block; + } + &[data-variant="primary"] { background-color: var(--button-primary-base); border-color: var(--border-weak-base); diff --git a/prokube/app-prefixable/src/context/terminal.tsx b/prokube/app-prefixable/src/context/terminal.tsx index 0650062f17f..80b37ded753 100644 --- a/prokube/app-prefixable/src/context/terminal.tsx +++ b/prokube/app-prefixable/src/context/terminal.tsx @@ -11,11 +11,11 @@ interface TerminalContextValue { active: () => string | null opened: () => boolean height: () => number - create: () => Promise + create: (cwd?: string) => Promise close: (id: string) => Promise setActive: (id: string | null) => void - toggle: () => void - open: () => void + toggle: (cwd?: string) => void + open: (cwd?: string) => void setHeight: (h: number) => void } @@ -28,9 +28,9 @@ export function TerminalProvider(props: ParentProps) { const [opened, setOpened] = createSignal(false) const [height, setHeight] = createSignal(280) - async function create(): Promise { + async function create(cwd?: string): Promise { try { - const res = await client.pty.create({}) + const res = await client.pty.create({ cwd }) if (res.data) { const session: PTYSession = { id: res.data.id, @@ -63,21 +63,21 @@ export function TerminalProvider(props: ParentProps) { } } - function toggle() { + function toggle(cwd?: string) { if (opened()) { setOpened(false) } else { if (sessions().length === 0) { - create() + create(cwd) } else { setOpened(true) } } } - function open() { + function open(cwd?: string) { if (sessions().length === 0) { - create() + create(cwd) } else { setOpened(true) } diff --git a/prokube/app-prefixable/src/pages/home.tsx b/prokube/app-prefixable/src/pages/home.tsx index 9c073165cf9..a3fbe271617 100644 --- a/prokube/app-prefixable/src/pages/home.tsx +++ b/prokube/app-prefixable/src/pages/home.tsx @@ -101,28 +101,32 @@ export function Home() { {/* Action buttons */}
- -
diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index f699decbe8c..514129a8506 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -49,18 +49,14 @@ function ProjectAvatar(props: { project: Project; size?: "small" | "large"; sele const initials = () => getInitials(name()) const size = () => (props.size === "large" ? "w-10 h-10" : "w-8 h-8") - // Use accent color with transparency for background, stronger for selected + // Same background always, purple border when selected (like chat input focus state) return (
{initials()} @@ -117,6 +113,19 @@ function ChatIcon(props: { class?: string }) { ) } +function ArchiveIcon(props: { class?: string }) { + return ( + + + + ) +} + function CloseIcon(props: { class?: string }) { return ( @@ -140,6 +149,7 @@ function ChevronIcon(props: { class?: string; direction: "left" | "right" | "dow export function Layout(props: ParentProps) { const { client, directory } = useSDK() + const { basePath } = useBasePath() const events = useEvents() const providers = useProviders() const terminal = useTerminal() @@ -164,11 +174,14 @@ export function Layout(props: ParentProps) { console.error("Failed to load projects:", e) } - // Load sidebar state + // Load sidebar state - default to open when a project is active try { const expanded = localStorage.getItem(SIDEBAR_EXPANDED_KEY) if (expanded !== null) { setSidebarExpanded(expanded === "true") + } else if (directory) { + // Default to open when viewing a project + setSidebarExpanded(true) } } catch (e) { console.error("Failed to load sidebar state:", e) @@ -177,6 +190,9 @@ export function Layout(props: ParentProps) { // Add current directory to projects if not present if (directory) { addProject(directory) + // Ensure sidebar is open when navigating to a project + setSidebarExpanded(true) + localStorage.setItem(SIDEBAR_EXPANDED_KEY, "true") } }) @@ -262,7 +278,7 @@ export function Layout(props: ParentProps) { function handleKeyDown(e: KeyboardEvent) { if (e.ctrlKey && e.key === "`") { e.preventDefault() - terminal.toggle() + terminal.toggle(directory) } if (e.ctrlKey && e.key === "b") { e.preventDefault() @@ -290,6 +306,30 @@ export function Layout(props: ParentProps) { } } + async function archiveSession(session: Session) { + const currentSessions = projectSessions() + const index = currentSessions.findIndex((s) => s.id === session.id) + const nextSession = currentSessions[index + 1] ?? currentSessions[index - 1] + + try { + await client.session.update({ + sessionID: session.id, + time: { archived: Date.now() }, + }) + setSessions((prev) => prev.filter((s) => s.id !== session.id)) + + if (isActive(session.id)) { + if (nextSession) { + navigate(`/${dirSlug()}/session/${nextSession.id}`) + } else { + navigate(`/${dirSlug()}/session`) + } + } + } catch (e) { + console.error("Failed to archive session:", e) + } + } + function isActive(sessionId: string) { return location.pathname.includes(sessionId) } @@ -299,7 +339,14 @@ export function Layout(props: ParentProps) { } function navigateToProject(worktree: string) { - navigate(`/${base64Encode(worktree)}/session`) + // Force a full page reload when switching projects + // because the SDK context is tied to the directory + const base = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath + window.location.href = `${base}/${base64Encode(worktree)}/session` + } + + function navigateToHome() { + navigate("/") } return ( @@ -316,12 +363,12 @@ export function Layout(props: ParentProps) { class="w-16 shrink-0 flex flex-col items-center" style={{ background: "var(--background-base)", "border-right": "1px solid var(--border-base)" }} > - {/* Prokube Logo */} + {/* OpenCode Logo - navigates to home */} @@ -370,7 +417,7 @@ export function Layout(props: ParentProps) { {/* Bottom icons */}
@@ -455,25 +504,41 @@ export function Layout(props: ParentProps) {
{(session) => ( - { - if (!isActive(session.id)) e.currentTarget.style.background = "var(--surface-inset)" - }} - onMouseLeave={(e) => { - if (!isActive(session.id)) e.currentTarget.style.background = "transparent" - }} - > - - - - {session.title || "Untitled"} - +
+ { + if (!isActive(session.id)) e.currentTarget.style.background = "var(--surface-inset)" + }} + onMouseLeave={(e) => { + if (!isActive(session.id)) e.currentTarget.style.background = "transparent" + }} + > + + + + {session.title || "Untitled"} + + +
)}
@@ -567,7 +632,7 @@ export function Layout(props: ParentProps) { )}
-
From a53437eb3f8278ff894dcea092aa2a2488fb8635 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 15:11:08 +0200 Subject: [PATCH 043/144] fix(prokube): revert button.css change and add powered by prokube to session - Revert button.css change (outside prokube folder) - Add 'Powered by prokube' to session welcome screen - Fix alignment to match project picker --- packages/ui/src/components/button.css | 6 ----- prokube/app-prefixable/src/pages/session.tsx | 28 +++++++++++++++++--- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/packages/ui/src/components/button.css b/packages/ui/src/components/button.css index 096de5de49b..d9b34592304 100644 --- a/packages/ui/src/components/button.css +++ b/packages/ui/src/components/button.css @@ -11,12 +11,6 @@ outline: none; white-space: nowrap; - /* Ensure SVG icons are properly aligned */ - svg { - flex-shrink: 0; - display: block; - } - &[data-variant="primary"] { background-color: var(--button-primary-base); border-color: var(--border-weak-base); diff --git a/prokube/app-prefixable/src/pages/session.tsx b/prokube/app-prefixable/src/pages/session.tsx index 10e8ec5a174..46950c2fd51 100644 --- a/prokube/app-prefixable/src/pages/session.tsx +++ b/prokube/app-prefixable/src/pages/session.tsx @@ -547,9 +547,31 @@ export function Session() {
-

- AI-powered coding assistant -

+ {/* Action buttons */}
From 27605e187a97ebd08a7698fa7bc453230980ab8e Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 15:45:01 +0200 Subject: [PATCH 044/144] feat(prokube): migrate to Lucide icons, add settings icons, fix avatar fallback, responsive sidebar - Migrate all SVG icons to lucide-solid package - Add icons to Settings tabs (Providers, Git, MCP, Models, Agents) - Fix ProjectAvatar to show Folder icon for invalid/encoded names - Add Settings button to home screen sidebar - Auto-hide sessions sidebar on Settings page - Auto-collapse sidebar on small screens (<900px) --- bun.lock | 3 + prokube/app-prefixable/package.json | 1 + .../src/components/mcp-add-dialog.tsx | 37 +- .../src/components/mcp-dialog.tsx | 9 +- .../src/components/project-dialog.tsx | 28 +- .../src/components/tool-part.tsx | 10 +- .../app-prefixable/src/pages/home-layout.tsx | 44 +- prokube/app-prefixable/src/pages/home.tsx | 20 +- prokube/app-prefixable/src/pages/layout.tsx | 161 +++---- .../src/pages/project-picker.tsx | 16 +- prokube/app-prefixable/src/pages/session.tsx | 55 +-- prokube/app-prefixable/src/pages/settings.tsx | 402 ++++++++++++++++-- 12 files changed, 477 insertions(+), 309 deletions(-) diff --git a/bun.lock b/bun.lock index 15bbcec1075..3795d3837c0 100644 --- a/bun.lock +++ b/bun.lock @@ -495,6 +495,7 @@ "@solidjs/router": "catalog:", "@xterm/addon-fit": "0.11.0", "@xterm/xterm": "6.0.0", + "lucide-solid": "0.563.0", "marked": "catalog:", "solid-js": "catalog:", }, @@ -2973,6 +2974,8 @@ "lru_map": ["lru_map@0.4.1", "", {}, "sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg=="], + "lucide-solid": ["lucide-solid@0.563.0", "", { "peerDependencies": { "solid-js": "^1.4.7" } }, "sha512-Ort9I6BaKdarM/e0VwWddcd9tuven/y0wHqfXIPNzPPe3zwXtIZJDjR2UcAj2XBCfx1aHw/SWiLHPvn9O1Fniw=="], + "luxon": ["luxon@3.6.1", "", {}, "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], diff --git a/prokube/app-prefixable/package.json b/prokube/app-prefixable/package.json index dc8109e4bc6..bda8d82304f 100644 --- a/prokube/app-prefixable/package.json +++ b/prokube/app-prefixable/package.json @@ -16,6 +16,7 @@ "@solidjs/router": "catalog:", "@xterm/addon-fit": "0.11.0", "@xterm/xterm": "6.0.0", + "lucide-solid": "0.563.0", "marked": "catalog:", "solid-js": "catalog:" }, diff --git a/prokube/app-prefixable/src/components/mcp-add-dialog.tsx b/prokube/app-prefixable/src/components/mcp-add-dialog.tsx index 9c4387ebe49..53880cc209e 100644 --- a/prokube/app-prefixable/src/components/mcp-add-dialog.tsx +++ b/prokube/app-prefixable/src/components/mcp-add-dialog.tsx @@ -1,5 +1,6 @@ import { createSignal, Show, For } from "solid-js" import { useMCP, type McpLocalConfig, type McpRemoteConfig } from "../context/mcp" +import { X, ChevronLeft, ChevronRight } from "lucide-solid" interface Props { onClose: () => void @@ -199,9 +200,7 @@ export function MCPAddDialog(props: Props) { onMouseEnter={(e) => (e.currentTarget.style.background = "var(--surface-inset)")} onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")} > - - - +

@@ -215,9 +214,7 @@ export function MCPAddDialog(props: Props) { onMouseEnter={(e) => (e.currentTarget.style.background = "var(--surface-inset)")} onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")} > - - - +

@@ -311,15 +308,7 @@ export function MCPAddDialog(props: Props) { class="flex items-center gap-2 text-sm" style={{ color: "var(--text-interactive-base)" }} > - - - + Advanced Options @@ -385,14 +374,7 @@ export function MCPAddDialog(props: Props) { class="p-1.5 rounded" style={{ color: "var(--icon-critical-base)" }} > - - - +
)} @@ -446,14 +428,7 @@ export function MCPAddDialog(props: Props) { class="p-1.5 rounded" style={{ color: "var(--icon-critical-base)" }} > - - - +
)} diff --git a/prokube/app-prefixable/src/components/mcp-dialog.tsx b/prokube/app-prefixable/src/components/mcp-dialog.tsx index cc5fef649b8..4e6809bfd64 100644 --- a/prokube/app-prefixable/src/components/mcp-dialog.tsx +++ b/prokube/app-prefixable/src/components/mcp-dialog.tsx @@ -1,5 +1,6 @@ import { createSignal, createMemo, Show, For } from "solid-js" import { useMCP } from "../context/mcp" +import { X, Plus } from "lucide-solid" interface Props { onClose: () => void @@ -102,9 +103,7 @@ export function MCPDialog(props: Props) { onMouseEnter={(e) => (e.currentTarget.style.background = "var(--surface-inset)")} onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")} > - - - +
@@ -207,9 +206,7 @@ export function MCPDialog(props: Props) { onMouseEnter={(e) => (e.currentTarget.style.opacity = "0.9")} onMouseLeave={(e) => (e.currentTarget.style.opacity = "1")} > - - - + Add MCP Server
diff --git a/prokube/app-prefixable/src/components/project-dialog.tsx b/prokube/app-prefixable/src/components/project-dialog.tsx index a1f0d6255c9..5ea1dbedc3d 100644 --- a/prokube/app-prefixable/src/components/project-dialog.tsx +++ b/prokube/app-prefixable/src/components/project-dialog.tsx @@ -3,6 +3,7 @@ import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" import { useBasePath } from "../context/base-path" import { Spinner } from "@opencode-ai/ui/spinner" import { Button } from "@opencode-ai/ui/button" +import { Folder, X } from "lucide-solid" interface ProjectDialogProps { open: boolean @@ -10,27 +11,6 @@ interface ProjectDialogProps { onSelect: (worktree: string) => void } -function FolderIcon(props: { class?: string }) { - return ( - - - - ) -} - -function CloseIcon(props: { class?: string }) { - return ( - - - - ) -} - export function ProjectDialog(props: ProjectDialogProps) { const { serverUrl } = useBasePath() @@ -139,7 +119,7 @@ export function ProjectDialog(props: ProjectDialogProps) { class="p-1 rounded-md transition-colors" style={{ color: "var(--icon-base)" }} > - +
@@ -183,7 +163,7 @@ export function ProjectDialog(props: ProjectDialogProps) { onMouseEnter={(e) => (e.currentTarget.style.background = "var(--surface-inset)")} onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")} > - + {path} )} @@ -257,7 +237,7 @@ export function ProjectDialog(props: ProjectDialogProps) { onMouseEnter={(e) => (e.currentTarget.style.background = "var(--surface-inset)")} onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")} > - + Open home directory ({homeDirectory()})
diff --git a/prokube/app-prefixable/src/components/tool-part.tsx b/prokube/app-prefixable/src/components/tool-part.tsx index 57e8c2c49c3..7d9e9eeb8bf 100644 --- a/prokube/app-prefixable/src/components/tool-part.tsx +++ b/prokube/app-prefixable/src/components/tool-part.tsx @@ -1,5 +1,6 @@ import { createSignal, Show, For } from "solid-js" import type { Part, ToolPart as SDKToolPart, ToolState } from "@opencode-ai/sdk/v2/client" +import { ChevronDown } from "lucide-solid" // Use the SDK's ToolPart type type ToolPart = SDKToolPart @@ -147,18 +148,13 @@ export function ToolPartDisplay(props: { part: ToolPart }) { {/* Expand arrow */} - - - + /> diff --git a/prokube/app-prefixable/src/pages/home-layout.tsx b/prokube/app-prefixable/src/pages/home-layout.tsx index 72e00655590..09b68b2c6d1 100644 --- a/prokube/app-prefixable/src/pages/home-layout.tsx +++ b/prokube/app-prefixable/src/pages/home-layout.tsx @@ -2,6 +2,7 @@ import { type ParentProps, createSignal, For, onMount } from "solid-js" import { useNavigate } from "@solidjs/router" import { base64Encode } from "../utils/path" import { ProjectDialog } from "../components/project-dialog" +import { Plus, X, Settings, Folder } from "lucide-solid" // Storage key const PROJECTS_STORAGE_KEY = "opencode.projects" @@ -16,12 +17,16 @@ function getFilename(path: string): string { } function getInitials(name: string): string { - return name + // Only use ASCII letters for initials + const clean = name.replace(/[^a-zA-Z0-9\s_-]/g, "") + if (!clean) return "" + const parts = clean .split(/[-_\s]/) .filter(Boolean) .slice(0, 2) .map((w) => w[0]?.toUpperCase() || "") .join("") + return parts } // OpenCode Logo @@ -38,6 +43,7 @@ function ProjectAvatar(props: { project: Project; size?: "small" | "large"; sele const name = () => props.project.name || getFilename(props.project.worktree) const initials = () => getInitials(name()) const size = () => (props.size === "large" ? "w-10 h-10" : "w-8 h-8") + const iconSize = () => (props.size === "large" ? "w-5 h-5" : "w-4 h-4") return (
- {initials()} + {initials() || }
) } -function PlusIcon(props: { class?: string }) { - return ( - - - - ) -} - -function CloseIcon(props: { class?: string }) { - return ( - - - - ) -} - /** * Layout for the home screen (no active project). * Shows the left sidebar strip with projects, but no sessions panel. @@ -165,7 +155,7 @@ export function HomeLayout(props: ParentProps) { class="absolute -top-1 -right-1 w-4 h-4 rounded-full hidden group-hover:flex items-center justify-center" style={{ background: "var(--surface-strong)", color: "var(--text-base)" }} > - +
)} @@ -180,7 +170,21 @@ export function HomeLayout(props: ParentProps) { onMouseLeave={(e) => (e.currentTarget.style.borderColor = "var(--border-base)")} title="Open Project" > - + + +
+ + {/* Bottom: Settings */} +
+
diff --git a/prokube/app-prefixable/src/pages/home.tsx b/prokube/app-prefixable/src/pages/home.tsx index a3fbe271617..70367777b87 100644 --- a/prokube/app-prefixable/src/pages/home.tsx +++ b/prokube/app-prefixable/src/pages/home.tsx @@ -2,6 +2,7 @@ import { useNavigate } from "@solidjs/router" import { Button } from "@opencode-ai/ui/button" import { useSDK } from "../context/sdk" import { base64Encode } from "../utils/path" +import { Plus, Settings } from "lucide-solid" // OpenCode wordmark SVG (light version for dark backgrounds) function OpenCodeLogo(props: { class?: string; style?: Record }) { @@ -103,28 +104,13 @@ export function Home() {
diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index 514129a8506..0273a3b8074 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -1,4 +1,4 @@ -import { type ParentProps, createSignal, For, Show, onMount, createMemo, onCleanup } from "solid-js" +import { type ParentProps, createSignal, For, Show, onMount, createMemo, onCleanup, createEffect } from "solid-js" import { A, useLocation, useNavigate, useParams } from "@solidjs/router" import { useBasePath } from "../context/base-path" import { useSDK } from "../context/sdk" @@ -11,6 +11,18 @@ import { Button } from "@opencode-ai/ui/button" import { Terminal } from "../components/terminal" import { ProjectDialog } from "../components/project-dialog" import type { Session } from "@opencode-ai/sdk/v2/client" +import { + Plus, + Settings, + SquareTerminal, + MessageCircle, + Archive, + X, + ChevronLeft, + ChevronRight, + ChevronDown, + Folder, +} from "lucide-solid" // Storage keys const PROJECTS_STORAGE_KEY = "opencode.projects" @@ -26,12 +38,16 @@ function getFilename(path: string): string { } function getInitials(name: string): string { - return name + // Only use ASCII letters for initials + const clean = name.replace(/[^a-zA-Z0-9\s_-]/g, "") + if (!clean) return "" + const parts = clean .split(/[-_\s]/) .filter(Boolean) .slice(0, 2) .map((w) => w[0]?.toUpperCase() || "") .join("") + return parts } // OpenCode Logo @@ -48,8 +64,8 @@ function ProjectAvatar(props: { project: Project; size?: "small" | "large"; sele const name = () => props.project.name || getFilename(props.project.worktree) const initials = () => getInitials(name()) const size = () => (props.size === "large" ? "w-10 h-10" : "w-8 h-8") + const iconSize = () => (props.size === "large" ? "w-5 h-5" : "w-4 h-4") - // Same background always, purple border when selected (like chat input focus state) return (
- {initials()} + {initials() || }
) } -// Icons -function PlusIcon(props: { class?: string }) { - return ( - - - - ) -} - -function SettingsIcon(props: { class?: string }) { - return ( - - - - - ) -} - -function TerminalIcon(props: { class?: string }) { - return ( - - - - ) -} - -function ChatIcon(props: { class?: string }) { - return ( - - - - ) -} - -function ArchiveIcon(props: { class?: string }) { - return ( - - - - ) -} - -function CloseIcon(props: { class?: string }) { - return ( - - - - ) -} - -function ChevronIcon(props: { class?: string; direction: "left" | "right" | "down" }) { - const path = () => { - if (props.direction === "left") return "M15 19l-7-7 7-7" - if (props.direction === "right") return "M9 5l7 7-7 7" - return "M19 9l-7 7-7-7" - } - return ( - - - - ) -} - export function Layout(props: ParentProps) { const { client, directory } = useSDK() const { basePath } = useBasePath() @@ -161,6 +94,17 @@ export function Layout(props: ParentProps) { const [projects, setProjects] = createSignal([]) const [sidebarExpanded, setSidebarExpanded] = createSignal(true) const [projectDialogOpen, setProjectDialogOpen] = createSignal(false) + const [windowWidth, setWindowWidth] = createSignal(typeof window !== "undefined" ? window.innerWidth : 1200) + + // Responsive breakpoint - collapse sidebar below 900px + const COLLAPSE_BREAKPOINT = 900 + + // Effective sidebar state: hidden on settings page or small screens + const showSidebar = createMemo(() => { + if (location.pathname.endsWith("/settings")) return false + if (windowWidth() < COLLAPSE_BREAKPOINT) return false + return sidebarExpanded() + }) // Load state from storage onMount(() => { @@ -194,6 +138,13 @@ export function Layout(props: ParentProps) { setSidebarExpanded(true) localStorage.setItem(SIDEBAR_EXPANDED_KEY, "true") } + + // Resize listener for responsive sidebar + function handleResize() { + setWindowWidth(window.innerWidth) + } + window.addEventListener("resize", handleResize) + onCleanup(() => window.removeEventListener("resize", handleResize)) }) function saveProjects(list: Project[]) { @@ -395,7 +346,7 @@ export function Layout(props: ParentProps) { class="absolute -top-1 -right-1 w-4 h-4 rounded-full hidden group-hover:flex items-center justify-center" style={{ background: "var(--surface-strong)", color: "var(--text-base)" }} > - +
)} @@ -410,7 +361,7 @@ export function Layout(props: ParentProps) { onMouseLeave={(e) => (e.currentTarget.style.borderColor = "var(--border-base)")} title="Open Project" > - +
@@ -425,7 +376,7 @@ export function Layout(props: ParentProps) { }} title="Terminal (Ctrl+`)" > - +
@@ -445,10 +396,10 @@ export function Layout(props: ParentProps) {
@@ -469,7 +420,7 @@ export function Layout(props: ParentProps) { style={{ color: "var(--icon-base)" }} title="Collapse Sidebar (Ctrl+B)" > - +
@@ -477,7 +428,7 @@ export function Layout(props: ParentProps) {
@@ -520,7 +471,7 @@ export function Layout(props: ParentProps) { }} > - + {session.title || "Untitled"} @@ -536,7 +487,7 @@ export function Layout(props: ParentProps) { onMouseLeave={(e) => (e.currentTarget.style.color = "var(--icon-weak)")} title="Archive session" > - +
)} @@ -566,8 +517,10 @@ export function Layout(props: ParentProps) {
- {/* Expand button when collapsed */} - + {/* Expand button when manually collapsed (not on settings or small screens) */} + = COLLAPSE_BREAKPOINT} + > @@ -616,7 +569,7 @@ export function Layout(props: ParentProps) { color: terminal.active() === session.id ? "var(--text-strong)" : "var(--text-weak)", }} > - + {session.title} )} @@ -637,7 +590,7 @@ export function Layout(props: ParentProps) { style={{ color: "var(--icon-weak)" }} title="New Terminal" > - + @@ -647,7 +600,7 @@ export function Layout(props: ParentProps) { style={{ color: "var(--icon-weak)" }} title="Close Terminal" > - + diff --git a/prokube/app-prefixable/src/pages/project-picker.tsx b/prokube/app-prefixable/src/pages/project-picker.tsx index e57880cc0ee..a35522ddb19 100644 --- a/prokube/app-prefixable/src/pages/project-picker.tsx +++ b/prokube/app-prefixable/src/pages/project-picker.tsx @@ -5,6 +5,7 @@ import { useBasePath } from "../context/base-path" import { base64Encode } from "../utils/path" import { Spinner } from "@opencode-ai/ui/spinner" import { Button } from "@opencode-ai/ui/button" +import { Folder } from "lucide-solid" // OpenCode Wordmark function OpenCodeWordmark(props: { class?: string }) { @@ -69,19 +70,6 @@ function ProkubeLogo(props: { class?: string }) { ) } -function FolderIcon(props: { class?: string; style?: { [key: string]: string } }) { - return ( - - - - ) -} - /** * Project picker content - shown inside HomeLayout. * Displays OpenCode logo and folder selection options. @@ -220,7 +208,7 @@ export function ProjectPicker() { onMouseEnter={(e) => (e.currentTarget.style.background = "var(--surface-inset)")} onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")} > - + {path} )} diff --git a/prokube/app-prefixable/src/pages/session.tsx b/prokube/app-prefixable/src/pages/session.tsx index 46950c2fd51..9360da29c0c 100644 --- a/prokube/app-prefixable/src/pages/session.tsx +++ b/prokube/app-prefixable/src/pages/session.tsx @@ -12,6 +12,7 @@ import { MCPDialog } from "../components/mcp-dialog" import { MCPAddDialog } from "../components/mcp-add-dialog" import { base64Encode } from "../utils/path" import type { Part } from "@opencode-ai/sdk/v2/client" +import { Plus, Settings, ChevronDown, MessageCircle } from "lucide-solid" interface Command { id: string @@ -600,29 +601,14 @@ export function Session() { size="large" >
- - - + New Session
@@ -678,15 +664,7 @@ export function Session() { onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")} > {providers.selectedAgent} - - - + @@ -755,15 +733,7 @@ export function Session() { ? `${providers.selectedModel.providerID}/${providers.selectedModel.modelID}` : "Select model"} - - - + @@ -879,20 +849,7 @@ export function Session() { class="w-16 h-16 rounded-full flex items-center justify-center mb-4" style={{ background: "var(--surface-inset)" }} > - - - +

Ready to chat diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index 929e49b66a2..dedd244cfa1 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -1,12 +1,15 @@ -import { createSignal, For, Show } from "solid-js" +import { createSignal, For, Show, type JSX } from "solid-js" import { Spinner } from "@opencode-ai/ui/spinner" import { useProviders } from "../context/providers" import { useMCP } from "../context/mcp" +import { useSDK } from "../context/sdk" import { MCPAddDialog } from "../components/mcp-add-dialog" +import { Check, Copy, Plug, GitBranch, Server, Cpu, Bot } from "lucide-solid" export function Settings() { const providers = useProviders() const mcp = useMCP() + const { client, url, directory } = useSDK() const [selectedProvider, setSelectedProvider] = createSignal(null) const [apiKey, setApiKey] = createSignal("") const [connecting, setConnecting] = createSignal(false) @@ -16,6 +19,152 @@ export function Settings() { const [showMCPAddDialog, setShowMCPAddDialog] = createSignal(false) const [mcpLoading, setMcpLoading] = createSignal(null) + // Git SSH Key state + const [sshKeys, setSshKeys] = createSignal>([]) + const [selectedKeyName, setSelectedKeyName] = createSignal(null) + const [sshKeyLoading, setSshKeyLoading] = createSignal(false) + const [sshKeyGenerating, setSshKeyGenerating] = createSignal(false) + const [sshKeyError, setSshKeyError] = createSignal(null) + const [sshKeyCopied, setSshKeyCopied] = createSignal(false) + const [sshKeyLoaded, setSshKeyLoaded] = createSignal(false) + + // Get currently selected key content + const selectedKey = () => { + const name = selectedKeyName() + if (!name) return null + return sshKeys().find((k) => k.name === name)?.content ?? null + } + + // Load SSH key when Git tab is first accessed + function onTabChange(tabId: string) { + setActiveTab(tabId) + if (tabId === "git" && !sshKeyLoaded()) { + setSshKeyLoaded(true) + loadSshKeys() + } + } + + async function runPtyCommand(command: string, timeout = 3000): Promise { + const ptyRes = await client.pty.create({ + command: "/bin/sh", + args: ["-c", command + "; exit"], + }) + + if (!ptyRes.data?.id) return "" + + const ptyId = ptyRes.data.id + const wsUrl = url.replace(/^http/, "ws") + `/pty/${ptyId}/connect?directory=${encodeURIComponent(directory || "")}` + + const output = await new Promise((resolve) => { + let data = "" + const ws = new WebSocket(wsUrl) + const timeoutId = setTimeout(() => { + ws.close() + resolve(data) + }, timeout) + + ws.addEventListener("message", (event) => { + data += event.data + }) + + ws.addEventListener("close", () => { + clearTimeout(timeoutId) + resolve(data) + }) + + ws.addEventListener("error", () => { + clearTimeout(timeoutId) + resolve(data) + }) + }) + + await client.pty.remove({ ptyID: ptyId }).catch(() => {}) + return output + } + + async function loadSshKeys() { + setSshKeyLoading(true) + setSshKeyError(null) + try { + // List all .pub files in ~/.ssh/ + const listOutput = await runPtyCommand("ls -1 ~/.ssh/*.pub 2>/dev/null") + + // Parse file names + const files = listOutput + .split("\n") + .map((line) => line.trim()) + .filter((line) => line.endsWith(".pub") && !line.includes("*")) + + if (files.length === 0) { + setSshKeys([]) + setSelectedKeyName(null) + return + } + + // Read each key file + const keys: Array<{ name: string; content: string }> = [] + for (const file of files) { + const content = await runPtyCommand(`cat "${file}" 2>/dev/null`) + const keyContent = content + .split("\n") + .find((line) => { + const trimmed = line.trim() + return trimmed.startsWith("ssh-") || trimmed.startsWith("ecdsa-") + }) + ?.trim() + + if (keyContent) { + // Extract just the filename without path + const name = file.split("/").pop()?.replace(".pub", "") || file + keys.push({ name, content: keyContent }) + } + } + + setSshKeys(keys) + + // Select first key by default, or keep current selection if still valid + const current = selectedKeyName() + if (!current || !keys.find((k) => k.name === current)) { + setSelectedKeyName(keys[0]?.name ?? null) + } + } catch (e) { + console.error("Failed to load SSH keys:", e) + setSshKeyError("Failed to check for SSH keys") + } finally { + setSshKeyLoading(false) + } + } + + async function generateSshKey() { + setSshKeyGenerating(true) + setSshKeyError(null) + try { + // Generate new ed25519 key + await runPtyCommand('mkdir -p ~/.ssh && ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" -q 2>/dev/null', 10000) + + // Reload all keys and select the new one + await loadSshKeys() + setSelectedKeyName("id_ed25519") + } catch (e) { + console.error("Failed to generate SSH key:", e) + setSshKeyError("Failed to generate SSH key") + } finally { + setSshKeyGenerating(false) + } + } + + async function copySshKey() { + const key = selectedKey() + if (!key) return + try { + await navigator.clipboard.writeText(key) + setSshKeyCopied(true) + setTimeout(() => setSshKeyCopied(false), 2000) + } catch (e) { + console.error("Failed to copy:", e) + } + } + async function handleConnect(e: SubmitEvent) { e.preventDefault() const providerID = selectedProvider() @@ -45,11 +194,12 @@ export function Settings() { return provider?.name ?? id } - const tabs = [ - { id: "providers", label: "Providers" }, - { id: "mcp", label: "MCP Servers" }, - { id: "models", label: "Models" }, - { id: "agents", label: "Agents" }, + const tabs: Array<{ id: string; label: string; icon: () => JSX.Element }> = [ + { id: "providers", label: "Providers", icon: () => }, + { id: "git", label: "Git", icon: () => }, + { id: "mcp", label: "MCP Servers", icon: () => }, + { id: "models", label: "Models", icon: () => }, + { id: "agents", label: "Agents", icon: () => }, ] return ( @@ -69,7 +219,7 @@ export function Settings() { {(tab) => ( )} @@ -141,19 +292,7 @@ export function Settings() { >

- - - +
{getProviderDisplayName(providerID)} @@ -279,6 +418,210 @@ export function Settings() {
+ {/* Git Tab */} + +
+
+

+ Git Authentication +

+

+ Configure SSH keys to push and pull from remote repositories +

+
+ + {/* SSH Key Section */} +
+
+

+ SSH Key +

+
+
+ +
+ + Checking for SSH keys... +
+
+ + +
+ {sshKeyError()} +
+
+ + +
+

+ No SSH keys found. Generate one to authenticate with Git providers. +

+ +
+
+ + 0}> +
+ {/* Key Selection Dropdown */} +
+ + +
+ + {/* Selected Key Display */} + +
+ +
+
+                              {selectedKey()}
+                            
+ +
+
+
+ +
+ + +
+
+
+
+
+ + {/* Instructions Section */} +
+

+ Add your key to a Git provider +

+
+

Copy your public key above and add it to your Git provider:

+ +
+
+
+
+ {/* MCP Servers Tab */}
@@ -537,20 +880,7 @@ export function Settings() { > {model.name} - - - + ) @@ -613,9 +943,7 @@ export function Settings() { > {agent.name} - - - + )} From 395209cf7d89726ae8449e3a42be8fc29e826b7a Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 15:51:05 +0200 Subject: [PATCH 045/144] fix(prokube): show all providers in settings, not just first 8 --- prokube/app-prefixable/src/pages/settings.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index dedd244cfa1..1da9a637560 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -342,7 +342,7 @@ export function Settings() { Select Provider
- !providers.connected.includes(p.id)).slice(0, 8)}> + !providers.connected.includes(p.id))}> {(provider) => (
- {/* API Key Input */} - -
-
+
- + {/* OAuth Pending - waiting for code */} + + {(pending) => ( +
+
+ {pending().instructions} +
+ + + setOauthCode(e.currentTarget.value)} + placeholder="Enter the code..." + class="w-full px-3 py-2 rounded-md text-sm font-mono" + style={{ + background: "var(--background-base)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + /> + + +
+ + +
+
+ )}
diff --git a/prokube/app-prefixable/src/utils/path.ts b/prokube/app-prefixable/src/utils/path.ts index 9ebbc6a9c4d..96b29dd9d86 100644 --- a/prokube/app-prefixable/src/utils/path.ts +++ b/prokube/app-prefixable/src/utils/path.ts @@ -79,7 +79,13 @@ export function base64Encode(value: string): string { export function base64Decode(value: string): string { // Restore standard base64 chars - const binary = atob(value.replace(/-/g, "+").replace(/_/g, "/")) + let base64 = value.replace(/-/g, "+").replace(/_/g, "/") + // Restore padding (base64 must be multiple of 4) + const pad = base64.length % 4 + if (pad) { + base64 += "=".repeat(4 - pad) + } + const binary = atob(base64) const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0)) return new TextDecoder().decode(bytes) } From 5df0638af0123834f4eece30ff996aa8337b1952 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 16:40:23 +0200 Subject: [PATCH 048/144] fix(prokube): fix OAuth auto method to poll immediately after opening URL - Start completeOAuth call immediately for 'auto' method (device flow) - Show 'Waiting for authorization...' spinner instead of 'Complete' button - The callback polls GitHub until user authorizes in browser --- prokube/app-prefixable/src/pages/settings.tsx | 103 +++++++++++------- 1 file changed, 61 insertions(+), 42 deletions(-) diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index 3973ff141cc..9646c2707b9 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -235,7 +235,7 @@ export function Settings() { window.open(result.url, "_blank") if (result.method === "code") { - // User needs to enter a code + // User needs to enter a code manually setOauthPending({ providerID, methodIndex, @@ -244,23 +244,29 @@ export function Settings() { }) setConnecting(false) } else { - // Auto method - poll or wait for callback + // Auto method (device flow) - show waiting state and immediately start polling setOauthPending({ providerID, methodIndex, method: "auto", instructions: result.instructions, }) - // Try to complete the OAuth after a short delay - setTimeout(async () => { - const ok = await providers.completeOAuth(providerID, methodIndex) - if (ok) { - setSuccess(`Connected to ${getProviderDisplayName(providerID)}!`) - setOauthPending(null) - setSelectedProvider(null) - } - setConnecting(false) - }, 2000) + + // Start the callback immediately - it will poll until user authorizes + // This call blocks until authorization succeeds or fails + console.log("[OAuth] Starting auto callback for", providerID) + const ok = await providers.completeOAuth(providerID, methodIndex) + console.log("[OAuth] Callback result:", ok) + + if (ok) { + setSuccess(`Connected to ${getProviderDisplayName(providerID)}!`) + setOauthPending(null) + setSelectedProvider(null) + } else { + setError("Authentication failed or was cancelled. Please try again.") + setOauthPending(null) + } + setConnecting(false) } } else { setError("Failed to start authentication.") @@ -595,7 +601,7 @@ export function Settings() {
- {/* OAuth Pending - waiting for code */} + {/* OAuth Pending - waiting for authorization */} {(pending) => (
@@ -609,6 +615,20 @@ export function Settings() { {pending().instructions}
+ {/* Auto method - just show waiting spinner */} + +
+ + + Waiting for authorization... + +
+

+ Complete the authorization in the browser window, then return here. +

+
+ + {/* Code method - show input and submit button */} +
+ + +
- -
- - -
)}
From fa9091f534b0de0576c960ce4bb9e6828489c0ed Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 21:13:55 +0200 Subject: [PATCH 049/144] feat(prokube): improve settings UX, add global settings route, allow typing during agent thinking - Add /settings route under HomeLayout so settings is accessible without a project - Wrap HomeLayout with SDK/Provider/MCP contexts for settings functionality - Add provider search with fuzzy filtering in settings - Sort popular providers first (opencode, anthropic, github-copilot, etc) - Show OAuth device code prominently with copy button during authorization - Add 'Recommended' badge for opencode provider - Make input field always enabled so users can type next prompt while agent is thinking - Add dismissible success/error messages in provider connection --- prokube/app-prefixable/src/app.tsx | 1 + .../app-prefixable/src/context/providers.tsx | 5 +- .../app-prefixable/src/pages/home-layout.tsx | 163 ++++---- prokube/app-prefixable/src/pages/session.tsx | 1 - prokube/app-prefixable/src/pages/settings.tsx | 387 ++++++++++++------ 5 files changed, 361 insertions(+), 196 deletions(-) diff --git a/prokube/app-prefixable/src/app.tsx b/prokube/app-prefixable/src/app.tsx index 702b43cb51c..77c76694445 100644 --- a/prokube/app-prefixable/src/app.tsx +++ b/prokube/app-prefixable/src/app.tsx @@ -16,6 +16,7 @@ function AppRoutes() { {/* Root: Show project picker with sidebar */} + {/* Directory-scoped routes */} diff --git a/prokube/app-prefixable/src/context/providers.tsx b/prokube/app-prefixable/src/context/providers.tsx index 3188d40308e..017e0340026 100644 --- a/prokube/app-prefixable/src/context/providers.tsx +++ b/prokube/app-prefixable/src/context/providers.tsx @@ -175,8 +175,9 @@ export function ProviderProvider(props: ParentProps) { method: methodIndex, code, }) - // Refresh provider list - refetchProviders() + // Refresh provider list and wait for it to complete + await refetchProviders() + console.log("[Providers] Refetched after OAuth, connected:", providerData()?.connected) return true } catch (e) { console.error("Failed to complete OAuth:", e) diff --git a/prokube/app-prefixable/src/pages/home-layout.tsx b/prokube/app-prefixable/src/pages/home-layout.tsx index 09b68b2c6d1..ba36933f093 100644 --- a/prokube/app-prefixable/src/pages/home-layout.tsx +++ b/prokube/app-prefixable/src/pages/home-layout.tsx @@ -1,6 +1,10 @@ import { type ParentProps, createSignal, For, onMount } from "solid-js" import { useNavigate } from "@solidjs/router" import { base64Encode } from "../utils/path" +import { SDKProvider } from "../context/sdk" +import { EventProvider } from "../context/events" +import { ProviderProvider } from "../context/providers" +import { MCPProvider } from "../context/mcp" import { ProjectDialog } from "../components/project-dialog" import { Plus, X, Settings, Folder } from "lucide-solid" @@ -114,85 +118,96 @@ export function HomeLayout(props: ParentProps) { } return ( -
- {/* Project Dialog */} - setProjectDialogOpen(false)} - onSelect={handleProjectSelect} - /> - - {/* Left: Project Icons Strip */} -
- {/* Prokube Logo */} - - - {/* Project icons */} -
- - {(project) => ( + + + + +
+ {/* Project Dialog */} + setProjectDialogOpen(false)} + onSelect={handleProjectSelect} + /> + + {/* Left: Project Icons Strip */}
navigateToProject(project.worktree)} - class="group relative cursor-pointer" - title={project.name || getFilename(project.worktree)} + class="w-16 shrink-0 flex flex-col items-center" + style={{ background: "var(--background-base)", "border-right": "1px solid var(--border-base)" }} > - + {/* Prokube Logo */} + + {/* Project icons */} +
+ + {(project) => ( +
navigateToProject(project.worktree)} + class="group relative cursor-pointer" + title={project.name || getFilename(project.worktree)} + > + + +
+ )} +
+ + {/* Add project button */} + +
+ + {/* Bottom: Settings */} +
+ +
- )} - - - {/* Add project button */} - -
- - {/* Bottom: Settings */} -
- -
-
- - {/* Main Content */} -
- {props.children} -
-
+ + {/* Main Content */} +
+ {props.children} +
+
+ + + + ) } diff --git a/prokube/app-prefixable/src/pages/session.tsx b/prokube/app-prefixable/src/pages/session.tsx index 9360da29c0c..06bb0867c61 100644 --- a/prokube/app-prefixable/src/pages/session.tsx +++ b/prokube/app-prefixable/src/pages/session.tsx @@ -1037,7 +1037,6 @@ export function Session() { "--tw-ring-color": "var(--interactive-base)", } as any } - disabled={loading() || processing()} /> {/* Hint for slash commands */} diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index 9646c2707b9..76e75bb4bb2 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -4,7 +4,7 @@ import { useProviders } from "../context/providers" import { useMCP } from "../context/mcp" import { useSDK } from "../context/sdk" import { MCPAddDialog } from "../components/mcp-add-dialog" -import { Check, Copy, Plug, GitBranch, Server, Cpu, Bot, ExternalLink, Key } from "lucide-solid" +import { Check, Copy, Plug, GitBranch, Server, Cpu, Bot, ExternalLink, Key, Search, X } from "lucide-solid" export function Settings() { const providers = useProviders() @@ -19,14 +19,20 @@ export function Settings() { const [showMCPAddDialog, setShowMCPAddDialog] = createSignal(false) const [mcpLoading, setMcpLoading] = createSignal(null) + // Provider search + const [providerSearch, setProviderSearch] = createSignal("") + // OAuth state const [oauthPending, setOauthPending] = createSignal<{ providerID: string + providerName: string methodIndex: number method: "auto" | "code" instructions: string + code: string // Extracted code from instructions (e.g., "XXXX-YYYY") } | null>(null) const [oauthCode, setOauthCode] = createSignal("") + const [codeCopied, setCodeCopied] = createSignal(false) // Git SSH Key state const [sshKeys, setSshKeys] = createSignal>([]) @@ -44,6 +50,30 @@ export function Settings() { return providers.authMethods[id] || [] }) + // Popular providers shown first + const popularProviders = ["opencode", "anthropic", "github-copilot", "openai", "google", "openrouter"] + + // Filtered and sorted providers for display + const filteredProviders = createMemo(() => { + const search = providerSearch().toLowerCase().trim() + const unconnected = providers.providers.filter((p) => !providers.connected.includes(p.id)) + + // Filter by search + const filtered = search + ? unconnected.filter((p) => p.name.toLowerCase().includes(search) || p.id.toLowerCase().includes(search)) + : unconnected + + // Sort: popular first, then alphabetically + return filtered.sort((a, b) => { + const aPopular = popularProviders.indexOf(a.id) + const bPopular = popularProviders.indexOf(b.id) + if (aPopular >= 0 && bPopular >= 0) return aPopular - bPopular + if (aPopular >= 0) return -1 + if (bPopular >= 0) return 1 + return a.name.localeCompare(b.name) + }) + }) + // Get currently selected key content const selectedKey = () => { const name = selectedKeyName() @@ -224,53 +254,64 @@ export function Settings() { } async function handleOAuthStart(providerID: string, methodIndex: number) { - setConnecting(true) setError(null) setSuccess(null) const result = await providers.startOAuth(providerID, methodIndex) if (result) { - // Open the authorization URL - window.open(result.url, "_blank") + // Extract code from instructions (e.g., "Enter code: XXXX-YYYY" -> "XXXX-YYYY") + const codeMatch = result.instructions.match(/:\s*([A-Z0-9]{4}-[A-Z0-9]{4})/i) + const code = codeMatch ? codeMatch[1] : "" + + const providerName = getProviderDisplayName(providerID) if (result.method === "code") { // User needs to enter a code manually setOauthPending({ providerID, + providerName, methodIndex, method: "code", instructions: result.instructions, + code, }) - setConnecting(false) + // Open the authorization URL + window.open(result.url, "_blank") } else { - // Auto method (device flow) - show waiting state and immediately start polling + // Auto method (device flow) - show code immediately, then start polling setOauthPending({ providerID, + providerName, methodIndex, method: "auto", instructions: result.instructions, + code, }) + // Open the authorization URL + window.open(result.url, "_blank") + // Start the callback immediately - it will poll until user authorizes // This call blocks until authorization succeeds or fails - console.log("[OAuth] Starting auto callback for", providerID) + console.log("[OAuth] Starting auto callback for", providerID, "with code:", code) + setConnecting(true) const ok = await providers.completeOAuth(providerID, methodIndex) console.log("[OAuth] Callback result:", ok) + setConnecting(false) if (ok) { - setSuccess(`Connected to ${getProviderDisplayName(providerID)}!`) + setSuccess(`Connected to ${providerName}!`) setOauthPending(null) setSelectedProvider(null) + setProviderSearch("") } else { setError("Authentication failed or was cancelled. Please try again.") setOauthPending(null) } - setConnecting(false) } } else { setError("Failed to start authentication.") - setConnecting(false) } } @@ -287,10 +328,11 @@ export function Settings() { setConnecting(false) if (ok) { - setSuccess(`Connected to ${getProviderDisplayName(pending.providerID)}!`) + setSuccess(`Connected to ${pending.providerName}!`) setOauthPending(null) setOauthCode("") setSelectedProvider(null) + setProviderSearch("") } else { setError("Failed to complete authentication. Please try again.") } @@ -299,9 +341,22 @@ export function Settings() { function cancelOAuth() { setOauthPending(null) setOauthCode("") + setCodeCopied(false) setConnecting(false) } + async function copyCode() { + const pending = oauthPending() + if (!pending?.code) return + try { + await navigator.clipboard.writeText(pending.code) + setCodeCopied(true) + setTimeout(() => setCodeCopied(false), 2000) + } catch (e) { + console.error("Failed to copy code:", e) + } + } + function getProviderDisplayName(id: string): string { const provider = providers.providers.find((p) => p.id === id) return provider?.name ?? id @@ -436,56 +491,224 @@ export function Settings() {
+ {/* Success/Error messages at top */} -
- {success()} +
+ {success()} +
-
- {error()} +
+ {error()} +
-
- {/* Provider Selection */} -
- -
- !providers.connected.includes(p.id))}> - {(provider) => ( + {/* OAuth Pending - show prominently at top */} + + {(pending) => ( +
+
+ + Connecting to {pending().providerName} + + + + +
+ + {/* Show the code prominently with copy button */} + +
+
+ Enter this code on GitHub: +
+
+ + {pending().code} + + +
+
+
+ + {/* Auto method - show waiting spinner */} + +
+ + + Waiting for authorization... + +
+
+ + {/* Code method - show input */} + +
+ setOauthCode(e.currentTarget.value)} + placeholder="Paste authorization code here..." + class="w-full px-3 py-2 rounded-md text-sm font-mono" + style={{ + background: "var(--background-base)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + /> - )} - +
+
+ )} +
- !providers.connected.includes(p.id)).length === 0}> -

- All available providers are connected! -

-
-
+ + {/* Search and Provider Selection */} + +
+ {/* Search input */} +
+ + setProviderSearch(e.currentTarget.value)} + placeholder="Search providers..." + class="w-full pl-9 pr-8 py-2 rounded-md text-sm" + style={{ + background: "var(--background-base)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + /> + + + +
+ + {/* Provider grid - max height with scroll */} +
+ + {(provider) => ( + + )} + +
+ + +

+ No providers found matching "{providerSearch()}" +

+
+ + !providers.connected.includes(p.id)).length === 0 && + !providerSearch() + } + > +

+ All available providers are connected! +

+
+
+
{/* Auth Methods for Selected Provider */} @@ -600,80 +823,6 @@ export function Settings() {

- - {/* OAuth Pending - waiting for authorization */} - - {(pending) => ( -
-
- {pending().instructions} -
- - {/* Auto method - just show waiting spinner */} - -
- - - Waiting for authorization... - -
-

- Complete the authorization in the browser window, then return here. -

-
- - {/* Code method - show input and submit button */} - - setOauthCode(e.currentTarget.value)} - placeholder="Enter the code..." - class="w-full px-3 py-2 rounded-md text-sm font-mono" - style={{ - background: "var(--background-base)", - border: "1px solid var(--border-base)", - color: "var(--text-base)", - }} - /> -
- - -
-
-
- )} -
From b5bdeeb71dac9a6355fd83ecf4d74cb526216f5d Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 21:26:38 +0200 Subject: [PATCH 050/144] fix(prokube): add terminal diagnostics and error handling - Show connection status messages in terminal (connecting, connected, errors) - Display server URL, directory, and PTY ID in terminal on init - Add error state and creating state to terminal context - Show error panel in layout when PTY creation fails - Show loading spinner when creating terminal session - Better WebSocket close reason messages for debugging --- .../src/components/terminal.tsx | 50 +++++- .../app-prefixable/src/context/terminal.tsx | 21 ++- prokube/app-prefixable/src/pages/layout.tsx | 146 +++++++++++------- 3 files changed, 160 insertions(+), 57 deletions(-) diff --git a/prokube/app-prefixable/src/components/terminal.tsx b/prokube/app-prefixable/src/components/terminal.tsx index 9acb1eae69c..211c9ce3cdb 100644 --- a/prokube/app-prefixable/src/components/terminal.tsx +++ b/prokube/app-prefixable/src/components/terminal.tsx @@ -1,4 +1,4 @@ -import { onMount, onCleanup } from "solid-js" +import { onMount, onCleanup, createSignal } from "solid-js" import { Terminal as XTerm } from "@xterm/xterm" import { FitAddon } from "@xterm/addon-fit" import "@xterm/xterm/css/xterm.css" @@ -18,6 +18,19 @@ export function Terminal(props: TerminalProps) { let reconnectTimer: ReturnType | undefined let disposed = false + const [status, setStatus] = createSignal<"connecting" | "connected" | "error" | "disconnected">("connecting") + const [error, setError] = createSignal(null) + + function writeStatus(message: string, type: "info" | "error" | "success" = "info") { + if (!term) return + const colors = { + info: "\x1b[90m", // gray + error: "\x1b[31m", // red + success: "\x1b[32m", // green + } + term.write(`${colors[type]}${message}\x1b[0m\r\n`) + } + function connect() { if (disposed || !term) return @@ -25,11 +38,18 @@ export function Terminal(props: TerminalProps) { const wsUrl = url.replace(/^http/, "ws") + `/pty/${props.ptyId}/connect?directory=${encodeURIComponent(directory || "")}` console.log("[Terminal] Connecting to:", wsUrl) + writeStatus(`Connecting to ${wsUrl}...`, "info") + + setStatus("connecting") + setError(null) ws = new WebSocket(wsUrl) ws.addEventListener("open", () => { console.log("[Terminal] WebSocket connected") + setStatus("connected") + writeStatus("Connected! Waiting for shell output...", "success") + // Send initial size after connection if (term) { client.pty @@ -37,7 +57,13 @@ export function Terminal(props: TerminalProps) { ptyID: props.ptyId, size: { cols: term.cols, rows: term.rows }, }) - .catch((e) => console.error("[Terminal] Failed to update size:", e)) + .then(() => { + console.log("[Terminal] Size updated:", term?.cols, "x", term?.rows) + }) + .catch((e) => { + console.error("[Terminal] Failed to update size:", e) + writeStatus(`Warning: Failed to update terminal size: ${e.message || e}`, "error") + }) } }) @@ -47,13 +73,27 @@ export function Terminal(props: TerminalProps) { ws.addEventListener("error", (e) => { console.error("[Terminal] WebSocket error:", e) + setStatus("error") + setError("WebSocket connection error") + writeStatus("WebSocket error - check browser console for details", "error") }) ws.addEventListener("close", (event) => { console.log("[Terminal] WebSocket closed:", event.code, event.reason) + setStatus("disconnected") + + if (event.code === 1000) { + writeStatus("Connection closed normally", "info") + } else if (event.code === 1006) { + writeStatus(`Connection lost (code: ${event.code}) - server may have closed the PTY`, "error") + } else { + writeStatus(`Connection closed: code=${event.code}, reason=${event.reason || "unknown"}`, "error") + } + // Reconnect on abnormal close (but not if we're disposing) if (!disposed && event.code !== 1000) { console.log("[Terminal] Scheduling reconnect...") + writeStatus("Reconnecting in 2 seconds...", "info") reconnectTimer = setTimeout(() => connect(), 2000) } }) @@ -85,6 +125,11 @@ export function Terminal(props: TerminalProps) { term.open(container) console.log("[Terminal] Terminal opened in container") + // Show initial status + writeStatus(`Terminal initialized (PTY ID: ${props.ptyId})`, "info") + writeStatus(`Server URL: ${url}`, "info") + writeStatus(`Directory: ${directory || "(none)"}`, "info") + // Send terminal input to WebSocket term.onData((data) => { if (ws?.readyState === WebSocket.OPEN) { @@ -113,6 +158,7 @@ export function Terminal(props: TerminalProps) { console.log("[Terminal] Terminal size after fit:", term?.cols, "x", term?.rows) } else { console.warn("[Terminal] Container has no size yet") + writeStatus("Warning: Terminal container has no size yet", "error") } connect() }, 100) diff --git a/prokube/app-prefixable/src/context/terminal.tsx b/prokube/app-prefixable/src/context/terminal.tsx index 80b37ded753..5e86d355baa 100644 --- a/prokube/app-prefixable/src/context/terminal.tsx +++ b/prokube/app-prefixable/src/context/terminal.tsx @@ -11,12 +11,15 @@ interface TerminalContextValue { active: () => string | null opened: () => boolean height: () => number + error: () => string | null + creating: () => boolean create: (cwd?: string) => Promise close: (id: string) => Promise setActive: (id: string | null) => void toggle: (cwd?: string) => void open: (cwd?: string) => void setHeight: (h: number) => void + clearError: () => void } const TerminalContext = createContext() @@ -27,10 +30,16 @@ export function TerminalProvider(props: ParentProps) { const [active, setActive] = createSignal(null) const [opened, setOpened] = createSignal(false) const [height, setHeight] = createSignal(280) + const [error, setError] = createSignal(null) + const [creating, setCreating] = createSignal(false) async function create(cwd?: string): Promise { + setCreating(true) + setError(null) try { + console.log("[Terminal] Creating PTY session, cwd:", cwd) const res = await client.pty.create({ cwd }) + console.log("[Terminal] PTY create response:", res) if (res.data) { const session: PTYSession = { id: res.data.id, @@ -41,8 +50,13 @@ export function TerminalProvider(props: ParentProps) { setOpened(true) return session.id } - } catch (e) { - console.error("Failed to create PTY:", e) + setError("Failed to create terminal: No data in response") + } catch (e: any) { + console.error("[Terminal] Failed to create PTY:", e) + const msg = e?.message || e?.toString() || "Unknown error" + setError(`Failed to create terminal: ${msg}`) + } finally { + setCreating(false) } return null } @@ -90,12 +104,15 @@ export function TerminalProvider(props: ParentProps) { active, opened, height, + error, + creating, create, close, setActive, toggle, open, setHeight, + clearError: () => setError(null), }} > {props.children} diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index 0273a3b8074..d3c425939ff 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -22,6 +22,7 @@ import { ChevronRight, ChevronDown, Folder, + AlertTriangle, } from "lucide-solid" // Storage keys @@ -543,76 +544,115 @@ export function Layout(props: ParentProps) { {/* Terminal Panel */} - 0}> + 0 || terminal.error() || terminal.creating()}>
-
-
- - {(session) => ( -
terminal.setActive(session.id)} - class="flex items-center gap-1.5 px-2 py-1 text-xs rounded transition-colors cursor-pointer" - style={{ - background: terminal.active() === session.id ? "var(--surface-inset)" : "transparent", - color: terminal.active() === session.id ? "var(--text-strong)" : "var(--text-weak)", - }} - > - - {session.title} - +
+ + + {/* Creating indicator */} + +
+ + Creating terminal session... +
+
+ + {/* Terminal tabs and content */} + 0 && !terminal.error()}> +
+
+ + {(session) => ( +
terminal.setActive(session.id)} + class="flex items-center gap-1.5 px-2 py-1 text-xs rounded transition-colors cursor-pointer" + style={{ + background: terminal.active() === session.id ? "var(--surface-inset)" : "transparent", + color: terminal.active() === session.id ? "var(--text-strong)" : "var(--text-weak)", }} - class="ml-1 p-0.5 rounded hover:bg-white/10" - style={{ color: "var(--icon-weak)" }} > - - -
- )} -
+ + {session.title} + +
+ )} + + +
+
- -
- -
- - {(session) => ( -
- -
- )} -
-
+
+ + {(session) => ( +
+ +
+ )} +
+
+
From cfb55dfccb564cc6f63dfcfbb4e52f6fc1310611 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 21:38:28 +0200 Subject: [PATCH 051/144] fix(prokube): dispose instance after provider connect to reload state Call client.instance.dispose() after OAuth or API key connect to force the backend to reload the provider state. This mirrors what the TUI does and avoids the need for a manual server restart after connecting a provider. --- prokube/app-prefixable/src/context/providers.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/prokube/app-prefixable/src/context/providers.tsx b/prokube/app-prefixable/src/context/providers.tsx index 017e0340026..8f4151f8c66 100644 --- a/prokube/app-prefixable/src/context/providers.tsx +++ b/prokube/app-prefixable/src/context/providers.tsx @@ -146,8 +146,9 @@ export function ProviderProvider(props: ParentProps) { providerID, auth: { type: "api", key: apiKey }, }) - // Refresh provider list - refetchProviders() + // Dispose instance to reload provider state, then refresh + await client.instance.dispose() + await refetchProviders() return true } catch (e) { console.error("Failed to connect provider:", e) @@ -175,7 +176,8 @@ export function ProviderProvider(props: ParentProps) { method: methodIndex, code, }) - // Refresh provider list and wait for it to complete + // Dispose instance to reload provider state, then refresh + await client.instance.dispose() await refetchProviders() console.log("[Providers] Refetched after OAuth, connected:", providerData()?.connected) return true From 5a381a3915ec976b31bed401c63dc843d3e89b61 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 21:56:45 +0200 Subject: [PATCH 052/144] fix(prokube): add /instance to proxy apiPaths for dispose calls --- prokube/docker/serve-ui.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/prokube/docker/serve-ui.ts b/prokube/docker/serve-ui.ts index ac6a4867832..fb3d2dfc861 100644 --- a/prokube/docker/serve-ui.ts +++ b/prokube/docker/serve-ui.ts @@ -66,6 +66,7 @@ const apiPaths = [ "/formatter", "/doc", "/log", + "/instance", ] function isApiPath(path: string): boolean { From 30cf567ca28d41c4f75f6adde984bbfac59270f7 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 22:05:09 +0200 Subject: [PATCH 053/144] fix(prokube): add WebSocket proxy support for PTY terminal connections --- prokube/docker/serve-ui.ts | 87 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/prokube/docker/serve-ui.ts b/prokube/docker/serve-ui.ts index fb3d2dfc861..47ab9e3094e 100644 --- a/prokube/docker/serve-ui.ts +++ b/prokube/docker/serve-ui.ts @@ -4,17 +4,20 @@ * This server: * 1. Serves static files from /opt/opencode-ui/dist * 2. Proxies API requests to the OpenCode API server (localhost:4096) - * 3. Injects NB_PREFIX into index.html at runtime + * 3. Proxies WebSocket connections for PTY terminal sessions + * 4. Injects NB_PREFIX into index.html at runtime */ const BASE_PATH = process.env.NB_PREFIX || process.env.BASE_PATH || "/" const PORT = parseInt(process.env.PORT || "8888", 10) const API_URL = process.env.API_URL || "http://127.0.0.1:4096" +const WS_API_URL = API_URL.replace(/^http/, "ws") const DIST_DIR = process.env.DIST_DIR || "/opt/opencode-ui/dist" console.log(`OpenCode UI Server starting...`) console.log(` BASE_PATH: ${BASE_PATH}`) console.log(` API_URL: ${API_URL}`) +console.log(` WS_API_URL: ${WS_API_URL}`) console.log(` PORT: ${PORT}`) console.log(` DIST_DIR: ${DIST_DIR}`) @@ -73,12 +76,20 @@ function isApiPath(path: string): boolean { return apiPaths.some((p) => path === p || path.startsWith(p + "/") || path.startsWith(p + "?")) } -const server = Bun.serve({ +// Check if this is a PTY WebSocket connection request +function isPtyWebSocket(path: string): boolean { + return /^\/pty\/[^/]+\/connect/.test(path) +} + +// Store for backend WebSocket connections (keyed by client WebSocket) +const backendConnections = new WeakMap() + +const server = Bun.serve<{ path: string; search: string }>({ port: PORT, hostname: "0.0.0.0", idleTimeout: 0, // Disable timeout for SSE connections - async fetch(req) { + async fetch(req, server) { const url = new URL(req.url) let path = url.pathname @@ -90,6 +101,21 @@ const server = Bun.serve({ path = "/" + path } + // Handle WebSocket upgrade for PTY connections + if (isPtyWebSocket(path)) { + const upgradeHeader = req.headers.get("Upgrade") + if (upgradeHeader?.toLowerCase() === "websocket") { + console.log("[Proxy] WebSocket upgrade for PTY:", path) + const success = server.upgrade(req, { + data: { path, search: url.search }, + }) + if (success) { + return undefined // Bun handles the response + } + return new Response("WebSocket upgrade failed", { status: 500 }) + } + } + // Check if this is an API request (after stripping prefix) if (isApiPath(path)) { const target = new URL(path + url.search, API_URL) @@ -182,6 +208,61 @@ const server = Bun.serve({ }, }) }, + + // WebSocket handler for PTY proxy + websocket: { + open(ws) { + const { path, search } = ws.data + const targetUrl = `${WS_API_URL}${path}${search}` + console.log("[Proxy] Opening backend WebSocket to:", targetUrl) + + const backend = new WebSocket(targetUrl) + + backend.addEventListener("open", () => { + console.log("[Proxy] Backend WebSocket connected") + }) + + backend.addEventListener("message", (event) => { + // Forward backend messages to client + if (ws.readyState === WebSocket.OPEN) { + ws.send(event.data) + } + }) + + backend.addEventListener("close", (event) => { + console.log("[Proxy] Backend WebSocket closed:", event.code, event.reason) + if (ws.readyState === WebSocket.OPEN) { + ws.close(event.code, event.reason) + } + }) + + backend.addEventListener("error", (error) => { + console.error("[Proxy] Backend WebSocket error:", error) + if (ws.readyState === WebSocket.OPEN) { + ws.close(1011, "Backend connection error") + } + }) + + backendConnections.set(ws, backend) + }, + + message(ws, message) { + // Forward client messages to backend + const backend = backendConnections.get(ws) + if (backend?.readyState === WebSocket.OPEN) { + backend.send(message) + } + }, + + close(ws, code, reason) { + console.log("[Proxy] Client WebSocket closed:", code, reason) + const backend = backendConnections.get(ws) + if (backend?.readyState === WebSocket.OPEN) { + backend.close(code, reason) + } + backendConnections.delete(ws) + }, + }, }) console.log(`\nOpenCode UI Server running at http://0.0.0.0:${PORT}${basePathWithTrailing}`) From 0ec2e8ebf1ddc8cbd84e8a7cce941b1b35fe33b2 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 22:16:15 +0200 Subject: [PATCH 054/144] Improve UX: resizable terminal, auto-grow textarea, smooth project switching - Add drag handle to terminal panel for resizing (100-600px range) - Convert input to textarea with text wrap and auto-grow (max 200px) - Enter submits, Shift+Enter for newlines - Use keyed For in DirectoryLayout to force provider remount on project switch - Replace window.location.href with router navigation for smoother transitions --- .../src/pages/directory-layout.tsx | 16 +++++-- prokube/app-prefixable/src/pages/layout.tsx | 42 ++++++++++++++++--- prokube/app-prefixable/src/pages/session.tsx | 36 ++++++++++++---- 3 files changed, 76 insertions(+), 18 deletions(-) diff --git a/prokube/app-prefixable/src/pages/directory-layout.tsx b/prokube/app-prefixable/src/pages/directory-layout.tsx index ef3281ab248..95195e0b657 100644 --- a/prokube/app-prefixable/src/pages/directory-layout.tsx +++ b/prokube/app-prefixable/src/pages/directory-layout.tsx @@ -1,4 +1,4 @@ -import { type ParentProps, createMemo, Show } from "solid-js" +import { type ParentProps, createMemo, For } from "solid-js" import { useParams, Navigate } from "@solidjs/router" import { SDKProvider } from "../context/sdk" import { EventProvider } from "../context/events" @@ -11,6 +11,7 @@ import { Layout } from "./layout" /** * Wraps routes that need a directory context. * Extracts the base64-encoded directory from the URL and provides SDK context. + * Uses a keyed For to force full remount when directory changes. */ export function DirectoryLayout(props: ParentProps) { const params = useParams<{ dir: string }>() @@ -30,10 +31,17 @@ export function DirectoryLayout(props: ParentProps) { } }) + // Use For with a single-element array keyed by directory to force remount + // This ensures all providers are recreated when switching projects + const directories = createMemo(() => { + const dir = directory() + return dir ? [dir] : [] + }) + return ( - }> + }> {(dir) => ( - + @@ -45,6 +53,6 @@ export function DirectoryLayout(props: ParentProps) { )} - + ) } diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index d3c425939ff..0089886d626 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -291,10 +291,9 @@ export function Layout(props: ParentProps) { } function navigateToProject(worktree: string) { - // Force a full page reload when switching projects - // because the SDK context is tied to the directory - const base = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath - window.location.href = `${base}/${base64Encode(worktree)}/session` + // Use router navigation - DirectoryLayout uses keyed For + // to force full remount when directory changes + navigate(`/${base64Encode(worktree)}/session`) } function navigateToHome() { @@ -546,16 +545,47 @@ export function Layout(props: ParentProps) { {/* Terminal Panel */} 0 || terminal.error() || terminal.creating()}>
+ {/* Resize handle */} + +
{ + e.preventDefault() + const startY = e.clientY + const startHeight = terminal.height() + + function onMouseMove(e: MouseEvent) { + const delta = startY - e.clientY + const newHeight = Math.max(100, Math.min(600, startHeight + delta)) + terminal.setHeight(newHeight) + } + + function onMouseUp() { + document.removeEventListener("mousemove", onMouseMove) + document.removeEventListener("mouseup", onMouseUp) + } + + document.addEventListener("mousemove", onMouseMove) + document.addEventListener("mouseup", onMouseUp) + }} + > +
+
+ {/* Error display */}
(null) let messagesEndRef: HTMLDivElement | undefined - let inputRef: HTMLInputElement | undefined + let inputRef: HTMLTextAreaElement | undefined let agentPickerRef: HTMLDivElement | undefined let modelPickerRef: HTMLDivElement | undefined let slashPopoverRef: HTMLDivElement | undefined @@ -1019,28 +1019,48 @@ export function Session() {
-
+
- handleInputChange(e.currentTarget.value)} - onKeyDown={handleInputKeyDown} + onInput={(e) => { + handleInputChange(e.currentTarget.value) + // Auto-grow: reset height then set to scrollHeight + e.currentTarget.style.height = "auto" + e.currentTarget.style.height = Math.min(e.currentTarget.scrollHeight, 200) + "px" + }} + onKeyDown={(e) => { + // Handle slash command navigation first + if (showSlashPopover()) { + handleInputKeyDown(e) + return + } + // Enter to submit (without shift), Shift+Enter for newline + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault() + const form = e.currentTarget.closest("form") + if (form) form.requestSubmit() + } + }} placeholder="Type a message or / for commands..." - class="w-full px-4 py-3 rounded-lg focus:ring-2 focus:outline-none" + rows={1} + class="w-full px-4 py-3 rounded-lg focus:ring-2 focus:outline-none resize-none" style={ { background: "var(--background-base)", border: "1px solid var(--border-base)", color: "var(--text-base)", "--tw-ring-color": "var(--interactive-base)", + "min-height": "48px", + "max-height": "200px", + "overflow-y": "auto", } as any } /> {/* Hint for slash commands */} -
+
Type{" "} / From 18dd010cd8fcdcc3f047eb1947305e5b8b45a4d0 Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 22:29:43 +0200 Subject: [PATCH 055/144] Add mkdir API and fix folder creation in project dialog - Add File.mkdir() function to create directories recursively - Add POST /file/mkdir API endpoint - Regenerate SDK with new endpoint - Update project-dialog to actually create folder before navigating - This also fixes terminal starting in ~ (folder now exists) --- packages/opencode/src/file/index.ts | 11 ++++++ packages/opencode/src/server/routes/file.ts | 29 +++++++++++++++ packages/sdk/js/src/v2/gen/sdk.gen.ts | 36 +++++++++++++++++++ packages/sdk/js/src/v2/gen/types.gen.ts | 20 +++++++++++ .../src/components/project-dialog.tsx | 28 ++++++++++++--- 5 files changed, 119 insertions(+), 5 deletions(-) diff --git a/packages/opencode/src/file/index.ts b/packages/opencode/src/file/index.ts index dfa6356a274..ef3bd32b701 100644 --- a/packages/opencode/src/file/index.ts +++ b/packages/opencode/src/file/index.ts @@ -412,4 +412,15 @@ export namespace File { log.info("search", { query, kind, results: output.length }) return output } + + export async function mkdir(dir: string): Promise { + log.info("mkdir", { dir }) + try { + await fs.promises.mkdir(dir, { recursive: true }) + return true + } catch (e) { + log.error("mkdir failed", { dir, error: e }) + return false + } + } } diff --git a/packages/opencode/src/server/routes/file.ts b/packages/opencode/src/server/routes/file.ts index 60789ef4b72..bea0a256c30 100644 --- a/packages/opencode/src/server/routes/file.ts +++ b/packages/opencode/src/server/routes/file.ts @@ -193,5 +193,34 @@ export const FileRoutes = lazy(() => const content = await File.status() return c.json(content) }, + ) + .post( + "/file/mkdir", + describeRoute({ + summary: "Create directory", + description: "Create a directory (and any parent directories) at the specified path.", + operationId: "file.mkdir", + responses: { + 200: { + description: "Directory created", + content: { + "application/json": { + schema: resolver(z.boolean()), + }, + }, + }, + }, + }), + validator( + "json", + z.object({ + path: z.string(), + }), + ), + async (c) => { + const dir = c.req.valid("json").path + const result = await File.mkdir(dir) + return c.json(result) + }, ), ) diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts index b757b753507..98e39fb71e1 100644 --- a/packages/sdk/js/src/v2/gen/sdk.gen.ts +++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts @@ -26,6 +26,7 @@ import type { EventTuiToastShow, ExperimentalResourceListResponses, FileListResponses, + FileMkdirResponses, FilePartInput, FilePartSource, FileReadResponses, @@ -2338,6 +2339,41 @@ export class File extends HeyApiClient { ...params, }) } + + /** + * Create directory + * + * Create a directory (and any parent directories) at the specified path. + */ + public mkdir( + parameters?: { + directory?: string + path?: string + }, + options?: Options, + ) { + const params = buildClientParams( + [parameters], + [ + { + args: [ + { in: "query", key: "directory" }, + { in: "body", key: "path" }, + ], + }, + ], + ) + return (options?.client ?? this.client).post({ + url: "/file/mkdir", + ...options, + ...params, + headers: { + "Content-Type": "application/json", + ...options?.headers, + ...params.headers, + }, + }) + } } export class Auth2 extends HeyApiClient { diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index cb2f586775a..909cc63601e 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -4234,6 +4234,26 @@ export type FileStatusResponses = { export type FileStatusResponse = FileStatusResponses[keyof FileStatusResponses] +export type FileMkdirData = { + body?: { + path: string + } + path?: never + query?: { + directory?: string + } + url: "/file/mkdir" +} + +export type FileMkdirResponses = { + /** + * Directory created + */ + 200: boolean +} + +export type FileMkdirResponse = FileMkdirResponses[keyof FileMkdirResponses] + export type McpStatusData = { body?: never path?: never diff --git a/prokube/app-prefixable/src/components/project-dialog.tsx b/prokube/app-prefixable/src/components/project-dialog.tsx index 5ea1dbedc3d..3adc7fb3ead 100644 --- a/prokube/app-prefixable/src/components/project-dialog.tsx +++ b/prokube/app-prefixable/src/components/project-dialog.tsx @@ -20,6 +20,7 @@ export function ProjectDialog(props: ProjectDialogProps) { const [searchResults, setSearchResults] = createSignal([]) const [searching, setSearching] = createSignal(false) const [newFolderName, setNewFolderName] = createSignal("") + const [creating, setCreating] = createSignal(false) const client = createOpencodeClient({ baseUrl: serverUrl, throwOnError: false }) @@ -69,12 +70,27 @@ export function ProjectDialog(props: ProjectDialogProps) { setNewFolderName("") } - function createFolder() { + async function createFolder() { const home = homeDirectory() const name = newFolderName().trim() - if (!name || !home) return + if (!name || !home || creating()) return + const fullPath = `${home}/${name}`.replace(/\/+/g, "/") - selectProject(fullPath) + + setCreating(true) + try { + // Actually create the directory on the server + const res = await client.file.mkdir({ path: fullPath }) + if (res.data) { + selectProject(fullPath) + } else { + console.error("Failed to create directory:", res.error) + } + } catch (e) { + console.error("Failed to create directory:", e) + } finally { + setCreating(false) + } } function openFolderPath() { @@ -216,8 +232,10 @@ export function ProjectDialog(props: ProjectDialogProps) { }} onKeyDown={(e) => e.key === "Enter" && createFolder()} /> -
From 39dcbf163841db2c761b6e970c16bb9bbd2b4edc Mon Sep 17 00:00:00 2001 From: hsteude Date: Sun, 25 Jan 2026 22:34:42 +0200 Subject: [PATCH 056/144] Fix folder search to support custom directory in find.files API --- packages/opencode/src/file/index.ts | 37 +++++++++++++++++++-- packages/opencode/src/server/routes/file.ts | 3 ++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/file/index.ts b/packages/opencode/src/file/index.ts index ef3bd32b701..c01def9ea6a 100644 --- a/packages/opencode/src/file/index.ts +++ b/packages/opencode/src/file/index.ts @@ -373,13 +373,44 @@ export namespace File { }) } - export async function search(input: { query: string; limit?: number; dirs?: boolean; type?: "file" | "directory" }) { + async function scanDirectory(dir: string): Promise<{ files: string[]; dirs: string[] }> { + const result: { files: string[]; dirs: string[] } = { files: [], dirs: [] } + const ignoreNested = new Set(["node_modules", "dist", "build", "target", "vendor"]) + const shouldIgnore = (name: string) => name.startsWith(".") || ignoreNested.has(name) + + const top = await fs.promises.readdir(dir, { withFileTypes: true }).catch(() => [] as fs.Dirent[]) + + for (const entry of top) { + if (!entry.isDirectory()) continue + if (shouldIgnore(entry.name)) continue + result.dirs.push(entry.name + "/") + + const base = path.join(dir, entry.name) + const children = await fs.promises.readdir(base, { withFileTypes: true }).catch(() => [] as fs.Dirent[]) + for (const child of children) { + if (!child.isDirectory()) continue + if (shouldIgnore(child.name)) continue + result.dirs.push(entry.name + "/" + child.name + "/") + } + } + + result.dirs.sort() + return result + } + + export async function search(input: { + query: string + directory?: string + limit?: number + dirs?: boolean + type?: "file" | "directory" + }) { const query = input.query.trim() const limit = input.limit ?? 100 const kind = input.type ?? (input.dirs === false ? "file" : "all") - log.info("search", { query, kind }) + log.info("search", { query, kind, directory: input.directory }) - const result = await state().then((x) => x.files()) + const result = input.directory ? await scanDirectory(input.directory) : await state().then((x) => x.files()) const hidden = (item: string) => { const normalized = item.replaceAll("\\", "/").replace(/\/+$/, "") diff --git a/packages/opencode/src/server/routes/file.ts b/packages/opencode/src/server/routes/file.ts index bea0a256c30..82ec7705974 100644 --- a/packages/opencode/src/server/routes/file.ts +++ b/packages/opencode/src/server/routes/file.ts @@ -63,6 +63,7 @@ export const FileRoutes = lazy(() => "query", z.object({ query: z.string(), + directory: z.string().optional(), dirs: z.enum(["true", "false"]).optional(), type: z.enum(["file", "directory"]).optional(), limit: z.coerce.number().int().min(1).max(200).optional(), @@ -70,11 +71,13 @@ export const FileRoutes = lazy(() => ), async (c) => { const query = c.req.valid("query").query + const directory = c.req.valid("query").directory const dirs = c.req.valid("query").dirs const type = c.req.valid("query").type const limit = c.req.valid("query").limit const results = await File.search({ query, + directory, limit: limit ?? 10, dirs: dirs !== "false", type, From 172ce3de0559f3df05aff4516b333bb872a1e5ca Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 08:45:46 +0200 Subject: [PATCH 057/144] UI improvements: remove models tab, fix SSH key generation, improve loading indicators --- prokube/app-prefixable/src/pages/layout.tsx | 3 +- prokube/app-prefixable/src/pages/settings.tsx | 113 ++++-------------- 2 files changed, 26 insertions(+), 90 deletions(-) diff --git a/prokube/app-prefixable/src/pages/layout.tsx b/prokube/app-prefixable/src/pages/layout.tsx index 0089886d626..d1a39e7996b 100644 --- a/prokube/app-prefixable/src/pages/layout.tsx +++ b/prokube/app-prefixable/src/pages/layout.tsx @@ -437,8 +437,9 @@ export function Layout(props: ParentProps) { {/* Sessions List */}
-
+
+ Loading sessions...
diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index 76e75bb4bb2..1d01cd5a0b5 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -4,7 +4,7 @@ import { useProviders } from "../context/providers" import { useMCP } from "../context/mcp" import { useSDK } from "../context/sdk" import { MCPAddDialog } from "../components/mcp-add-dialog" -import { Check, Copy, Plug, GitBranch, Server, Cpu, Bot, ExternalLink, Key, Search, X } from "lucide-solid" +import { Check, Copy, Plug, GitBranch, Server, Bot, ExternalLink, Key, Search, X } from "lucide-solid" export function Settings() { const providers = useProviders() @@ -90,11 +90,12 @@ export function Settings() { } } - async function runPtyCommand(command: string, timeout = 3000): Promise { + async function runPtyCommand(command: string, timeout = 5000): Promise { try { + // Create an interactive shell (not running the command immediately) const ptyRes = await client.pty.create({ command: "/bin/sh", - args: ["-c", command + "; exit"], + args: [], }) if (!ptyRes.data?.id) { @@ -103,26 +104,35 @@ export function Settings() { } const ptyId = ptyRes.data.id - // Use empty directory for SSH operations - they work in home dir const wsUrl = url.replace(/^http/, "ws") + `/pty/${ptyId}/connect` console.log("[runPtyCommand] Connecting to:", wsUrl) const output = await new Promise((resolve) => { let data = "" + let commandSent = false const ws = new WebSocket(wsUrl) - ws.addEventListener("open", () => { - console.log("[runPtyCommand] WebSocket connected") - }) - const timeoutId = setTimeout(() => { - console.log("[runPtyCommand] Timeout, closing WebSocket") + console.log("[runPtyCommand] Timeout, closing WebSocket. Data so far:", data.length) ws.close() resolve(data) }, timeout) + ws.addEventListener("open", () => { + console.log("[runPtyCommand] WebSocket connected, sending command") + // Small delay to ensure shell is ready, then send command + setTimeout(() => { + // Send the command followed by exit + ws.send(command + "; exit\n") + commandSent = true + }, 100) + }) + ws.addEventListener("message", (event) => { - data += event.data + // Only collect data after we've sent the command + if (commandSent) { + data += event.data + } }) ws.addEventListener("close", () => { @@ -366,7 +376,8 @@ export function Settings() { { id: "providers", label: "Providers", icon: () => }, { id: "git", label: "Git", icon: () => }, { id: "mcp", label: "MCP Servers", icon: () => }, - { id: "models", label: "Models", icon: () => }, + // Models tab removed - model selection happens per-session, not globally + // { id: "models", label: "Models", icon: () => }, { id: "agents", label: "Agents", icon: () => }, ] @@ -440,7 +451,7 @@ export function Settings() {
- Loading... + Loading connected providers...
@@ -1075,7 +1086,7 @@ export function Settings() {
- Loading... + Loading MCP servers...
@@ -1228,82 +1239,6 @@ export function Settings() {
- {/* Models Tab */} - -
-
-

- Models -

-

- Select a default model for new sessions -

-
- - -
-

- Connect a provider to see available models. -

-
-
- - providers.connected.includes(p.id))}> - {(provider) => ( -
-
-

- {provider.name} -

-
-
- - {(model) => { - const isSelected = - providers.selectedModel?.providerID === provider.id && - providers.selectedModel?.modelID === model.id - return ( - - ) - }} - -
-
- )} -
-
-
- {/* Agents Tab */}
From 3b2a86aa9ceaa8b1d7b5f074067eddef04c4bd6d Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 08:53:06 +0200 Subject: [PATCH 058/144] Add detailed logging to SSH key generation for debugging --- prokube/app-prefixable/src/pages/settings.tsx | 59 +++++++++++++------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index 1d01cd5a0b5..7b8911e0bea 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -91,6 +91,7 @@ export function Settings() { } async function runPtyCommand(command: string, timeout = 5000): Promise { + console.log("[runPtyCommand] Starting with command:", command) try { // Create an interactive shell (not running the command immediately) const ptyRes = await client.pty.create({ @@ -98,6 +99,8 @@ export function Settings() { args: [], }) + console.log("[runPtyCommand] PTY create response:", ptyRes) + if (!ptyRes.data?.id) { console.error("[runPtyCommand] Failed to create PTY:", ptyRes) return "" @@ -109,34 +112,31 @@ export function Settings() { const output = await new Promise((resolve) => { let data = "" - let commandSent = false const ws = new WebSocket(wsUrl) const timeoutId = setTimeout(() => { - console.log("[runPtyCommand] Timeout, closing WebSocket. Data so far:", data.length) + console.log("[runPtyCommand] Timeout reached. Data collected:", data) ws.close() resolve(data) }, timeout) ws.addEventListener("open", () => { - console.log("[runPtyCommand] WebSocket connected, sending command") - // Small delay to ensure shell is ready, then send command + console.log("[runPtyCommand] WebSocket connected, sending command in 200ms") + // Wait for shell prompt, then send command setTimeout(() => { - // Send the command followed by exit - ws.send(command + "; exit\n") - commandSent = true - }, 100) + const fullCommand = command + "; exit\n" + console.log("[runPtyCommand] Sending:", fullCommand) + ws.send(fullCommand) + }, 200) }) ws.addEventListener("message", (event) => { - // Only collect data after we've sent the command - if (commandSent) { - data += event.data - } + console.log("[runPtyCommand] Received message:", event.data) + data += event.data }) ws.addEventListener("close", () => { - console.log("[runPtyCommand] WebSocket closed, output length:", data.length) + console.log("[runPtyCommand] WebSocket closed, total output length:", data.length) clearTimeout(timeoutId) resolve(data) }) @@ -148,6 +148,7 @@ export function Settings() { }) }) + console.log("[runPtyCommand] Final output:", output) await client.pty.remove({ ptyID: ptyId }).catch(() => {}) return output } catch (e) { @@ -212,16 +213,38 @@ export function Settings() { async function generateSshKey() { setSshKeyGenerating(true) setSshKeyError(null) + console.log("[generateSshKey] Starting SSH key generation") try { - // Generate new ed25519 key - await runPtyCommand('mkdir -p ~/.ssh && ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" -q 2>/dev/null', 10000) + // Find a unique key name if id_ed25519 already exists + const existingKeys = sshKeys().map((k) => k.name) + let keyName = "id_ed25519" + let counter = 2 + while (existingKeys.includes(keyName)) { + keyName = `id_ed25519_${counter}` + counter++ + } + console.log("[generateSshKey] Using key name:", keyName) + + // Generate new ed25519 key with unique name + const cmd = `mkdir -p ~/.ssh && chmod 700 ~/.ssh && ssh-keygen -t ed25519 -f ~/.ssh/${keyName} -N "" -q && echo "KEY_GENERATED"` + console.log("[generateSshKey] Running command:", cmd) + const result = await runPtyCommand(cmd, 10000) + console.log("[generateSshKey] Command result:", result) + + if (!result.includes("KEY_GENERATED")) { + console.error("[generateSshKey] SSH key generation failed, output:", result) + setSshKeyError("SSH key generation failed. Check browser console for details.") + return + } + console.log("[generateSshKey] Key generated successfully, reloading keys") // Reload all keys and select the new one await loadSshKeys() - setSelectedKeyName("id_ed25519") + setSelectedKeyName(keyName) + console.log("[generateSshKey] Done") } catch (e) { - console.error("Failed to generate SSH key:", e) - setSshKeyError("Failed to generate SSH key") + console.error("[generateSshKey] Error:", e) + setSshKeyError("Failed to generate SSH key: " + String(e)) } finally { setSshKeyGenerating(false) } From 0e360a44ec7a388761559f095d353c08d5fda898 Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 08:58:38 +0200 Subject: [PATCH 059/144] Fix SSH key loading: strip ANSI escape codes from terminal output --- prokube/app-prefixable/src/pages/settings.tsx | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index 7b8911e0bea..5e73bdf8ec9 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -157,19 +157,30 @@ export function Settings() { } } + // Strip ANSI escape codes from terminal output + function stripAnsi(str: string): string { + // eslint-disable-next-line no-control-regex + return str.replace(/\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\x1b\[\?[0-9;]*[a-zA-Z]/g, "") + } + async function loadSshKeys() { setSshKeyLoading(true) setSshKeyError(null) + console.log("[loadSshKeys] Starting") try { // List all .pub files in ~/.ssh/ const listOutput = await runPtyCommand("ls -1 ~/.ssh/*.pub 2>/dev/null") + const cleanOutput = stripAnsi(listOutput) + console.log("[loadSshKeys] Clean output:", cleanOutput) // Parse file names - const files = listOutput + const files = cleanOutput .split("\n") .map((line) => line.trim()) .filter((line) => line.endsWith(".pub") && !line.includes("*")) + console.log("[loadSshKeys] Found files:", files) + if (files.length === 0) { setSshKeys([]) setSelectedKeyName(null) @@ -180,7 +191,8 @@ export function Settings() { const keys: Array<{ name: string; content: string }> = [] for (const file of files) { const content = await runPtyCommand(`cat "${file}" 2>/dev/null`) - const keyContent = content + const cleanContent = stripAnsi(content) + const keyContent = cleanContent .split("\n") .find((line) => { const trimmed = line.trim() @@ -188,6 +200,8 @@ export function Settings() { }) ?.trim() + console.log("[loadSshKeys] Key content for", file, ":", keyContent?.substring(0, 50)) + if (keyContent) { // Extract just the filename without path const name = file.split("/").pop()?.replace(".pub", "") || file @@ -195,6 +209,10 @@ export function Settings() { } } + console.log( + "[loadSshKeys] Loaded keys:", + keys.map((k) => k.name), + ) setSshKeys(keys) // Select first key by default, or keep current selection if still valid @@ -203,7 +221,7 @@ export function Settings() { setSelectedKeyName(keys[0]?.name ?? null) } } catch (e) { - console.error("Failed to load SSH keys:", e) + console.error("[loadSshKeys] Failed to load SSH keys:", e) setSshKeyError("Failed to check for SSH keys") } finally { setSshKeyLoading(false) From 0f3a33af5e57d5437c9c6c1be7279140ec1d5a47 Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 09:00:41 +0200 Subject: [PATCH 060/144] Add more debug logging for SSH key state updates --- prokube/app-prefixable/src/pages/settings.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index 5e73bdf8ec9..1e5124b374a 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -213,7 +213,9 @@ export function Settings() { "[loadSshKeys] Loaded keys:", keys.map((k) => k.name), ) + console.log("[loadSshKeys] Setting sshKeys signal with", keys.length, "keys") setSshKeys(keys) + console.log("[loadSshKeys] sshKeys() now has", sshKeys().length, "keys") // Select first key by default, or keep current selection if still valid const current = selectedKeyName() From c550ed2e8288b53a0911f50cd0e8a1dde290bd0f Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 09:13:41 +0200 Subject: [PATCH 061/144] Fix PTY command execution: pass command via args instead of interactive shell --- prokube/app-prefixable/src/pages/settings.tsx | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index 1e5124b374a..fdee0b6117c 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -93,10 +93,10 @@ export function Settings() { async function runPtyCommand(command: string, timeout = 5000): Promise { console.log("[runPtyCommand] Starting with command:", command) try { - // Create an interactive shell (not running the command immediately) + // Create PTY with the command directly (non-interactive) const ptyRes = await client.pty.create({ command: "/bin/sh", - args: [], + args: ["-c", command], }) console.log("[runPtyCommand] PTY create response:", ptyRes) @@ -121,13 +121,7 @@ export function Settings() { }, timeout) ws.addEventListener("open", () => { - console.log("[runPtyCommand] WebSocket connected, sending command in 200ms") - // Wait for shell prompt, then send command - setTimeout(() => { - const fullCommand = command + "; exit\n" - console.log("[runPtyCommand] Sending:", fullCommand) - ws.send(fullCommand) - }, 200) + console.log("[runPtyCommand] WebSocket connected, waiting for output") }) ws.addEventListener("message", (event) => { From deb14f29fd043d023204a956fdca47aa4aca76ab Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 15:44:00 +0200 Subject: [PATCH 062/144] Add provider enable/disable toggle in Settings UI - Shows disabled providers section when any are disabled - Toggle button on connected providers to disable them - Enable button on disabled providers to re-enable them - Saves to opencode.json disabled_providers config - Useful for disabling auto-detected providers like Amazon Bedrock when AWS credentials are used for other purposes (e.g., MinIO/S3) --- .../app-prefixable/src/context/providers.tsx | 42 ++++++++++ prokube/app-prefixable/src/pages/settings.tsx | 81 ++++++++++++++++++- 2 files changed, 119 insertions(+), 4 deletions(-) diff --git a/prokube/app-prefixable/src/context/providers.tsx b/prokube/app-prefixable/src/context/providers.tsx index 8f4151f8c66..56e8033cfe7 100644 --- a/prokube/app-prefixable/src/context/providers.tsx +++ b/prokube/app-prefixable/src/context/providers.tsx @@ -48,6 +48,11 @@ interface OAuthAuthorization { instructions: string } +interface ConfigData { + disabled_providers?: string[] + [key: string]: unknown +} + interface ProviderContextValue { providers: Provider[] connected: string[] @@ -57,12 +62,14 @@ interface ProviderContextValue { loading: boolean selectedModel: ModelKey | null selectedAgent: string + disabledProviders: string[] setSelectedModel: (model: ModelKey | null) => void setSelectedAgent: (agent: string) => void refetch: () => void connectProvider: (providerID: string, apiKey: string) => Promise startOAuth: (providerID: string, methodIndex: number) => Promise completeOAuth: (providerID: string, methodIndex: number, code?: string) => Promise + toggleProviderDisabled: (providerID: string) => Promise } const ProviderContext = createContext() @@ -86,6 +93,17 @@ export function ProviderProvider(props: ParentProps) { } }) + // Fetch config for disabled_providers + const [configData, { refetch: refetchConfig }] = createResource(async () => { + try { + const res = await client.config.get() + return res.data as ConfigData | undefined + } catch (e) { + console.error("Failed to fetch config:", e) + return undefined + } + }) + // Auto-select default model when provider data loads createEffect(() => { const data = providerData() @@ -190,6 +208,26 @@ export function ProviderProvider(props: ParentProps) { function refetch() { refetchProviders() refetchAgents() + refetchConfig() + } + + async function toggleProviderDisabled(providerID: string): Promise { + try { + const current = configData()?.disabled_providers ?? [] + const isDisabled = current.includes(providerID) + const updated = isDisabled ? current.filter((id) => id !== providerID) : [...current, providerID] + + await client.config.update({ config: { disabled_providers: updated } }) + + // Dispose instance to reload provider state, then refresh + await client.instance.dispose() + await refetchConfig() + await refetchProviders() + return true + } catch (e) { + console.error("Failed to toggle provider:", e) + return false + } } const value: ProviderContextValue = { @@ -219,12 +257,16 @@ export function ProviderProvider(props: ParentProps) { get selectedAgent() { return store.selectedAgent }, + get disabledProviders() { + return configData()?.disabled_providers ?? [] + }, setSelectedModel, setSelectedAgent, refetch, connectProvider, startOAuth, completeOAuth, + toggleProviderDisabled, } return {props.children} diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index fdee0b6117c..100f1f45eb3 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -4,7 +4,20 @@ import { useProviders } from "../context/providers" import { useMCP } from "../context/mcp" import { useSDK } from "../context/sdk" import { MCPAddDialog } from "../components/mcp-add-dialog" -import { Check, Copy, Plug, GitBranch, Server, Bot, ExternalLink, Key, Search, X } from "lucide-solid" +import { + Check, + Copy, + Plug, + GitBranch, + Server, + Bot, + ExternalLink, + Key, + Search, + X, + ToggleLeft, + ToggleRight, +} from "lucide-solid" export function Settings() { const providers = useProviders() @@ -514,9 +527,19 @@ export function Settings() { {getProviderDisplayName(providerID)}
- - Connected - +
+ + Connected + + +
)} @@ -525,6 +548,56 @@ export function Settings() {
+ {/* Disabled Providers */} + 0}> +
+
+

+ Disabled Providers +

+

+ These providers are disabled and won't be auto-detected +

+
+
+
+ + {(providerID) => ( +
+
+
+ +
+ + {getProviderDisplayName(providerID)} + +
+ +
+ )} +
+
+
+
+
+ {/* Add Provider */}
Date: Mon, 26 Jan 2026 15:47:14 +0200 Subject: [PATCH 063/144] Improve provider disable button visibility and add logging --- prokube/app-prefixable/src/pages/settings.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index 100f1f45eb3..6e5a15ac023 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -532,12 +532,22 @@ export function Settings() { Connected
From 9d1afb588a40580c11b4eb666bd1a2875ea87f7f Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 15:48:01 +0200 Subject: [PATCH 064/144] Add detailed logging to toggleProviderDisabled --- prokube/app-prefixable/src/context/providers.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/prokube/app-prefixable/src/context/providers.tsx b/prokube/app-prefixable/src/context/providers.tsx index 56e8033cfe7..6b22c07cb96 100644 --- a/prokube/app-prefixable/src/context/providers.tsx +++ b/prokube/app-prefixable/src/context/providers.tsx @@ -212,20 +212,28 @@ export function ProviderProvider(props: ParentProps) { } async function toggleProviderDisabled(providerID: string): Promise { + console.log("[Providers] toggleProviderDisabled called for:", providerID) try { const current = configData()?.disabled_providers ?? [] + console.log("[Providers] Current disabled_providers:", current) const isDisabled = current.includes(providerID) const updated = isDisabled ? current.filter((id) => id !== providerID) : [...current, providerID] + console.log("[Providers] Will update to:", updated) - await client.config.update({ config: { disabled_providers: updated } }) + console.log("[Providers] Calling config.update...") + const result = await client.config.update({ config: { disabled_providers: updated } }) + console.log("[Providers] config.update result:", result) // Dispose instance to reload provider state, then refresh + console.log("[Providers] Disposing instance...") await client.instance.dispose() + console.log("[Providers] Refetching config and providers...") await refetchConfig() await refetchProviders() + console.log("[Providers] Done, new disabled_providers:", configData()?.disabled_providers) return true } catch (e) { - console.error("Failed to toggle provider:", e) + console.error("[Providers] Failed to toggle provider:", e) return false } } From 07ef135c3b02194ba7f142d73622ac6b5e9d2597 Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 15:51:06 +0200 Subject: [PATCH 065/144] Fix Config.update to write opencode.json instead of config.json Config.get() reads from opencode.json but Config.update() was writing to config.json, causing updates to be lost. Now both use opencode.json. --- packages/opencode/src/config/config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 7969e307957..e5cc43f1c77 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -1273,7 +1273,8 @@ export namespace Config { } export async function update(config: Info) { - const filepath = path.join(Instance.directory, "config.json") + // Write to opencode.json in the project directory (same file that get() reads from) + const filepath = path.join(Instance.directory, "opencode.json") const existing = await loadFile(filepath) await Bun.write(filepath, JSON.stringify(mergeDeep(existing, config), null, 2)) await Instance.dispose() From e980aad3c6ab0534aeb0e3db69cdf9d65bf4a2c8 Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 15:58:44 +0200 Subject: [PATCH 066/144] Revert provider toggle feature, add default config disabling amazon-bedrock The toggle feature requires a core fix to Config.update() which we want to avoid. Instead, disable amazon-bedrock by default via opencode.json in the Docker image. This prevents AWS S3/MinIO credentials from triggering Bedrock auto-detection. --- .../app-prefixable/src/context/providers.tsx | 50 ---------- prokube/app-prefixable/src/pages/settings.tsx | 91 +------------------ prokube/docker/Dockerfile | 9 +- prokube/docker/opencode-default-config.json | 4 + 4 files changed, 15 insertions(+), 139 deletions(-) create mode 100644 prokube/docker/opencode-default-config.json diff --git a/prokube/app-prefixable/src/context/providers.tsx b/prokube/app-prefixable/src/context/providers.tsx index 6b22c07cb96..8f4151f8c66 100644 --- a/prokube/app-prefixable/src/context/providers.tsx +++ b/prokube/app-prefixable/src/context/providers.tsx @@ -48,11 +48,6 @@ interface OAuthAuthorization { instructions: string } -interface ConfigData { - disabled_providers?: string[] - [key: string]: unknown -} - interface ProviderContextValue { providers: Provider[] connected: string[] @@ -62,14 +57,12 @@ interface ProviderContextValue { loading: boolean selectedModel: ModelKey | null selectedAgent: string - disabledProviders: string[] setSelectedModel: (model: ModelKey | null) => void setSelectedAgent: (agent: string) => void refetch: () => void connectProvider: (providerID: string, apiKey: string) => Promise startOAuth: (providerID: string, methodIndex: number) => Promise completeOAuth: (providerID: string, methodIndex: number, code?: string) => Promise - toggleProviderDisabled: (providerID: string) => Promise } const ProviderContext = createContext() @@ -93,17 +86,6 @@ export function ProviderProvider(props: ParentProps) { } }) - // Fetch config for disabled_providers - const [configData, { refetch: refetchConfig }] = createResource(async () => { - try { - const res = await client.config.get() - return res.data as ConfigData | undefined - } catch (e) { - console.error("Failed to fetch config:", e) - return undefined - } - }) - // Auto-select default model when provider data loads createEffect(() => { const data = providerData() @@ -208,34 +190,6 @@ export function ProviderProvider(props: ParentProps) { function refetch() { refetchProviders() refetchAgents() - refetchConfig() - } - - async function toggleProviderDisabled(providerID: string): Promise { - console.log("[Providers] toggleProviderDisabled called for:", providerID) - try { - const current = configData()?.disabled_providers ?? [] - console.log("[Providers] Current disabled_providers:", current) - const isDisabled = current.includes(providerID) - const updated = isDisabled ? current.filter((id) => id !== providerID) : [...current, providerID] - console.log("[Providers] Will update to:", updated) - - console.log("[Providers] Calling config.update...") - const result = await client.config.update({ config: { disabled_providers: updated } }) - console.log("[Providers] config.update result:", result) - - // Dispose instance to reload provider state, then refresh - console.log("[Providers] Disposing instance...") - await client.instance.dispose() - console.log("[Providers] Refetching config and providers...") - await refetchConfig() - await refetchProviders() - console.log("[Providers] Done, new disabled_providers:", configData()?.disabled_providers) - return true - } catch (e) { - console.error("[Providers] Failed to toggle provider:", e) - return false - } } const value: ProviderContextValue = { @@ -265,16 +219,12 @@ export function ProviderProvider(props: ParentProps) { get selectedAgent() { return store.selectedAgent }, - get disabledProviders() { - return configData()?.disabled_providers ?? [] - }, setSelectedModel, setSelectedAgent, refetch, connectProvider, startOAuth, completeOAuth, - toggleProviderDisabled, } return {props.children} diff --git a/prokube/app-prefixable/src/pages/settings.tsx b/prokube/app-prefixable/src/pages/settings.tsx index 6e5a15ac023..fdee0b6117c 100644 --- a/prokube/app-prefixable/src/pages/settings.tsx +++ b/prokube/app-prefixable/src/pages/settings.tsx @@ -4,20 +4,7 @@ import { useProviders } from "../context/providers" import { useMCP } from "../context/mcp" import { useSDK } from "../context/sdk" import { MCPAddDialog } from "../components/mcp-add-dialog" -import { - Check, - Copy, - Plug, - GitBranch, - Server, - Bot, - ExternalLink, - Key, - Search, - X, - ToggleLeft, - ToggleRight, -} from "lucide-solid" +import { Check, Copy, Plug, GitBranch, Server, Bot, ExternalLink, Key, Search, X } from "lucide-solid" export function Settings() { const providers = useProviders() @@ -527,29 +514,9 @@ export function Settings() { {getProviderDisplayName(providerID)}
-
- - Connected - - -
+ + Connected +
)} @@ -558,56 +525,6 @@ export function Settings() { - {/* Disabled Providers */} - 0}> -
-
-

- Disabled Providers -

-

- These providers are disabled and won't be auto-detected -

-
-
-
- - {(providerID) => ( -
-
-
- -
- - {getProviderDisplayName(providerID)} - -
- -
- )} -
-
-
-
-
- {/* Add Provider */}
Date: Mon, 26 Jan 2026 15:58:55 +0200 Subject: [PATCH 067/144] Revert core Config.update fix (keeping it unchanged from upstream) --- packages/opencode/src/config/config.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index e5cc43f1c77..7969e307957 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -1273,8 +1273,7 @@ export namespace Config { } export async function update(config: Info) { - // Write to opencode.json in the project directory (same file that get() reads from) - const filepath = path.join(Instance.directory, "opencode.json") + const filepath = path.join(Instance.directory, "config.json") const existing = await loadFile(filepath) await Bun.write(filepath, JSON.stringify(mergeDeep(existing, config), null, 2)) await Instance.dispose() From a61c1d82a3f89b52959eab08482c59192d8e86b2 Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 22:10:54 +0200 Subject: [PATCH 068/144] Redesign project picker as welcome screen with action cards - Replace complex multi-section layout with clean welcome screen - Add 3 action cards: Open Project, New Project, Clone Repository - All cards open ProjectDialog which handles folder selection, creation, and git clone - Add keyboard navigation (Arrow/Enter/Escape) to model and agent pickers in session page - Add keyboard navigation to folder selection in ProjectDialog - Add folder listing with search/filter in ProjectDialog - Add git clone functionality with error handling and progress feedback --- .../src/components/project-dialog.tsx | 482 ++++++++++++++---- .../src/pages/project-picker.tsx | 265 +++------- prokube/app-prefixable/src/pages/session.tsx | 355 +++++++++---- 3 files changed, 699 insertions(+), 403 deletions(-) diff --git a/prokube/app-prefixable/src/components/project-dialog.tsx b/prokube/app-prefixable/src/components/project-dialog.tsx index 3adc7fb3ead..ae6e1fc52d3 100644 --- a/prokube/app-prefixable/src/components/project-dialog.tsx +++ b/prokube/app-prefixable/src/components/project-dialog.tsx @@ -1,9 +1,9 @@ -import { createSignal, For, Show, onMount } from "solid-js" +import { createSignal, For, Show, onMount, createEffect } from "solid-js" import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" import { useBasePath } from "../context/base-path" import { Spinner } from "@opencode-ai/ui/spinner" import { Button } from "@opencode-ai/ui/button" -import { Folder, X } from "lucide-solid" +import { Folder, X, GitBranch, AlertCircle } from "lucide-solid" interface ProjectDialogProps { open: boolean @@ -15,15 +15,25 @@ export function ProjectDialog(props: ProjectDialogProps) { const { serverUrl } = useBasePath() const [homeDirectory, setHomeDirectory] = createSignal(null) - const [folderPath, setFolderPath] = createSignal("") + const [homeFolders, setHomeFolders] = createSignal([]) + const [homeFoldersLoaded, setHomeFoldersLoaded] = createSignal(false) + const [loadingHome, setLoadingHome] = createSignal(false) const [folderSearch, setFolderSearch] = createSignal("") const [searchResults, setSearchResults] = createSignal([]) const [searching, setSearching] = createSignal(false) + const [selectedIndex, setSelectedIndex] = createSignal(0) const [newFolderName, setNewFolderName] = createSignal("") const [creating, setCreating] = createSignal(false) + // Git clone state + const [showCloneForm, setShowCloneForm] = createSignal(false) + const [repoUrl, setRepoUrl] = createSignal("") + const [cloning, setCloning] = createSignal(false) + const [cloneError, setCloneError] = createSignal(null) + const client = createOpencodeClient({ baseUrl: serverUrl, throwOnError: false }) + // Load home directory on mount onMount(async () => { try { const res = await client.path.get() @@ -35,6 +45,38 @@ export function ProjectDialog(props: ProjectDialogProps) { } }) + // Load home folders when dialog opens or home directory changes + createEffect(() => { + const home = homeDirectory() + if (props.open && home && !homeFoldersLoaded()) { + loadHomeFolders(home) + } + }) + + async function loadHomeFolders(home: string) { + setLoadingHome(true) + try { + // Use find.files with a space query to list all directories + // (empty query doesn't work, but space returns all results) + const res = await client.find.files({ + directory: home, + query: " ", + type: "directory", + limit: 50, + }) + const results = res.data ?? [] + // Filter to only show top-level directories (no nested paths) + const topLevel = results.filter((r) => !r.includes("/")).map((r) => `${home}/${r}`.replace(/\/+/g, "/")) + setHomeFolders(topLevel) + } catch (e) { + console.error("Failed to load home folders:", e) + setHomeFolders([]) + } finally { + setHomeFoldersLoaded(true) + setLoadingHome(false) + } + } + async function searchFolders(query: string) { const home = homeDirectory() if (!query.trim() || !home) { @@ -64,10 +106,12 @@ export function ProjectDialog(props: ProjectDialogProps) { props.onSelect(path) props.onClose() // Reset state - setFolderPath("") setFolderSearch("") setSearchResults([]) setNewFolderName("") + setShowCloneForm(false) + setRepoUrl("") + setCloneError(null) } async function createFolder() { @@ -79,7 +123,6 @@ export function ProjectDialog(props: ProjectDialogProps) { setCreating(true) try { - // Actually create the directory on the server const res = await client.file.mkdir({ path: fullPath }) if (res.data) { selectProject(fullPath) @@ -93,18 +136,123 @@ export function ProjectDialog(props: ProjectDialogProps) { } } - function openFolderPath() { - const path = folderPath().trim() - if (path) { - selectProject(path) + async function cloneRepo() { + const home = homeDirectory() + const url = repoUrl().trim() + if (!url || !home || cloning()) return + + setCloning(true) + setCloneError(null) + + try { + // Extract repo name from URL for the target directory + const repoName = url + .split("/") + .pop() + ?.replace(/\.git$/, "") + if (!repoName) { + setCloneError("Invalid repository URL") + setCloning(false) + return + } + + const targetPath = `${home}/${repoName}`.replace(/\/+/g, "/") + + // Use PTY to run git clone + const res = await client.pty.spawn({ + args: ["git", "clone", url, targetPath], + cols: 120, + rows: 24, + }) + + if (res.data?.id) { + const ptyId = res.data.id + + // Wait for clone to complete (poll for completion) + let attempts = 0 + const maxAttempts = 120 // 2 minutes max + + while (attempts < maxAttempts) { + await new Promise((r) => setTimeout(r, 1000)) + attempts++ + + // Try to read output to check if it's done + try { + const readRes = await client.pty.read({ id: ptyId }) + const output = readRes.data?.data || "" + + // Check for error messages + if ( + output.includes("fatal:") || + output.includes("error:") || + output.includes("Permission denied") || + output.includes("Authentication failed") + ) { + // Extract error message + const lines = output.split("\n") + const errorLine = lines.find( + (l) => + l.includes("fatal:") || + l.includes("error:") || + l.includes("Permission denied") || + l.includes("Authentication failed"), + ) + setCloneError(errorLine || "Clone failed - check repository URL and credentials") + await client.pty.kill({ id: ptyId }) + setCloning(false) + return + } + + // Check if clone completed successfully + if ( + output.includes("Cloning into") && + (output.includes("done.") || output.includes("Receiving objects: 100%")) + ) { + await client.pty.kill({ id: ptyId }) + // Refresh home folders and select the new project + await loadHomeFolders(home) + selectProject(targetPath) + return + } + } catch { + // PTY might have exited, check if directory exists + break + } + } + + // If we get here, try to select the project anyway (clone might have succeeded) + await client.pty.kill({ id: ptyId }).catch(() => {}) + await loadHomeFolders(home) + selectProject(targetPath) + } else { + setCloneError("Failed to start git clone") + } + } catch (e) { + console.error("Failed to clone repository:", e) + setCloneError(e instanceof Error ? e.message : "Clone failed") + } finally { + setCloning(false) } } // Handle escape key function handleKeyDown(e: KeyboardEvent) { if (e.key === "Escape") { - props.onClose() + if (showCloneForm()) { + setShowCloneForm(false) + setCloneError(null) + } else { + props.onClose() + } + } + } + + // Folders to display - search results or home folders + const displayFolders = () => { + if (folderSearch().trim()) { + return searchResults() } + return homeFolders() } return ( @@ -128,10 +276,10 @@ export function ProjectDialog(props: ProjectDialogProps) { style={{ "border-bottom": "1px solid var(--border-base)" }} >

- Open Project + {showCloneForm() ? "Clone Git Repository" : "Open Project"}

- )} - - - - - - {/* Direct path input */} -
- -
+ + {/* Search for folder */} +
+ setFolderPath(e.currentTarget.value)} - placeholder="/home/jovyan/my-project" - class="flex-1 px-3 py-2 rounded-md text-sm" - style={{ - background: "var(--background-stronger)", - border: "1px solid var(--border-base)", - color: "var(--text-base)", + value={folderSearch()} + onInput={(e) => { + setFolderSearch(e.currentTarget.value) + setSelectedIndex(0) + searchFolders(e.currentTarget.value) }} - onKeyDown={(e) => e.key === "Enter" && openFolderPath()} - /> - -
-
- - {/* Create new folder */} -
- -
- setNewFolderName(e.currentTarget.value)} - placeholder="my-new-project" - class="flex-1 px-3 py-2 rounded-md text-sm" + onKeyDown={(e) => { + const folders = displayFolders() + if (folders.length === 0) return + if (e.key === "ArrowDown") { + e.preventDefault() + const newIndex = Math.min(selectedIndex() + 1, folders.length - 1) + setSelectedIndex(newIndex) + document + .querySelector(`[data-dialog-folder-index="${newIndex}"]`) + ?.scrollIntoView({ block: "nearest" }) + } else if (e.key === "ArrowUp") { + e.preventDefault() + const newIndex = Math.max(selectedIndex() - 1, 0) + setSelectedIndex(newIndex) + document + .querySelector(`[data-dialog-folder-index="${newIndex}"]`) + ?.scrollIntoView({ block: "nearest" }) + } else if (e.key === "Enter") { + e.preventDefault() + const selected = folders[selectedIndex()] + if (selected) selectProject(selected) + } + }} + placeholder="Type to search... (use arrow keys to navigate)" + class="w-full px-3 py-2 rounded-md text-sm" style={{ background: "var(--background-stronger)", border: "1px solid var(--border-base)", color: "var(--text-base)", }} - onKeyDown={(e) => e.key === "Enter" && createFolder()} /> - + )} + +
- +
+
+ + {/* Create new folder */} +
+ +
+ setNewFolderName(e.currentTarget.value)} + placeholder="my-new-project" + class="flex-1 px-3 py-2 rounded-md text-sm" + style={{ + background: "var(--background-stronger)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + onKeyDown={(e) => e.key === "Enter" && createFolder()} + /> + +
+ +

+ Will create: {homeDirectory()}/{newFolderName()} +

+
- -

- Will open: {homeDirectory()}/{newFolderName()} -

-
- - {/* Quick access to home directory */} - + {/* Clone Git Repo button */}
+ + {/* Quick access to home directory */} + +
+ +
+
+
+ + {/* Clone form */} + +
+ {/* Info about private repos */} +
+ +
+

+ Private repositories +

+

+ To clone private repositories, first configure your Git credentials (SSH key) in Settings. +

+
+
+ + {/* Repo URL input */} +
+ + { + setRepoUrl(e.currentTarget.value) + setCloneError(null) + }} + placeholder="https://github.com/user/repo.git or git@github.com:user/repo.git" + class="w-full px-3 py-2 rounded-md text-sm" + style={{ + background: "var(--background-stronger)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + onKeyDown={(e) => e.key === "Enter" && cloneRepo()} + /> +
+ + {/* Error message */} + +
+ {cloneError()} +
+
+ + {/* Clone target info */} + +

+ Will clone to: {homeDirectory()}/ + {repoUrl() + .split("/") + .pop() + ?.replace(/\.git$/, "") || "..."} +

+
+ + {/* Actions */} +
+ + +
+
diff --git a/prokube/app-prefixable/src/pages/project-picker.tsx b/prokube/app-prefixable/src/pages/project-picker.tsx index a35522ddb19..d518128471d 100644 --- a/prokube/app-prefixable/src/pages/project-picker.tsx +++ b/prokube/app-prefixable/src/pages/project-picker.tsx @@ -1,11 +1,9 @@ -import { createSignal, For, Show, onMount } from "solid-js" +import { createSignal, Show } from "solid-js" import { useNavigate } from "@solidjs/router" -import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" import { useBasePath } from "../context/base-path" import { base64Encode } from "../utils/path" -import { Spinner } from "@opencode-ai/ui/spinner" -import { Button } from "@opencode-ai/ui/button" -import { Folder } from "lucide-solid" +import { Folder, GitBranch, Plus } from "lucide-solid" +import { ProjectDialog } from "../components/project-dialog" // OpenCode Wordmark function OpenCodeWordmark(props: { class?: string }) { @@ -70,87 +68,61 @@ function ProkubeLogo(props: { class?: string }) { ) } +// Action Card Component +function ActionCard(props: { icon: typeof Folder; title: string; description: string; onClick: () => void }) { + return ( + + ) +} + /** - * Project picker content - shown inside HomeLayout. - * Displays OpenCode logo and folder selection options. + * Project picker - Welcome screen with action cards. */ export function ProjectPicker() { - const { serverUrl } = useBasePath() const navigate = useNavigate() + const [dialogOpen, setDialogOpen] = createSignal(false) - const [homeDirectory, setHomeDirectory] = createSignal(null) - const [folderPath, setFolderPath] = createSignal("") - const [folderSearch, setFolderSearch] = createSignal("") - const [searchResults, setSearchResults] = createSignal([]) - const [searching, setSearching] = createSignal(false) - const [newFolderName, setNewFolderName] = createSignal("") - - const client = createOpencodeClient({ baseUrl: serverUrl, throwOnError: false }) - - onMount(async () => { - try { - const res = await client.path.get() - if (res.data?.home) { - setHomeDirectory(res.data.home) - } - } catch (e) { - console.error("Failed to fetch path info:", e) - } - }) - - function selectProject(worktree: string) { + function handleProjectSelect(worktree: string) { navigate(`/${base64Encode(worktree)}/session`) } - async function searchFolders(query: string) { - const home = homeDirectory() - if (!query.trim() || !home) { - setSearchResults([]) - return - } - - setSearching(true) - try { - const res = await client.find.files({ - directory: home, - query: query, - type: "directory", - limit: 20, - }) - const results = res.data ?? [] - setSearchResults(results.map((r) => `${home}/${r}`.replace(/\/+/g, "/"))) - } catch (e) { - console.error("Failed to search folders:", e) - setSearchResults([]) - } finally { - setSearching(false) - } - } - - function createFolder() { - const home = homeDirectory() - const name = newFolderName().trim() - if (!name || !home) return - const fullPath = `${home}/${name}`.replace(/\/+/g, "/") - selectProject(fullPath) - } - - function openFolderPath() { - const path = folderPath().trim() - if (path) { - selectProject(path) - } - } - return (
-
+
{/* Logo and Title */} -
+
-
+
Powered by
-

Choose a folder to start working

+

+ Get started by choosing an option below +

- {/* Search for folder */} -
- - { - setFolderSearch(e.currentTarget.value) - searchFolders(e.currentTarget.value) - }} - placeholder={`Type to search in ${homeDirectory() ?? "..."}...`} - class="w-full px-3 py-2 rounded-md text-sm" - style={{ - background: "var(--background-stronger)", - border: "1px solid var(--border-base)", - color: "var(--text-base)", - }} + {/* Action Cards */} +
+ setDialogOpen(true)} + /> + setDialogOpen(true)} + /> + setDialogOpen(true)} /> - - -
- -
-
- - 0}> -
- - {(path) => ( - - )} - -
-
-
- - {/* Direct path input */} -
- -
- setFolderPath(e.currentTarget.value)} - placeholder="/home/jovyan/my-project" - class="flex-1 px-3 py-2 rounded-md text-sm" - style={{ - background: "var(--background-stronger)", - border: "1px solid var(--border-base)", - color: "var(--text-base)", - }} - onKeyDown={(e) => e.key === "Enter" && openFolderPath()} - /> - -
-
- - {/* Create new folder */} -
- -
- setNewFolderName(e.currentTarget.value)} - placeholder="my-new-project" - class="flex-1 px-3 py-2 rounded-md text-sm" - style={{ - background: "var(--background-stronger)", - border: "1px solid var(--border-base)", - color: "var(--text-base)", - }} - onKeyDown={(e) => e.key === "Enter" && createFolder()} - /> - -
- -

- Will open: {homeDirectory()}/{newFolderName()} -

-
- - {/* Quick access to home directory */} - -
- -
-
+ + {/* Project Dialog */} + setDialogOpen(false)} onSelect={handleProjectSelect} />
) } diff --git a/prokube/app-prefixable/src/pages/session.tsx b/prokube/app-prefixable/src/pages/session.tsx index 3c30250657a..7ffdfcd562a 100644 --- a/prokube/app-prefixable/src/pages/session.tsx +++ b/prokube/app-prefixable/src/pages/session.tsx @@ -80,14 +80,24 @@ export function Session() { const [showMCPDialog, setShowMCPDialog] = createSignal(false) const [showMCPAddDialog, setShowMCPAddDialog] = createSignal(false) const [error, setError] = createSignal(null) + + // Model picker state + const [modelFilter, setModelFilter] = createSignal("") + const [modelIndex, setModelIndex] = createSignal(0) + + // Agent picker state + const [agentFilter, setAgentFilter] = createSignal("") + const [agentIndex, setAgentIndex] = createSignal(0) let messagesEndRef: HTMLDivElement | undefined let inputRef: HTMLTextAreaElement | undefined let agentPickerRef: HTMLDivElement | undefined let modelPickerRef: HTMLDivElement | undefined let slashPopoverRef: HTMLDivElement | undefined + let modelFilterRef: HTMLInputElement | undefined + let agentFilterRef: HTMLInputElement | undefined - // Define slash commands directly (not through context to avoid reactivity issues) - const slashCommands: Command[] = [ + // Base slash commands (static ones) + const baseSlashCommands: Command[] = [ { id: "session.new", title: "New Session", @@ -125,7 +135,11 @@ export function Session() { slash: "model", onSelect: () => { console.log("[Command] Model picker") + setModelFilter("") + setModelIndex(0) setShowModelPicker(true) + // Focus filter input after popup opens + setTimeout(() => modelFilterRef?.focus(), 50) }, }, { @@ -135,7 +149,11 @@ export function Session() { slash: "agent", onSelect: () => { console.log("[Command] Agent picker") + setAgentFilter("") + setAgentIndex(0) setShowAgentPicker(true) + // Focus filter input after popup opens + setTimeout(() => agentFilterRef?.focus(), 50) }, }, { @@ -153,8 +171,8 @@ export function Session() { // Filtered slash commands based on query const filteredSlashCommands = createMemo(() => { const q = slashQuery().toLowerCase() - if (!q) return slashCommands - return slashCommands.filter( + if (!q) return baseSlashCommands + return baseSlashCommands.filter( (c) => c.slash?.toLowerCase().startsWith(q) || c.title.toLowerCase().includes(q) || @@ -162,6 +180,34 @@ export function Session() { ) }) + // Filtered models for model picker + const filteredModels = createMemo(() => { + const filter = modelFilter().toLowerCase() + const result: { provider: { id: string; name: string }; model: { id: string; name: string } }[] = [] + + for (const provider of providers.providers.filter((p) => providers.connected.includes(p.id))) { + for (const model of Object.values(provider.models).slice(0, 10)) { + if ( + !filter || + model.name.toLowerCase().includes(filter) || + model.id.toLowerCase().includes(filter) || + provider.name.toLowerCase().includes(filter) || + provider.id.toLowerCase().includes(filter) + ) { + result.push({ provider: { id: provider.id, name: provider.name }, model: { id: model.id, name: model.name } }) + } + } + } + return result + }) + + // Filtered agents for agent picker + const filteredAgents = createMemo(() => { + const filter = agentFilter().toLowerCase() + if (!filter) return providers.agents + return providers.agents.filter((a) => a.name.toLowerCase().includes(filter)) + }) + // Close dropdowns on click outside function handleClickOutside(e: MouseEvent) { const target = e.target as Node @@ -652,7 +698,14 @@ export function Session() { - )} - - -
- No agents available -
-
+ } + }} + class="w-full px-3 py-2 text-sm rounded-md focus:outline-none focus:ring-2" + style={ + { + background: "var(--surface-inset)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + "--tw-ring-color": "var(--interactive-base)", + } as any + } + /> +
+ + {/* Agent list */} +
+ +
+ {providers.agents.length === 0 ? "No agents available" : `No agents match "${agentFilter()}"`} +
+
+ + + {(agent, idx) => { + const selected = providers.selectedAgent === agent.name + const highlighted = idx() === agentIndex() + return ( + + ) + }} + +
@@ -717,7 +820,14 @@ export function Session() { - ) - }} - + Connect a provider + +
+ + + 0}> +
+ No models match "{modelFilter()}"
- )} - +
+ + + {(item, idx) => { + const selected = + providers.selectedModel?.providerID === item.provider.id && + providers.selectedModel?.modelID === item.model.id + const highlighted = idx() === modelIndex() + return ( + + ) + }} + + @@ -954,21 +1109,25 @@ export function Session() { 0}>
- Commands + {slashQuery().toLowerCase().startsWith("model") + ? "Models" + : slashQuery().toLowerCase().startsWith("agent") + ? "Agents" + : "Commands"}
{(cmd, idx) => ( From ecb3d0da09c4bc18d90eea5493969df967aaf420 Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 22:13:02 +0200 Subject: [PATCH 069/144] Clone Repository card opens dialog directly to clone form --- .../src/components/project-dialog.tsx | 10 ++++++++++ .../src/pages/project-picker.tsx | 19 +++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/prokube/app-prefixable/src/components/project-dialog.tsx b/prokube/app-prefixable/src/components/project-dialog.tsx index ae6e1fc52d3..abfc625b6d3 100644 --- a/prokube/app-prefixable/src/components/project-dialog.tsx +++ b/prokube/app-prefixable/src/components/project-dialog.tsx @@ -5,10 +5,13 @@ import { Spinner } from "@opencode-ai/ui/spinner" import { Button } from "@opencode-ai/ui/button" import { Folder, X, GitBranch, AlertCircle } from "lucide-solid" +type DialogView = "browse" | "clone" + interface ProjectDialogProps { open: boolean onClose: () => void onSelect: (worktree: string) => void + initialView?: DialogView } export function ProjectDialog(props: ProjectDialogProps) { @@ -53,6 +56,13 @@ export function ProjectDialog(props: ProjectDialogProps) { } }) + // Set initial view when dialog opens + createEffect(() => { + if (props.open) { + setShowCloneForm(props.initialView === "clone") + } + }) + async function loadHomeFolders(home: string) { setLoadingHome(true) try { diff --git a/prokube/app-prefixable/src/pages/project-picker.tsx b/prokube/app-prefixable/src/pages/project-picker.tsx index d518128471d..73655c8ee26 100644 --- a/prokube/app-prefixable/src/pages/project-picker.tsx +++ b/prokube/app-prefixable/src/pages/project-picker.tsx @@ -109,6 +109,12 @@ function ActionCard(props: { icon: typeof Folder; title: string; description: st export function ProjectPicker() { const navigate = useNavigate() const [dialogOpen, setDialogOpen] = createSignal(false) + const [dialogView, setDialogView] = createSignal<"browse" | "clone">("browse") + + function openDialog(view: "browse" | "clone") { + setDialogView(view) + setDialogOpen(true) + } function handleProjectSelect(worktree: string) { navigate(`/${base64Encode(worktree)}/session`) @@ -147,25 +153,30 @@ export function ProjectPicker() { icon={Folder} title="Open Project" description="Browse and open an existing folder" - onClick={() => setDialogOpen(true)} + onClick={() => openDialog("browse")} /> setDialogOpen(true)} + onClick={() => openDialog("browse")} /> setDialogOpen(true)} + onClick={() => openDialog("clone")} />
{/* Project Dialog */} - setDialogOpen(false)} onSelect={handleProjectSelect} /> + setDialogOpen(false)} + onSelect={handleProjectSelect} + initialView={dialogView()} + /> ) } From fbc89aabf4c214a04688b93a7dfb0c0c25a712b9 Mon Sep 17 00:00:00 2001 From: hsteude Date: Mon, 26 Jan 2026 22:22:22 +0200 Subject: [PATCH 070/144] Add diff viewer for edit tool results - Port ContentDiff and ContentCode components from web UI - Add shiki and diff package dependencies for syntax highlighting - Display side-by-side diff with red/green highlighting for edit tools - Responsive layout: side-by-side on desktop, unified on mobile --- bun.lock | 11 + prokube/app-prefixable/package.json | 3 + .../src/components/diff/content-code.css | 26 +++ .../src/components/diff/content-code.tsx | 32 +++ .../src/components/diff/content-diff.css | 154 ++++++++++++++ .../src/components/diff/content-diff.tsx | 200 ++++++++++++++++++ .../src/components/tool-part.tsx | 64 +++++- 7 files changed, 488 insertions(+), 2 deletions(-) create mode 100644 prokube/app-prefixable/src/components/diff/content-code.css create mode 100644 prokube/app-prefixable/src/components/diff/content-code.tsx create mode 100644 prokube/app-prefixable/src/components/diff/content-diff.css create mode 100644 prokube/app-prefixable/src/components/diff/content-diff.tsx diff --git a/bun.lock b/bun.lock index 3795d3837c0..0fd07fe8446 100644 --- a/bun.lock +++ b/bun.lock @@ -492,11 +492,14 @@ "@opencode-ai/sdk": "workspace:*", "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", + "@shikijs/transformers": "^3.4.2", "@solidjs/router": "catalog:", "@xterm/addon-fit": "0.11.0", "@xterm/xterm": "6.0.0", + "diff": "^7.0.0", "lucide-solid": "0.563.0", "marked": "catalog:", + "shiki": "^3.4.2", "solid-js": "catalog:", }, "devDependencies": { @@ -4264,6 +4267,10 @@ "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], + "@prokube/app-prefixable/@shikijs/transformers": ["@shikijs/transformers@3.19.0", "", { "dependencies": { "@shikijs/core": "3.19.0", "@shikijs/types": "3.19.0" } }, "sha512-e6vwrsyw+wx4OkcrDbL+FVCxwx8jgKiCoXzakVur++mIWVcgpzIi8vxf4/b4dVTYrV/nUx5RjinMf4tq8YV8Fw=="], + + "@prokube/app-prefixable/diff": ["diff@7.0.0", "", {}, "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw=="], + "@prokube/app-prefixable/tailwindcss": ["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.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=="], "@protobuf-ts/plugin/typescript": ["typescript@3.9.10", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q=="], @@ -4890,6 +4897,10 @@ "@pierre/diffs/shiki/@shikijs/types": ["@shikijs/types@3.19.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ=="], + "@prokube/app-prefixable/@shikijs/transformers/@shikijs/core": ["@shikijs/core@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-L7SrRibU7ZoYi1/TrZsJOFAnnHyLTE1SwHG1yNWjZIVCqjOEmCSuK2ZO9thnRbJG6TOkPp+Z963JmpCNw5nzvA=="], + + "@prokube/app-prefixable/@shikijs/transformers/@shikijs/types": ["@shikijs/types@3.19.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ=="], + "@prokube/app-prefixable/tailwindcss/chokidar": ["chokidar@3.6.0", "", { "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=="], "@prokube/app-prefixable/tailwindcss/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], diff --git a/prokube/app-prefixable/package.json b/prokube/app-prefixable/package.json index bda8d82304f..a0970e0ea46 100644 --- a/prokube/app-prefixable/package.json +++ b/prokube/app-prefixable/package.json @@ -13,11 +13,14 @@ "@opencode-ai/sdk": "workspace:*", "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", + "@shikijs/transformers": "^3.4.2", "@solidjs/router": "catalog:", "@xterm/addon-fit": "0.11.0", "@xterm/xterm": "6.0.0", + "diff": "^7.0.0", "lucide-solid": "0.563.0", "marked": "catalog:", + "shiki": "^3.4.2", "solid-js": "catalog:" }, "devDependencies": { diff --git a/prokube/app-prefixable/src/components/diff/content-code.css b/prokube/app-prefixable/src/components/diff/content-code.css new file mode 100644 index 00000000000..17d652adcc7 --- /dev/null +++ b/prokube/app-prefixable/src/components/diff/content-code.css @@ -0,0 +1,26 @@ +.content-code { + border: 1px solid var(--border-base); + background-color: var(--surface-inset); + border-radius: 0.25rem; + padding: 0.5rem calc(0.5rem + 3px); +} + +.content-code[data-flush="true"] { + border: none; + background-color: transparent; + padding: 0; + border-radius: 0; +} + +.content-code pre { + --shiki-dark-bg: var(--surface-inset) !important; + background-color: var(--surface-inset) !important; + line-height: 1.6; + font-size: 0.75rem; + white-space: pre-wrap; + word-break: break-word; +} + +.content-code pre span { + white-space: break-spaces; +} diff --git a/prokube/app-prefixable/src/components/diff/content-code.tsx b/prokube/app-prefixable/src/components/diff/content-code.tsx new file mode 100644 index 00000000000..b780420fd88 --- /dev/null +++ b/prokube/app-prefixable/src/components/diff/content-code.tsx @@ -0,0 +1,32 @@ +import { codeToHtml, bundledLanguages } from "shiki" +import { createResource, Suspense } from "solid-js" +import { transformerNotationDiff } from "@shikijs/transformers" +import "./content-code.css" + +interface Props { + code: string + lang?: string + flush?: boolean +} + +export function ContentCode(props: Props) { + const [html] = createResource( + () => [props.code, props.lang], + async ([code, lang]) => { + return (await codeToHtml(code || "", { + lang: lang && lang in bundledLanguages ? lang : "text", + themes: { + light: "github-light", + dark: "github-dark", + }, + transformers: [transformerNotationDiff()], + })) as string + }, + ) + + return ( + +
+ + ) +} diff --git a/prokube/app-prefixable/src/components/diff/content-diff.css b/prokube/app-prefixable/src/components/diff/content-diff.css new file mode 100644 index 00000000000..fb9855cb85f --- /dev/null +++ b/prokube/app-prefixable/src/components/diff/content-diff.css @@ -0,0 +1,154 @@ +.content-diff { + display: flex; + flex-direction: column; + border: 1px solid var(--border-base); + background-color: var(--surface-inset); + border-radius: 0.25rem; + overflow: hidden; +} + +/* Desktop view */ +.diff-desktop { + display: block; +} + +.diff-mobile { + display: none; +} + +.diff-block { + display: flex; + flex-direction: column; +} + +.diff-row { + display: grid; + grid-template-columns: 1fr 1fr; + align-items: stretch; +} + +.diff-row:first-child .diff-slot { + padding-top: 0.25rem; +} + +.diff-row:last-child .diff-slot { + padding-bottom: 0.25rem; +} + +.diff-slot { + position: relative; + display: flex; + flex-direction: column; + overflow-x: visible; + min-width: 0; + align-items: stretch; + padding: 0 1rem 0 2.2ch; +} + +.diff-before { + border-right: 1px solid var(--border-base); +} + +/* Removed lines (red) */ +.diff-slot[data-diff-type="removed"] { + background-color: rgba(248, 81, 73, 0.15); +} + +.diff-slot[data-diff-type="removed"] pre { + --shiki-dark-bg: rgba(248, 81, 73, 0.15) !important; + background-color: rgba(248, 81, 73, 0.15) !important; +} + +.diff-slot[data-diff-type="removed"]::before { + content: "-"; + position: absolute; + left: 0.6ch; + top: 1px; + user-select: none; + color: #f85149; + font-weight: 600; +} + +/* Added lines (green) */ +.diff-slot[data-diff-type="added"] { + background-color: rgba(63, 185, 80, 0.15); +} + +.diff-slot[data-diff-type="added"] pre { + --shiki-dark-bg: rgba(63, 185, 80, 0.15) !important; + background-color: rgba(63, 185, 80, 0.15) !important; +} + +.diff-slot[data-diff-type="added"]::before { + content: "+"; + position: absolute; + user-select: none; + color: #3fb950; + left: 0.6ch; + top: 1px; + font-weight: 600; +} + +/* Mobile view */ +.diff-mobile > .diff-block:first-child > div { + padding-top: 0.25rem; +} + +.diff-mobile > .diff-block:last-child > div { + padding-bottom: 0.25rem; +} + +.diff-mobile > .diff-block > div { + padding: 0 1rem 0 2.2ch; +} + +.diff-mobile > .diff-block > div[data-diff-type="removed"] { + position: relative; + background-color: rgba(248, 81, 73, 0.15); +} + +.diff-mobile > .diff-block > div[data-diff-type="removed"] pre { + --shiki-dark-bg: rgba(248, 81, 73, 0.15) !important; + background-color: rgba(248, 81, 73, 0.15) !important; +} + +.diff-mobile > .diff-block > div[data-diff-type="removed"]::before { + content: "-"; + position: absolute; + left: 0.6ch; + top: 1px; + user-select: none; + color: #f85149; + font-weight: 600; +} + +.diff-mobile > .diff-block > div[data-diff-type="added"] { + position: relative; + background-color: rgba(63, 185, 80, 0.15); +} + +.diff-mobile > .diff-block > div[data-diff-type="added"] pre { + --shiki-dark-bg: rgba(63, 185, 80, 0.15) !important; + background-color: rgba(63, 185, 80, 0.15) !important; +} + +.diff-mobile > .diff-block > div[data-diff-type="added"]::before { + content: "+"; + position: absolute; + left: 0.6ch; + top: 1px; + user-select: none; + color: #3fb950; + font-weight: 600; +} + +/* Responsive: switch to mobile layout on small screens */ +@media (max-width: 40rem) { + .diff-desktop { + display: none; + } + + .diff-mobile { + display: block; + } +} diff --git a/prokube/app-prefixable/src/components/diff/content-diff.tsx b/prokube/app-prefixable/src/components/diff/content-diff.tsx new file mode 100644 index 00000000000..521948abf06 --- /dev/null +++ b/prokube/app-prefixable/src/components/diff/content-diff.tsx @@ -0,0 +1,200 @@ +import { parsePatch } from "diff" +import { createMemo, For } from "solid-js" +import { ContentCode } from "./content-code" +import "./content-diff.css" + +type DiffRow = { + left: string + right: string + type: "added" | "removed" | "unchanged" | "modified" +} + +interface Props { + diff: string + lang?: string +} + +export function ContentDiff(props: Props) { + const rows = createMemo(() => { + const diffRows: DiffRow[] = [] + + try { + const patches = parsePatch(props.diff) + + for (const patch of patches) { + for (const hunk of patch.hunks) { + const lines = hunk.lines + let i = 0 + + while (i < lines.length) { + const line = lines[i] + const content = line.slice(1) + const prefix = line[0] + + if (prefix === "-") { + // Look ahead for consecutive additions to pair with removals + const removals: string[] = [content] + let j = i + 1 + + // Collect all consecutive removals + while (j < lines.length && lines[j][0] === "-") { + removals.push(lines[j].slice(1)) + j++ + } + + // Collect all consecutive additions that follow + const additions: string[] = [] + while (j < lines.length && lines[j][0] === "+") { + additions.push(lines[j].slice(1)) + j++ + } + + // Pair removals with additions + const maxLength = Math.max(removals.length, additions.length) + for (let k = 0; k < maxLength; k++) { + const hasLeft = k < removals.length + const hasRight = k < additions.length + + if (hasLeft && hasRight) { + // Replacement - left is removed, right is added + diffRows.push({ + left: removals[k], + right: additions[k], + type: "modified", + }) + } else if (hasLeft) { + // Pure removal + diffRows.push({ + left: removals[k], + right: "", + type: "removed", + }) + } else if (hasRight) { + // Pure addition - only create if we actually have content + diffRows.push({ + left: "", + right: additions[k], + type: "added", + }) + } + } + + i = j + } else if (prefix === "+") { + // Standalone addition (not paired with removal) + diffRows.push({ + left: "", + right: content, + type: "added", + }) + i++ + } else if (prefix === " ") { + diffRows.push({ + left: content === "" ? " " : content, + right: content === "" ? " " : content, + type: "unchanged", + }) + i++ + } else { + i++ + } + } + } + } + } catch (error) { + console.error("Failed to parse patch:", error) + return [] + } + + return diffRows + }) + + const mobileRows = createMemo(() => { + const mobileBlocks: { + type: "removed" | "added" | "unchanged" + lines: string[] + }[] = [] + const currentRows = rows() + + let i = 0 + while (i < currentRows.length) { + const removedLines: string[] = [] + const addedLines: string[] = [] + + // Collect consecutive modified/removed/added rows + while ( + i < currentRows.length && + (currentRows[i].type === "modified" || currentRows[i].type === "removed" || currentRows[i].type === "added") + ) { + const row = currentRows[i] + if (row.left && (row.type === "removed" || row.type === "modified")) { + removedLines.push(row.left) + } + if (row.right && (row.type === "added" || row.type === "modified")) { + addedLines.push(row.right) + } + i++ + } + + // Add grouped blocks + if (removedLines.length > 0) { + mobileBlocks.push({ type: "removed", lines: removedLines }) + } + if (addedLines.length > 0) { + mobileBlocks.push({ type: "added", lines: addedLines }) + } + + // Add unchanged rows as-is + if (i < currentRows.length && currentRows[i].type === "unchanged") { + mobileBlocks.push({ + type: "unchanged", + lines: [currentRows[i].left], + }) + i++ + } + } + + return mobileBlocks + }) + + return ( +
+
+ + {(r) => ( +
+
+ +
+
+ +
+
+ )} +
+
+ +
+ + {(block) => ( +
+ + {(line) => ( +
+ +
+ )} +
+
+ )} +
+
+
+ ) +} diff --git a/prokube/app-prefixable/src/components/tool-part.tsx b/prokube/app-prefixable/src/components/tool-part.tsx index 7d9e9eeb8bf..808c7c07413 100644 --- a/prokube/app-prefixable/src/components/tool-part.tsx +++ b/prokube/app-prefixable/src/components/tool-part.tsx @@ -1,6 +1,7 @@ import { createSignal, Show, For } from "solid-js" import type { Part, ToolPart as SDKToolPart, ToolState } from "@opencode-ai/sdk/v2/client" import { ChevronDown } from "lucide-solid" +import { ContentDiff } from "./diff/content-diff" // Use the SDK's ToolPart type type ToolPart = SDKToolPart @@ -92,6 +93,54 @@ function formatInput(input: unknown): string { } } +// Get language from file extension for syntax highlighting +function getLangFromPath(path: string): string { + const ext = path.split(".").pop()?.toLowerCase() ?? "" + const langMap: Record = { + ts: "typescript", + tsx: "tsx", + js: "javascript", + jsx: "jsx", + json: "json", + md: "markdown", + css: "css", + scss: "scss", + html: "html", + xml: "xml", + yaml: "yaml", + yml: "yaml", + py: "python", + rb: "ruby", + go: "go", + rs: "rust", + java: "java", + kt: "kotlin", + swift: "swift", + c: "c", + cpp: "cpp", + h: "c", + hpp: "cpp", + cs: "csharp", + php: "php", + sh: "bash", + bash: "bash", + zsh: "bash", + sql: "sql", + graphql: "graphql", + vue: "vue", + svelte: "svelte", + astro: "astro", + } + return langMap[ext] || "text" +} + +// Get metadata from state +function getMetadata(state: ToolState): Record | undefined { + if (state.status === "completed") return state.metadata as Record | undefined + if (state.status === "running") return state.metadata as Record | undefined + return undefined +} + export function ToolPartDisplay(props: { part: ToolPart }) { const [expanded, setExpanded] = createSignal(false) @@ -99,6 +148,10 @@ export function ToolPartDisplay(props: { part: ToolPart }) { const status = () => getStatus(state()) const canExpand = () => hasOutput(state()) const title = () => getTitle(state()) || props.part.tool + const metadata = () => getMetadata(state()) + const isEdit = () => props.part.tool === "edit" + const hasDiff = () => isEdit() && metadata()?.diff + const filePath = () => (getInput(state()) as { filePath?: string })?.filePath || "" return (
- {/* Expanded content */} - + {/* Diff display for edit tools - shown inline (not in expanded section) */} + +
+ +
+
+ + {/* Expanded content for non-edit tools or when no diff */} +
Date: Tue, 27 Jan 2026 09:02:38 +0200 Subject: [PATCH 071/144] UI improvements: question prompt, diff styling, full-width messages - Add QuestionPrompt component for interactive question tool - Update diff colors from red/green to violet/indigo theme - Make diff blocks collapsible (auto-expand on load, toggle on click) - Expand message width to full screen (user messages max-w-2xl) - Switch terminal to light theme with cleaner startup message - Auto-create project directory before PTY initialization - Add /question route to API proxy - Fix CSS loading for diff component styles --- prokube/app-prefixable/dev.ts | 8 + .../src/components/diff/content-code.css | 4 +- .../src/components/diff/content-code.tsx | 8 +- .../src/components/diff/content-diff.css | 40 +- .../src/components/diff/content-diff.tsx | 2 +- .../src/components/project-dialog.tsx | 85 ++-- .../src/components/question-prompt.tsx | 473 ++++++++++++++++++ .../src/components/terminal.tsx | 38 +- .../src/components/tool-part.tsx | 20 +- .../app-prefixable/src/context/terminal.tsx | 8 + prokube/app-prefixable/src/index.html | 1 + prokube/app-prefixable/src/pages/session.tsx | 140 +++++- prokube/app-prefixable/src/types/diff.d.ts | 20 + prokube/app-prefixable/tsconfig.json | 1 + prokube/docker/serve-ui.ts | 1 + 15 files changed, 739 insertions(+), 110 deletions(-) create mode 100644 prokube/app-prefixable/src/components/question-prompt.tsx create mode 100644 prokube/app-prefixable/src/types/diff.d.ts diff --git a/prokube/app-prefixable/dev.ts b/prokube/app-prefixable/dev.ts index 29c403956c4..6e6385942c2 100644 --- a/prokube/app-prefixable/dev.ts +++ b/prokube/app-prefixable/dev.ts @@ -67,6 +67,14 @@ const server = Bun.serve<{ target: string }>({ "/agent", "/session", "/find", + "/question", + "/global", + "/skill", + "/lsp", + "/formatter", + "/doc", + "/log", + "/instance", ] // Check if this is an API request using the stripped path diff --git a/prokube/app-prefixable/src/components/diff/content-code.css b/prokube/app-prefixable/src/components/diff/content-code.css index 17d652adcc7..5ff57690563 100644 --- a/prokube/app-prefixable/src/components/diff/content-code.css +++ b/prokube/app-prefixable/src/components/diff/content-code.css @@ -13,8 +13,8 @@ } .content-code pre { - --shiki-dark-bg: var(--surface-inset) !important; - background-color: var(--surface-inset) !important; + --shiki-dark-bg: transparent !important; + background-color: transparent !important; line-height: 1.6; font-size: 0.75rem; white-space: pre-wrap; diff --git a/prokube/app-prefixable/src/components/diff/content-code.tsx b/prokube/app-prefixable/src/components/diff/content-code.tsx index b780420fd88..32cd2bcfc7a 100644 --- a/prokube/app-prefixable/src/components/diff/content-code.tsx +++ b/prokube/app-prefixable/src/components/diff/content-code.tsx @@ -25,7 +25,13 @@ export function ContentCode(props: Props) { ) return ( - + + {props.code} + + } + >
) diff --git a/prokube/app-prefixable/src/components/diff/content-diff.css b/prokube/app-prefixable/src/components/diff/content-diff.css index fb9855cb85f..88dd61f57d2 100644 --- a/prokube/app-prefixable/src/components/diff/content-diff.css +++ b/prokube/app-prefixable/src/components/diff/content-diff.css @@ -49,14 +49,9 @@ border-right: 1px solid var(--border-base); } -/* Removed lines (red) */ +/* Removed lines (fuchsia/magenta) */ .diff-slot[data-diff-type="removed"] { - background-color: rgba(248, 81, 73, 0.15); -} - -.diff-slot[data-diff-type="removed"] pre { - --shiki-dark-bg: rgba(248, 81, 73, 0.15) !important; - background-color: rgba(248, 81, 73, 0.15) !important; + background-color: rgba(192, 38, 211, 0.12); } .diff-slot[data-diff-type="removed"]::before { @@ -65,25 +60,20 @@ left: 0.6ch; top: 1px; user-select: none; - color: #f85149; + color: #c026d3; font-weight: 600; } -/* Added lines (green) */ +/* Added lines (indigo) */ .diff-slot[data-diff-type="added"] { - background-color: rgba(63, 185, 80, 0.15); -} - -.diff-slot[data-diff-type="added"] pre { - --shiki-dark-bg: rgba(63, 185, 80, 0.15) !important; - background-color: rgba(63, 185, 80, 0.15) !important; + background-color: rgba(99, 102, 241, 0.12); } .diff-slot[data-diff-type="added"]::before { content: "+"; position: absolute; user-select: none; - color: #3fb950; + color: #6366f1; left: 0.6ch; top: 1px; font-weight: 600; @@ -104,12 +94,7 @@ .diff-mobile > .diff-block > div[data-diff-type="removed"] { position: relative; - background-color: rgba(248, 81, 73, 0.15); -} - -.diff-mobile > .diff-block > div[data-diff-type="removed"] pre { - --shiki-dark-bg: rgba(248, 81, 73, 0.15) !important; - background-color: rgba(248, 81, 73, 0.15) !important; + background-color: rgba(192, 38, 211, 0.12); } .diff-mobile > .diff-block > div[data-diff-type="removed"]::before { @@ -118,18 +103,13 @@ left: 0.6ch; top: 1px; user-select: none; - color: #f85149; + color: #c026d3; font-weight: 600; } .diff-mobile > .diff-block > div[data-diff-type="added"] { position: relative; - background-color: rgba(63, 185, 80, 0.15); -} - -.diff-mobile > .diff-block > div[data-diff-type="added"] pre { - --shiki-dark-bg: rgba(63, 185, 80, 0.15) !important; - background-color: rgba(63, 185, 80, 0.15) !important; + background-color: rgba(99, 102, 241, 0.12); } .diff-mobile > .diff-block > div[data-diff-type="added"]::before { @@ -138,7 +118,7 @@ left: 0.6ch; top: 1px; user-select: none; - color: #3fb950; + color: #6366f1; font-weight: 600; } diff --git a/prokube/app-prefixable/src/components/diff/content-diff.tsx b/prokube/app-prefixable/src/components/diff/content-diff.tsx index 521948abf06..5c9da7e21fb 100644 --- a/prokube/app-prefixable/src/components/diff/content-diff.tsx +++ b/prokube/app-prefixable/src/components/diff/content-diff.tsx @@ -102,7 +102,7 @@ export function ContentDiff(props: Props) { } } } catch (error) { - console.error("Failed to parse patch:", error) + console.error("[ContentDiff] Failed to parse patch:", error) return [] } diff --git a/prokube/app-prefixable/src/components/project-dialog.tsx b/prokube/app-prefixable/src/components/project-dialog.tsx index abfc625b6d3..096e4fdd8e4 100644 --- a/prokube/app-prefixable/src/components/project-dialog.tsx +++ b/prokube/app-prefixable/src/components/project-dialog.tsx @@ -168,11 +168,11 @@ export function ProjectDialog(props: ProjectDialogProps) { const targetPath = `${home}/${repoName}`.replace(/\/+/g, "/") - // Use PTY to run git clone - const res = await client.pty.spawn({ - args: ["git", "clone", url, targetPath], - cols: 120, - rows: 24, + // Use PTY to run git clone - create a session with the clone command + const res = await client.pty.create({ + command: "git", + args: ["clone", url, targetPath], + cwd: home, }) if (res.data?.id) { @@ -186,61 +186,54 @@ export function ProjectDialog(props: ProjectDialogProps) { await new Promise((r) => setTimeout(r, 1000)) attempts++ - // Try to read output to check if it's done + // Try to get PTY status to check if it's done try { - const readRes = await client.pty.read({ id: ptyId }) - const output = readRes.data?.data || "" - - // Check for error messages - if ( - output.includes("fatal:") || - output.includes("error:") || - output.includes("Permission denied") || - output.includes("Authentication failed") - ) { - // Extract error message - const lines = output.split("\n") - const errorLine = lines.find( - (l) => - l.includes("fatal:") || - l.includes("error:") || - l.includes("Permission denied") || - l.includes("Authentication failed"), - ) - setCloneError(errorLine || "Clone failed - check repository URL and credentials") - await client.pty.kill({ id: ptyId }) - setCloning(false) - return - } - - // Check if clone completed successfully - if ( - output.includes("Cloning into") && - (output.includes("done.") || output.includes("Receiving objects: 100%")) - ) { - await client.pty.kill({ id: ptyId }) - // Refresh home folders and select the new project - await loadHomeFolders(home) - selectProject(targetPath) - return + const getRes = await client.pty.get({ ptyID: ptyId }) + const pty = getRes.data + + // Check if PTY has exited + if (pty?.status === "exited") { + // Check if directory was created (success indicator) + try { + await client.file.list({ path: targetPath }) + // Directory exists - clone succeeded + await client.pty.remove({ ptyID: ptyId }).catch(() => {}) + await loadHomeFolders(home) + selectProject(targetPath) + return + } catch { + // Directory doesn't exist - clone failed + setCloneError("Clone failed - check repository URL and credentials") + await client.pty.remove({ ptyID: ptyId }).catch(() => {}) + setCloning(false) + return + } } } catch { - // PTY might have exited, check if directory exists + // PTY might have been removed, check if directory exists break } } // If we get here, try to select the project anyway (clone might have succeeded) - await client.pty.kill({ id: ptyId }).catch(() => {}) - await loadHomeFolders(home) - selectProject(targetPath) + await client.pty.remove({ ptyID: ptyId }).catch(() => {}) + + // Check if clone succeeded by checking if directory exists + try { + await client.file.list({ path: targetPath }) + await loadHomeFolders(home) + selectProject(targetPath) + } catch { + setCloneError("Clone timed out or failed") + setCloning(false) + } } else { setCloneError("Failed to start git clone") + setCloning(false) } } catch (e) { console.error("Failed to clone repository:", e) setCloneError(e instanceof Error ? e.message : "Clone failed") - } finally { setCloning(false) } } diff --git a/prokube/app-prefixable/src/components/question-prompt.tsx b/prokube/app-prefixable/src/components/question-prompt.tsx new file mode 100644 index 00000000000..33dd3250ccb --- /dev/null +++ b/prokube/app-prefixable/src/components/question-prompt.tsx @@ -0,0 +1,473 @@ +import { createSignal, createMemo, For, Show, onMount, onCleanup } from "solid-js" +import { Button } from "@opencode-ai/ui/button" +import type { QuestionRequest } from "@opencode-ai/sdk/v2" + +interface Props { + request: QuestionRequest + onReply: (answers: string[][]) => void + onReject: () => void +} + +export function QuestionPrompt(props: Props) { + const questions = createMemo(() => props.request.questions) + const single = createMemo(() => questions().length === 1 && questions()[0]?.multiple !== true) + const tabs = createMemo(() => (single() ? 1 : questions().length + 1)) + + const [tab, setTab] = createSignal(0) + const [answers, setAnswers] = createSignal([]) + const [custom, setCustom] = createSignal([]) + const [selected, setSelected] = createSignal(0) + const [editing, setEditing] = createSignal(false) + + let inputRef: HTMLInputElement | undefined + + const question = createMemo(() => questions()[tab()]) + const confirm = createMemo(() => !single() && tab() === questions().length) + const options = createMemo(() => question()?.options ?? []) + const allowCustom = createMemo(() => question()?.custom !== false) + const other = createMemo(() => allowCustom() && selected() === options().length) + const input = createMemo(() => custom()[tab()] ?? "") + const multi = createMemo(() => question()?.multiple === true) + const customPicked = createMemo(() => { + const value = input() + if (!value) return false + return answers()[tab()]?.includes(value) ?? false + }) + + function submit() { + const result = questions().map((_, i) => answers()[i] ?? []) + props.onReply(result) + } + + function pick(answer: string, isCustom = false) { + const newAnswers = [...answers()] + newAnswers[tab()] = [answer] + setAnswers(newAnswers) + + if (isCustom) { + const inputs = [...custom()] + inputs[tab()] = answer + setCustom(inputs) + } + + if (single()) { + props.onReply([[answer]]) + return + } + + setTab(tab() + 1) + setSelected(0) + } + + function toggle(answer: string) { + const existing = answers()[tab()] ?? [] + const next = [...existing] + const index = next.indexOf(answer) + if (index === -1) next.push(answer) + else next.splice(index, 1) + + const newAnswers = [...answers()] + newAnswers[tab()] = next + setAnswers(newAnswers) + } + + function selectOption() { + if (other()) { + if (!multi()) { + setEditing(true) + setTimeout(() => inputRef?.focus(), 50) + return + } + const value = input() + if (value && customPicked()) { + toggle(value) + return + } + setEditing(true) + setTimeout(() => inputRef?.focus(), 50) + return + } + + const opt = options()[selected()] + if (!opt) return + + if (multi()) { + toggle(opt.label) + return + } + + pick(opt.label) + } + + function handleCustomSubmit() { + const text = input().trim() + if (!text) { + setEditing(false) + return + } + + if (multi()) { + const inputs = [...custom()] + inputs[tab()] = text + setCustom(inputs) + + const existing = answers()[tab()] ?? [] + if (!existing.includes(text)) { + const newAnswers = [...answers()] + newAnswers[tab()] = [...existing, text] + setAnswers(newAnswers) + } + setEditing(false) + return + } + + pick(text, true) + setEditing(false) + } + + function handleKeyDown(e: KeyboardEvent) { + if (editing()) { + if (e.key === "Escape") { + e.preventDefault() + setEditing(false) + } else if (e.key === "Enter") { + e.preventDefault() + handleCustomSubmit() + } + return + } + + const opts = options() + const total = opts.length + (allowCustom() ? 1 : 0) + + if (e.key === "ArrowUp" || e.key === "k") { + e.preventDefault() + setSelected((s) => (s - 1 + total) % total) + } else if (e.key === "ArrowDown" || e.key === "j") { + e.preventDefault() + setSelected((s) => (s + 1) % total) + } else if (e.key === "Enter") { + e.preventDefault() + if (confirm()) submit() + else selectOption() + } else if (e.key === "Escape") { + e.preventDefault() + props.onReject() + } else if (e.key === "Tab") { + e.preventDefault() + const direction = e.shiftKey ? -1 : 1 + setTab((t) => (t + direction + tabs()) % tabs()) + setSelected(0) + } else if (e.key >= "1" && e.key <= "9") { + const digit = parseInt(e.key) + if (digit <= total) { + e.preventDefault() + setSelected(digit - 1) + selectOption() + } + } + } + + onMount(() => { + document.addEventListener("keydown", handleKeyDown) + }) + + onCleanup(() => { + document.removeEventListener("keydown", handleKeyDown) + }) + + return ( +
+ {/* Header */} +
+ + Question from AI + + +
+ + {/* Tabs for multi-question */} + +
+ + {(q, index) => { + const isActive = () => index() === tab() + const isAnswered = () => (answers()[index()]?.length ?? 0) > 0 + return ( + + ) + }} + + +
+
+ + {/* Question content */} +
+ + {/* Question text */} +
+

+ {question()?.question} + {multi() ? " (select all that apply)" : ""} +

+
+ + {/* Options */} +
+ + {(opt, i) => { + const active = () => i() === selected() + const picked = () => answers()[tab()]?.includes(opt.label) ?? false + return ( + + ) + }} + + + {/* Custom answer option */} + +
+ + + +
+ { + const inputs = [...custom()] + inputs[tab()] = e.currentTarget.value + setCustom(inputs) + }} + onKeyDown={(e) => { + if (e.key === "Enter") { + e.preventDefault() + handleCustomSubmit() + } else if (e.key === "Escape") { + e.preventDefault() + setEditing(false) + } + }} + placeholder="Type your answer..." + class="flex-1 px-3 py-1.5 text-sm rounded-md" + style={{ + background: "var(--background-base)", + border: "1px solid var(--border-base)", + color: "var(--text-base)", + }} + /> + +
+
+ + +

+ {input()} +

+
+
+
+
+
+ + {/* Confirm view for multi-question */} + +
+

+ Review your answers +

+
+ + {(q, index) => { + const value = () => answers()[index()]?.join(", ") ?? "" + const answered = () => Boolean(value()) + return ( +
+ + {q.header}: + {" "} + + {answered() ? value() : "(not answered)"} + +
+ ) + }} +
+
+
+ + +
+
+ + {/* Footer with keyboard hints */} +
+ + + + Tab + {" "} + switch + + + + + + {"\u2191\u2193"} + {" "} + select + + + + + Enter + {" "} + {confirm() ? "submit" : multi() ? "toggle" : single() ? "submit" : "confirm"} + + + + Esc + {" "} + dismiss + +
+
+ ) +} diff --git a/prokube/app-prefixable/src/components/terminal.tsx b/prokube/app-prefixable/src/components/terminal.tsx index 211c9ce3cdb..01e72e1c00b 100644 --- a/prokube/app-prefixable/src/components/terminal.tsx +++ b/prokube/app-prefixable/src/components/terminal.tsx @@ -38,7 +38,6 @@ export function Terminal(props: TerminalProps) { const wsUrl = url.replace(/^http/, "ws") + `/pty/${props.ptyId}/connect?directory=${encodeURIComponent(directory || "")}` console.log("[Terminal] Connecting to:", wsUrl) - writeStatus(`Connecting to ${wsUrl}...`, "info") setStatus("connecting") setError(null) @@ -48,7 +47,6 @@ export function Terminal(props: TerminalProps) { ws.addEventListener("open", () => { console.log("[Terminal] WebSocket connected") setStatus("connected") - writeStatus("Connected! Waiting for shell output...", "success") // Send initial size after connection if (term) { @@ -102,17 +100,35 @@ export function Terminal(props: TerminalProps) { onMount(() => { console.log("[Terminal] Mounting, ptyId:", props.ptyId) - // Create terminal + // Create terminal with light theme term = new XTerm({ cursorBlink: true, cursorStyle: "bar", fontSize: 14, fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace", theme: { - background: "#1a1a1a", - foreground: "#d4d4d4", - cursor: "#d4d4d4", - selectionBackground: "rgba(255, 255, 255, 0.2)", + background: "#ffffff", + foreground: "#1f2937", + cursor: "#1f2937", + cursorAccent: "#ffffff", + selectionBackground: "rgba(59, 130, 246, 0.3)", + selectionForeground: "#1f2937", + black: "#1f2937", + red: "#dc2626", + green: "#16a34a", + yellow: "#ca8a04", + blue: "#2563eb", + magenta: "#9333ea", + cyan: "#0891b2", + white: "#f3f4f6", + brightBlack: "#6b7280", + brightRed: "#ef4444", + brightGreen: "#22c55e", + brightYellow: "#eab308", + brightBlue: "#3b82f6", + brightMagenta: "#a855f7", + brightCyan: "#06b6d4", + brightWhite: "#ffffff", }, scrollback: 10000, }) @@ -125,10 +141,8 @@ export function Terminal(props: TerminalProps) { term.open(container) console.log("[Terminal] Terminal opened in container") - // Show initial status - writeStatus(`Terminal initialized (PTY ID: ${props.ptyId})`, "info") - writeStatus(`Server URL: ${url}`, "info") - writeStatus(`Directory: ${directory || "(none)"}`, "info") + // Show initializing message + writeStatus("Initializing terminal...", "info") // Send terminal input to WebSocket term.onData((data) => { @@ -200,7 +214,7 @@ export function Terminal(props: TerminalProps) { ref={container} class="size-full" style={{ - background: "#1a1a1a", + background: "#ffffff", padding: "8px", "min-height": "100px", }} diff --git a/prokube/app-prefixable/src/components/tool-part.tsx b/prokube/app-prefixable/src/components/tool-part.tsx index 808c7c07413..bb10502c265 100644 --- a/prokube/app-prefixable/src/components/tool-part.tsx +++ b/prokube/app-prefixable/src/components/tool-part.tsx @@ -1,4 +1,4 @@ -import { createSignal, Show, For } from "solid-js" +import { createSignal, createEffect, Show, For } from "solid-js" import type { Part, ToolPart as SDKToolPart, ToolState } from "@opencode-ai/sdk/v2/client" import { ChevronDown } from "lucide-solid" import { ContentDiff } from "./diff/content-diff" @@ -143,16 +143,26 @@ function getMetadata(state: ToolState): Record | undefined { export function ToolPartDisplay(props: { part: ToolPart }) { const [expanded, setExpanded] = createSignal(false) + let autoExpanded = false const state = () => props.part.state const status = () => getStatus(state()) - const canExpand = () => hasOutput(state()) - const title = () => getTitle(state()) || props.part.tool const metadata = () => getMetadata(state()) const isEdit = () => props.part.tool === "edit" const hasDiff = () => isEdit() && metadata()?.diff + // Can expand if has output OR has diff + const canExpand = () => hasOutput(state()) || hasDiff() + const title = () => getTitle(state()) || props.part.tool const filePath = () => (getInput(state()) as { filePath?: string })?.filePath || "" + // Auto-expand edit tools when diff becomes available (only once) + createEffect(() => { + if (hasDiff() && !autoExpanded) { + autoExpanded = true + setExpanded(true) + } + }) + return (
- {/* Diff display for edit tools - shown inline (not in expanded section) */} - + {/* Diff display for edit tools - controlled by expanded state */} +
diff --git a/prokube/app-prefixable/src/context/terminal.tsx b/prokube/app-prefixable/src/context/terminal.tsx index 5e86d355baa..799f07e5b26 100644 --- a/prokube/app-prefixable/src/context/terminal.tsx +++ b/prokube/app-prefixable/src/context/terminal.tsx @@ -37,6 +37,14 @@ export function TerminalProvider(props: ParentProps) { setCreating(true) setError(null) try { + // Ensure the directory exists before creating the PTY + if (cwd) { + console.log("[Terminal] Ensuring directory exists:", cwd) + await client.file.mkdir({ path: cwd }).catch(() => { + // Directory might already exist, ignore error + }) + } + console.log("[Terminal] Creating PTY session, cwd:", cwd) const res = await client.pty.create({ cwd }) console.log("[Terminal] PTY create response:", res) diff --git a/prokube/app-prefixable/src/index.html b/prokube/app-prefixable/src/index.html index eb066920a4b..ce969c81033 100644 --- a/prokube/app-prefixable/src/index.html +++ b/prokube/app-prefixable/src/index.html @@ -8,6 +8,7 @@ +