● Zion Boggan zionboggan.com ↗

Zion PM v2 - initial build (SEED §10 acceptance complete)

Self-hosted PM app: GLM conductor (Mastra, Z.ai subscription) delegating to
claude/codex/ollama workers, with Chat/Board/Fleet UI, SQLite store, MCP-backed
memory (homelab-rag + cbm-homelab), and an approval outbox.

- Runs on CT120 (rebuilt clean Debian 12) at :4100, behind Traefik + Authentik
  at https://REDACTED-HOST.
- All 8 SEED §10 acceptance checks verified live.
- Old bash-sketch conductor archived under archive/old-conductor-sketch.
7f6862c   zionboggan committed on Jun 21, 2026 (1 month ago)
.env.example +14 -0
@@ -0,0 +1,14 @@
+# Zion PM v2 - environment (copy to .env.local on CT120; never commit real values)
+ZAI_API_KEY= # Z.ai Coding Plan subscription key (from /shared/projects/.env.secrets, CRLF-stripped)
+PM_BRAIN_MODEL=glm-4.6 # also: glm-4.5, glm-5.2
+ZAI_BASE_URL=https://api.z.ai/api/anthropic/v1
+ZPM_DATA_DIR=/opt/zion-pm/data
+ZPM_SSH_KEY=/root/.ssh/id_ed25519
+ZPM_OLLAMA_URL=http://REDACTED-IP:11434
+ZPM_OLLAMA_DEFAULT=mistral-nemo:12b
+ZPM_CLAUDE_USER=root # root@CT215 has the valid claude login
+ZPM_CLAUDE_HOST=REDACTED-IP
+ZPM_CODEX_HOST=REDACTED-IP
+ZPM_CODEX_USER=zion
+ZPM_RAG_SSE=http://REDACTED-IP:9876/sse
+ZPM_CBM_SSE=http://REDACTED-IP:9877/sse
.gitignore +13 -0
@@ -0,0 +1,13 @@
+node_modules/
+.next/
+out/
+build/
+data/
+*.log
+.env
+.env.*
+!.env.example
+.DS_Store
+*.tsbuildinfo
+next-env.d.ts
+.serena/
OPS_RUNBOOK.md +62 -0
@@ -0,0 +1,62 @@
+# Zion PM v2 - Ops Runbook
+
+Host: **CT120 (zion-pm, REDACTED-IP)** on the pve node. App at `/opt/zion-pm`, served on `:4100`, fronted at `https://REDACTED-HOST` (Traefik CT244 + Authentik CT246).
+
+## Service control (CT120)
+
+```bash
+systemctl status zion-pm
+systemctl restart zion-pm
+journalctl -u zion-pm -f # live logs
+ss -tlnp | grep 4100 # confirm listening
+```
+
+## Deploy a change
+
+Edit on CT215 (canonical repo `/shared/projects/zion-pm`), commit + push, then on CT120:
+
+```bash
+cd /opt/zion-pm && git pull && pnpm install && pnpm build && systemctl restart zion-pm
+```
+
+Never edit/run from the share (`/shared/projects` is noexec CIFS). Canonical repo on share, app runs from `/opt`.
+
+## Health checks
+
+```bash
+curl -s localhost:4100/api/channels # 4 seeded channels
+curl -s localhost:4100/api/fleet # worker availability
+curl -s -X POST localhost:4100/api/fleet/ping -H 'content-type: application/json' -d '{"model":"glm"}'
+curl -sk -D - -o /dev/null https://REDACTED-HOST/ # expect 302 -> auth.lab
+```
+
+## Fleet dependencies
+
+| Worker | Endpoint | Auth | Notes |
+|---|---|---|---|
+| glm (brain) | `https://api.z.ai/api/anthropic/v1` | `ZAI_API_KEY` | subscription, weekly cap (not PAYG) |
+| claude | SSH `root@REDACTED-IP` | CT120 key | `IS_SANDBOX=1` + `~/.local/bin` PATH |
+| codex | SSH `zion@REDACTED-IP` | CT120 key | `codex exec`, cwd `/tmp` (CIFS stalls sandbox) |
+| ollama | `http://REDACTED-IP:11434` | none | 3060; CT205 was offline at build |
+| queryMemory | MCP SSE `:9876` (CT215) | none | homelab-rag |
+| queryGraph | MCP SSE `:9877` (CT215) | none | cbm-homelab |
+
+## Common issues
+
+- **Worker `exit 127`**: binary not on non-login SSH PATH. Adapters prepend `~/.local/bin:/usr/local/bin`.
+- **claude `401`**: zion's claude login is invalid; the worker uses `root@CT215` (valid). Re-auth with `claude` as the target user if it breaks.
+- **claude refuses `--dangerously-skip-permissions` as root**: set `IS_SANDBOX=1` (the adapter does).
+- **codex timeout**: codex exec is slow (~30s+ cold). Default timeout 240s; keep cwd small/local.
+- **ollama unreachable**: if the 3060 sleeps, wake via CT244 control plane `curl http://REDACTED-IP:8765/wake/3060`. If CT205/pve-gpu returns, point `ZPM_OLLAMA_URL` back at `http://REDACTED-IP:11434`.
+- **pm.lab 404 from Authentik**: the `zion-pm` application/provider is missing on the embedded outpost - recreate it (see SEED build log) and the outpost reloads.
+- **Native module "bindings not found"**: `cd /opt/zion-pm/node_modules/.pnpm/better-sqlite3@*/node_modules/better-sqlite3 && npm run build-release`.
+
+## Recovery
+
+- **CT120 rebuild**: the parked perseus CT120 was backed up to PBS as `ct/120/2026-06-21T00:30:53Z` before the rebuild. The old KeePassXC vault is rescued at `/root/ct120-vault-rescue/homelab.kdbx` on CT215. `pct restore 120 <backup>` restores the old perseus.
+
+## Edge / SSO config
+
+- Traefik route: `CT244:/opt/edge/traefik/dynamic/pm.yml` → `http://REDACTED-IP:4100`, middleware `sso-auth@file`.
+- Authentik: proxy provider "Zion PM forwardAuth" + app `zion-pm` on the embedded outpost (CT246).
+- DNS: `REDACTED-HOST` resolves to CT244 via the existing `*.lab` wildcard.
README.md +96 -0
@@ -0,0 +1,96 @@
+# Zion PM v2
+
+A single self-hosted Project Manager app for Zion's homelab. The PM brain is **GLM** (via the Z.ai Coding Plan subscription); it takes any task, decomposes it, delegates work to the worker fleet (Claude, Codex, local Ollama), supervises, and gates every outward action behind an approval outbox.
+
+One surface, three panes:
+- **Chat** - channels with a default model; `@mention` any model mid-conversation.
+- **Board** - kanban tasks (todo / doing / done / blocked).
+- **Fleet** - worker status, cap gauges, ping, and the approval outbox.
+
+Built per `SEED.md` (the authoritative charter). Runs on **CT120 (REDACTED-IP)**, fronted at **https://REDACTED-HOST** behind Authentik SSO.
+
+## Architecture
+
+```
+REDACTED-HOST (Traefik + Authentik forwardAuth, CT244)
+ │
+ ▼ http://REDACTED-IP:4100
+Next.js app (App Router, port 4100)
+ │ REST API routes
+ ▼
+pmConductor (Mastra Agent, GLM via Z.ai Anthropic-compat)
+ │ tools: delegate / createTask / updateTask / draftApproval
+ ▼
+Worker adapters ──► claude (SSH root@CT215, claude -p)
+ ──► codex (SSH zion@CT241, codex exec)
+ ──► ollama (HTTP 3060 /api/chat)
+shared memory ──► queryMemory (homelab-rag MCP :9876)
+ ──► queryGraph (cbm-homelab MCP :9877)
+store ───────────► better-sqlite3 at data/zionpm.db
+```
+
+GLM is the **conductor**, not a worker. Worker tier = claude / codex / ollama, with strong→weak fallback (claude → codex → ollama) when a model is capped.
+
+## Layout
+
+| Path | Purpose |
+|---|---|
+| `lib/glm.ts` | GLM model via Z.ai Anthropic-compat (`@ai-sdk/anthropic`, custom baseURL) |
+| `lib/mastra.ts` | `pmConductor` Mastra agent + tool registry + `runConductor()` |
+| `lib/memory.ts` | `queryMemory` / `queryGraph` over the MCP SDK (SSE) |
+| `lib/router.ts` | channel-default + `@mention` dispatch (§7) |
+| `lib/db.ts` | SQLite schema + seed + accessors (§5) |
+| `lib/workers/{delegate,claude,codex,ollama,ssh}.ts` | worker adapters + tier fallback (§6) |
+| `app/api/**` | REST routes (channels, messages, tasks, outbox, fleet) |
+| `app/page.tsx` | Chat / Board / Fleet UI |
+
+## Configuration (`.env.local`, never committed)
+
+| Var | Default | Notes |
+|---|---|---|
+| `ZAI_API_KEY` | - | Z.ai Coding Plan subscription key (from `.env.secrets`, CRLF-stripped) |
+| `PM_BRAIN_MODEL` | `glm-4.6` | conductor model (also `glm-4.5`, `glm-5.2`) |
+| `ZAI_BASE_URL` | `https://api.z.ai/api/anthropic/v1` | Anthropic-compatible endpoint |
+| `ZPM_OLLAMA_URL` | `http://REDACTED-IP:11434` | 3060 Ollama (CT205 GPU node was offline at build) |
+| `ZPM_CLAUDE_USER` | `root` | root@CT215 has the working claude login |
+| `ZPM_SSH_KEY` | `/root/.ssh/id_ed25519` | CT120 key, authorized on CT215 + CT241 |
+| `ZPM_RAG_SSE` / `ZPM_CBM_SSE` | `:9876` / `:9877` | MCP SSE endpoints |
+
+Secrets live only in `.env.local` on CT120 and `/shared/projects/.env.secrets`. Never in code or git.
+
+## Run / deploy
+
+The canonical repo lives on the share at `/shared/projects/zion-pm` (committed from CT215). The app **runs from CT120 local fs** `/opt/zion-pm` (noexec CIFS rule - never execute from the share). Deploy = `git pull` on CT120.
+
+```bash
+# on CT120
+cd /opt/zion-pm
+git pull
+pnpm install
+pnpm build
+sudo systemctl restart zion-pm # next start -p 4100
+```
+
+Service: `zion-pm.service` (systemd, onboot). Logs: `journalctl -u zion-pm -f`.
+
+## Acceptance (SEED §10) - all 8 verified
+
+1. Boot: CT120 clean, app on :4100, pm.lab behind Authentik login.
+2. Channels `#pm`(glm) / `#claude` / `#codex` / `#ollama` seeded with model badges.
+3. GLM conductor: 5-bullet cbm-homelab summary grounded via queryMemory/queryGraph.
+4. `@ollama:mistral-nemo:12b` override → Ollama reply authored `ollama`.
+5. `@claude` → SSH CT215 → `claude -p` creates a file; path returned.
+6. Board: task created, drag todo→done persists.
+7. Fleet: glm + claude + codex + ollama green; Ping returns latency for each.
+8. Outbox: conductor/UI drafts an outward action → Approve/Reject; nothing auto-sends.
+
+## Build notes / deviations from SEED
+
+- **Node 22 LTS** (not 20): `create-mastra`/Mastra require Node ≥22.13.
+- **Scaffold**: `create-next-app` + `@mastra/core` (the `--template nextjs` flag was not usable non-interactively). Honors the locked "Mastra/TypeScript" decision.
+- **Ollama host**: CT205 / the pve-gpu node were **offline** at build time; the worker uses the documented overflow 3060 at `REDACTED-IP` (has `mistral-nemo:12b`).
+- **Claude worker** runs as `root@CT215` with `IS_SANDBOX=1` (zion's claude login returned 401; root's is valid; root needs the sandbox flag for `--dangerously-skip-permissions`).
+- **Live updates**: polling (MVP) rather than websockets (SEED permits).
+- **Authentik**: a proxy provider + `zion-pm` application were added to the embedded outpost for `pm.lab` (mirrors the dashboard/notes apps).
+
+See `OPS_RUNBOOK.md` for operations and `SEED.md` for the full charter.
SEED.md +363 -0
@@ -0,0 +1,363 @@
+# Zion PM v2 - Build Spec (SEED)
+
+> **Status:** AUTHORITATIVE build charter. Execute top-to-bottom.
+> **Origin:** Authored by GLM (CT247 opencode session) for Claude CT215 to implement.
+> **Date:** 2026-06-20. **Target:** live today.
+> **Replaces:** `claude-memory/zion-pm-conductor.md` (the earlier sketch - this is the real build).
+
+---
+
+## 1. Mission
+
+A single self-hosted app that is Zion's **Project Manager**. The PM is GLM (Z.ai) - it takes any task,
+decomposes it, **delegates work to the other models** (Claude Max, Codex Max, local Ollama),
+supervises, and gates every outward action behind an approval outbox. The UX is one unified surface:
+**Chat channels** (pick a model when creating a channel, or `@model` mid-chat), a **Board** (tasks), and a
+**Fleet** pane (worker status + quota gauges). It absorbs the channel/mention concepts of Mattermost and
+the board concept of Plane.so **into one bespoke Mastra app** - no dependency on either.
+
+The PM system is built by the model fleet it will eventually manage - Claude CT215 is the lead executor
+of this spec.
+
+## 2. Locked decisions (do NOT re-litigate)
+
+| Decision | Value | Rationale |
+|---|---|---|
+| Brain runtime | **Mastra (TypeScript)** | User choice; agent/workflow primitives + Next.js pairing |
+| Host | **CT120** (destroy + recreate clean Debian 12) | Was parked `perseus` 1c/1GB; repurposed |
+| Surface | **Unified bespoke app** (no Mattermost/Plane fork) | "Fork into one" = one Mastra app absorbing their concepts |
+| PM brain model | **GLM** via Z.ai Coding Plan **subscription** (weekly cap, NOT PAYG) - Anthropic-compat endpoint | Frees Claude Max for dev work; model id via `PM_BRAIN_MODEL` env (default = what the plan serves, e.g. `glm-4.6`/`glm-5.2`; confirm at build) |
+| Model roster | GLM (Z.ai Coding Plan sub), Claude Max, Codex Max, local Ollama | **No PAYG per-token API ever.** Subscription-only: CLI/container-auth (Claude, Codex) + Z.ai Coding Plan sub. Adding a future subscription model = 1 adapter file (see §6) |
+| Delegation primitive | **Spawn agent processes** (CLI/SSH/HTTP), not API calls | Auth lives inside each logged-in worker |
+| Build horizon | **Today** | Parallel dispatch across the fleet |
+
+## 3. Verified infra facts (build on these)
+
+### CT120 - target host
+- **Current:** `perseus`, PARKED 2026-06-16, stopped, onboot=0, 1c/1024MB, rootfs intact.
+- **Action:** `pct destroy 120` then recreate clean from debian-12 template (see §9 step 1).
+- **Recommended resources:** **4 cores / 6GB RAM / 2GB swap / 24GB disk, onboot=1.**
+- **Recommended IP:** static **REDACTED-IP** (mnemonic, free).
+- **Host:** pve node `root@REDACTED-IP` (Dell R410, Xeon E5645, 24c/31GB, 3.5TB free).
+
+### Fleet endpoints (all LAN-reachable from CT120)
+| Role | Host | Transport | Notes |
+|---|---|---|---|
+| GLM brain (this PM) | `https://api.z.ai/api/anthropic` | HTTPS, `ZAI_API_KEY` (from Z.ai Coding Plan **subscription**, weekly cap - NOT PAYG) | Anthropic-compat; model id via `PM_BRAIN_MODEL` env, default = plan's current (this CT247 session routes `zai/glm-5.2`; confirm `/api/anthropic` id at build) |
+| Claude Max worker | `zion@REDACTED-IP` (CT215) | SSH + `claude -p` | Claude Code, `--dangerously-skip-permissions` ok; tmux pool optional |
+| Codex Max worker | `zion@REDACTED-IP` (CT241) | SSH + `codex exec` | `codex-full`/`cdx` wrappers; `approval_policy=never`, full sandbox |
+| Ollama worker (free tier) | `http://REDACTED-IP:11434` (CT205) | HTTP `/api/chat` | RTX 3060 12GB on pve-gpu node; models: `qwen2.5-coder:7b`, `deepseek-coder-v2`, `mistral-nemo:12b` |
+| Ollama overflow | `http://REDACTED-IP:11434` (WIN3060) | HTTP | Second 3060; desktop may sleep - optional |
+| homelab-rag MCP | `http://REDACTED-IP:9876/sse` | SSE | Conductor's `queryMemory` tool |
+| cbm-homelab MCP | `http://REDACTED-IP:9877/sse` | SSE | Conductor's `queryGraph` tool |
+| serena MCP | `http://REDACTED-IP:9878/sse` | SSE | Optional for MVP |
+| memory-graph MCP | `http://REDACTED-IP:9879/sse` | SSE | Optional for MVP; durable cross-agent memory |
+| Traefik edge | CT244 `REDACTED-IP` | dynamic YAML | `/opt/edge/traefik/dynamic/*.yml` |
+| Authentik SSO | CT246 `REDACTED-HOST` | forwardAuth middleware | Reuse `authentik-forwardauth@docker` (same as vault.lab/notes.lab) |
+
+### Operational doctrine (from homelab conventions - obey)
+- **noexec CIFS rule:** the canonical repo lives at `/shared/projects/zion-pm/` (git, committed from CT215),
+ but the **app runs from CT120 local fs** `/opt/zion-pm`. Deploy = `git clone` / `git pull` on CT120. Never
+ execute from the share.
+- **RAG-first:** the conductor must call `queryMemory` (homelab-rag MCP) before reading/grepping files.
+- **Secret hygiene:** `ZAI_API_KEY` lives in `/shared/projects/.env.secrets` (has CRLF - strip when sourcing).
+ Workers SSH via **keys**, never passwords in code. Treat `[REDACTED:...]` as proof a secret exists.
+- **Approval outbox:** every outward action (email / deploy / publish / infra) **drafts** - never auto-fires.
+ Internal/reversible work (PM↔worker delegation, file edits) is full-auto.
+- **Git:** commits to `/shared/projects` happen from CT215 (per homelab rule).
+
+## 4. Architecture
+
+```
+ ┌─────────────── REDACTED-HOST (Traefik+Authentik) ──────────────┐
+ Zion (PWA) ──▶│ Next.js UI - Chat / Board / Fleet panes (:4100) │
+ └─────────────────────────────┬──────────────────────────────────────────┘
+ │ websocket / REST
+ ▼
+ ┌─────────── Mastra runtime ────────────┐
+ │ pmConductor agent (GLM via Z.ai) │
+ │ Tools: │
+ │ delegate(model, task, opts) │
+ │ createTask / updateTask │
+ │ draftApproval(action) │
+ │ queryMemory (→ homelab-rag MCP) │
+ │ queryGraph (→ cbm-homelab MCP) │
+ └───┬──────────┬──────────┬──────────┬───┘
+ ▼ ▼ ▼ ▼
+ ┌─────────────────────────────────────────────────────────┐
+ │ Worker adapters (TS) cap table (sqlite) │
+ │ claude → SSH CT215 `claude -p` ▓▓▓░ Max │
+ │ codex → SSH CT241 `codex exec` ▓▓░░ Max │
+ │ ollama → HTTP CT205 /api/chat ▓▓▓▓ free │
+ └─────────────────────────────────────────────────────────┘
+ (GLM conductor is the brain itself - NOT a worker adapter. Workers = claude/codex/ollama only.)
+ │
+ ▼ (every worker may also mount the 4 MCPs)
+ shared memory substrate (rag + cbm + serena + mem-graph)
+```
+
+### Layers
+1. **Mastra runtime** - `pmConductor` agent (GLM). Holds the system prompt, the tool registry, and the
+ workflow for decompose→delegate→verify.
+2. **Worker adapters** - one TS module per model behind a unified `delegate()` entry point. Each knows its
+ transport. A **cap table** gates availability and provides tier fallback.
+3. **Router** - message ingestion → resolve channel-default-model + parse `@mentions` → route to conductor
+ (if glm) or direct-dispatch (otherwise) → stream reply back to UI.
+4. **Web UI (Next.js)** - three panes: Chat, Board, Fleet. Mobile-first PWA.
+5. **Store** - libSQL/sqlite at `/opt/zion-pm/data/zionpm.db`.
+6. **Edge** - Traefik `pm.lab` route + Authentik forwardAuth.
+
+## 5. Data model (sqlite)
+
+```sql
+CREATE TABLE channels(
+ id TEXT PRIMARY KEY, -- ulid
+ name TEXT NOT NULL UNIQUE,
+ default_model TEXT NOT NULL, -- glm|claude|codex|ollama
+ created_at INTEGER NOT NULL
+);
+CREATE TABLE messages(
+ id TEXT PRIMARY KEY,
+ channel_id TEXT NOT NULL REFERENCES channels(id),
+ role TEXT NOT NULL, -- user|assistant|system
+ author_model TEXT, -- which model produced an assistant msg
+ body TEXT NOT NULL,
+ parent_id TEXT REFERENCES messages(id), -- threading
+ created_at INTEGER NOT NULL
+);
+CREATE TABLE tasks(
+ id TEXT PRIMARY KEY,
+ title TEXT NOT NULL,
+ status TEXT NOT NULL DEFAULT 'todo', -- todo|doing|done|blocked
+ assigned_model TEXT,
+ channel_id TEXT REFERENCES channels(id),
+ created_at INTEGER NOT NULL,
+ updated_at INTEGER NOT NULL
+);
+CREATE TABLE outbox( -- approval-gated outward actions
+ id TEXT PRIMARY KEY,
+ action_type TEXT NOT NULL, -- email|deploy|publish|infra
+ payload_json TEXT NOT NULL,
+ status TEXT NOT NULL DEFAULT 'draft', -- draft|approved|rejected|sent
+ created_at INTEGER NOT NULL,
+ approved_at INTEGER
+);
+CREATE TABLE cap_state(
+ model TEXT PRIMARY KEY,
+ available INTEGER NOT NULL, -- 0/1
+ reason TEXT,
+ last_checked INTEGER NOT NULL
+);
+```
+
+## 6. Worker adapter contracts (the delegation core)
+
+### Types
+```ts
+export type ModelId = 'glm' | 'claude' | 'codex' | 'ollama';
+export type OllamaModel = 'qwen2.5-coder:7b' | 'deepseek-coder-v2:16b' | 'mistral-nemo:12b';
+
+export interface DelegateParams {
+ model: ModelId;
+ ollamaModel?: OllamaModel; // required iff model === 'ollama'
+ task: string; // the work envelope (self-contained)
+ context?: string; // RAG/graph snippets to inject
+ cwd?: string; // working dir on the worker host (claude/codex)
+ timeoutMs?: number; // default 120_000
+}
+
+export interface DelegateResult {
+ ok: boolean;
+ output: string; // stdout / model reply
+ artifacts: string[]; // file paths produced (claude/codex)
+ error?: string;
+ durationMs: number;
+}
+```
+
+### `delegate()` entry point (src/workers/delegate.ts)
+1. Check `cap_state[model]`; if unavailable, **escalate tier**: claude→codex→ollama (strong→weak).
+ The conductor may override.
+2. Call the matching adapter.
+3. Persist a `messages` row (author_model) + update `cap_state.last_checked`.
+4. Return `DelegateResult`.
+
+### Adapters
+- **`claudeAdapter`** (src/workers/claude.ts): SSH `zion@REDACTED-IP`, run
+ `claude -p '<task>' --dangerously-skip-permissions` in `cwd` (default `/shared/projects`). Capture stdout.
+ Use `ssh2` (node) with key auth. MVP = one-shot; phase 2 = tmux pool `pm-claude-N`.
+- **`codexAdapter`** (src/workers/codex.ts): SSH `zion@REDACTED-IP`, run `codex exec '<task>'`
+ (or `cdx` wrapper) in `cwd`. Capture stdout.
+- **`ollamaAdapter`** (src/workers/ollama.ts): `POST http://REDACTED-IP:11434/api/chat`
+ `{model: ollamaModel, messages:[{role:'system',...},{role:'user',content:task}], stream:false}`.
+ Parse `message.content`.
+
+> **No `glm-sub` adapter** - the conductor (GLM) does all GLM reasoning itself. Worker tier = claude/codex/ollama only.
+>
+> **Adding a future subscription model** (e.g. a Gemini CLI sub, Cursor, etc.): create one new
+> `src/workers/<model>.ts` implementing the `DelegateParams→DelegateResult` contract, add one row to
+> `cap_state`, and one option in the channel model-picker + mention grammar. Same pattern as claude/codex.
+
+### SSH key setup (WS-A, once)
+On CT120 as the app user: `ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519`, then append the pubkey to
+`/home/zion/.ssh/authorized_keys` on **CT215** and **CT241** (the user `zion`). Verify:
+`ssh -o BatchMode=yes zion@REDACTED-IP 'echo ok'` returns `ok`.
+
+## 7. Router (channel-default + @mention)
+
+```ts
+// src/router.ts - pseudocode
+async function onMessage(channelId, userId, text) {
+ const binding = (await db.channels.get(channelId)).default_model;
+ const mentions = parseMentions(text); // ['@claude', ...] → ['claude']
+ const targets = mentions.length ? mentions : [binding];
+
+ const ragCtx = await conductor.tools.queryMemory(text); // always inject memory
+
+ for (const target of targets) {
+ let reply: string;
+ if (target === 'glm') {
+ // conductor owns it: may decompose + sub-delegate + verify
+ reply = (await conductor.run(text, { channelId, context: ragCtx })).text;
+ } else {
+ reply = (await delegate({ model: target, task: text, context: ragCtx })).output;
+ }
+ await db.messages.insert({ channelId, role:'assistant', author_model: target,
+ body: reply, parentId, createdAt: Date.now() });
+ io.to(channelId).emit('message', { ... }); // push to UI
+ }
+}
+```
+
+**Mention grammar:** `@(glm|claude|codex|ollama)(?::(\S+))?` - the optional `:model` suffix selects an
+Ollama model, e.g. `@ollama:mistral-nemo:12b`. Mention wins over channel-default **for that turn only**.
+
+## 8. Web UI (Next.js, three panes)
+
+- **Chat** - left: channel list (each shows its default-model badge). Main: threaded message view with
+ author-model color coding + @mention chips. Composer shows the active target model. **New Channel modal:
+ name + model `<select>`** (the "select model in a new channel" UX).
+- **Board** - kanban (todo / doing / done / blocked). Cards = tasks. Drag = status change. Click card →
+ assign model, link to channel.
+- **Fleet** - table: model | status | last task | cap gauge | `Ping` button (runs a trivial delegate and
+ reports latency). Live-updates via websocket.
+
+Stack: Next.js App Router, Tailwind, `@mastra/core`, socket.io (or server actions + polling for MVP).
+Auth = Authentik header (`X-Forwarded-User`) trusted behind Traefik; map to a local user row.
+
+## 9. Build steps (dependency order)
+
+### WS-A - CT120 provision (operator, gates everything)
+```bash
+# on pve node root@REDACTED-IP
+pct stop 120 2>/dev/null; pct destroy 120 --purge
+# create clean debian-12 CT (adjust template/storage to what pve has)
+pct create debian-12 120 \
+ --hostname zion-pm --cores 4 --memory 6144 --swap 2048 \
+ --rootfs local-lvm:24 --onboot 1 \
+ --net0 name=eth0,bridge=vmbr0,ip=REDACTED-IP/24,gw=REDACTED-IP
+pct start 120
+pct enter 120
+# inside CT120:
+apt update && apt -y install nodejs npm git build-essential curl python3
+curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt -y install nodejs # Node 20 LTS
+npm i -g pnpm
+# SSH keys for the app user (run as root or a dedicated 'zionpm' user):
+ssh-keygen -t ed25519 -N "" -f /root/.ssh/id_ed25519
+# distribute pubkey to CT215 + CT241 ~/.ssh/authorized_keys (zion user)
+ssh -o BatchMode=yes zion@REDACTED-IP 'echo ok' # must print ok
+```
+
+### WS-B - Mastra scaffold + conductor (Codex CT241 or Claude CT215)
+```bash
+# on CT120, in /opt
+cd /opt && pnpm create mastra@latest zion-pm --template nextjs
+cd zion-pm && pnpm install
+pnpm add @mastra/mcp ssh2 better-sqlite3 ulid socket.io
+```
+- Wire GLM via Z.ai Anthropic-compat (set `ZAI_API_KEY` env, base URL `https://api.z.ai/api/anthropic`).
+- Define `pmConductor` agent (`src/mastra/agents/pm.ts`) with the §4 tool registry.
+- Register MCP clients for homelab-rag + cbm-homelab via `@mastra/mcp` (SSE URLs in §3).
+
+### WS-C - Worker adapters + cap table (Claude CT215)
+Implement §6 exactly: `src/workers/{delegate,claude,codex,ollama}.ts` (3 adapters + delegate entry) + `src/db.ts`
+(better-sqlite3, schema in §5). Seed `cap_state` with `claude`,`codex`,`ollama` all `available=1` (glm = conductor, not a worker row).
+
+### WS-D - Next.js UI (Claude CT215)
+Implement §8: Chat / Board / Fleet panes, new-channel model picker, @mention rendering. Seed channels:
+`#pm`(glm), `#claude`, `#codex`, `#ollama`.
+
+### WS-E - Router (GLM CT247 / this session can also do it)
+Implement §7: message ingestion, channel-default + mention parse, dispatch loop, websocket push.
+
+### WS-F - Edge + SSO (Codex CT241)
+On CT244 add `/opt/edge/traefik/dynamic/pm.yml`:
+```yaml
+http:
+ routers:
+ pm:
+ rule: Host(`REDACTED-HOST`)
+ entrypoints: [websecure]
+ tls: { certResolver: letsencrypt }
+ service: pm
+ middlewares: [authentik-forwardauth@docker]
+ services:
+ pm:
+ loadBalancer:
+ servers: [{ url: http://REDACTED-IP:4100 }]
+```
+Add `REDACTED-HOST` to AdGuard/local DNS → CT244. Reload Traefik. Confirm Authentik forwardAuth
+applies (mirror `vault.lab`).
+
+### WS-G - Integration + e2e test (GLM, this session)
+Run the §10 acceptance test. Document at `/shared/projects/zion-pm/` (README, ops runbook, this SEED).
+Git-commit from CT215.
+
+## 10. Acceptance test - "done today" bar
+
+All of these must pass end-to-end on `https://REDACTED-HOST`:
+
+1. **Boot:** CT120 clean, app serves :4100, `pm.lab` resolves behind Authentik login.
+2. **Channels seeded:** `#pm`(glm), `#claude`, `#codex`, `#ollama` visible with correct model badges.
+3. **GLM conductor (channel-default):** Post in `#pm`: *"Summarize the cbm-homelab project's architecture
+ in 5 bullets."* → conductor calls `queryMemory`/`queryGraph` → posts a 5-bullet reply authored by `glm`.
+4. **@mention override:** In `#pm`: *"@ollama:mistral-nemo:12b suggest 3 names for this PM app"* → routes
+ to Ollama CT205 → inline reply authored by `ollama`, despite channel default being glm.
+5. **Heavy delegation:** In `#pm`: *"@claude create a README.md at /shared/projects/zion-pm/ describing this
+ app"* → claude adapter SSHes CT215, runs `claude -p`, returns → reply posts with the file path; file exists.
+6. **Board:** a task created from a conversation appears on the Board, assignable, drag todo→done persists.
+7. **Fleet:** all three workers (claude/codex/ollama) + the GLM conductor show green; `Ping` returns latency for each.
+8. **Approval outbox:** conductor drafts a (stub) outward action → appears as `draft` in outbox → UI shows
+ Approve/Reject → approving marks `approved`; nothing auto-sends.
+
+## 11. Operating rules (non-negotiable)
+
+1. **noexec CIFS** - app runs from `/opt/zion-pm` on CT120, never from `/shared/projects`.
+2. **RAG-first** - conductor queries homelab-rag MCP before any file read.
+3. **Secrets** - `ZAI_API_KEY` from `.env.secrets` (strip CRLF); SSH keys only; never print secrets.
+4. **Approval outbox** - outward actions draft only; internal delegation is full-auto.
+5. **Git** - canonical repo at `/shared/projects/zion-pm`, remote = **private `github.com/zionboggan/zion-pm`**; commit + push from CT215; CT120 deploys via `git pull`.
+6. **Cap-aware** - never silently drop a task; fall through tiers or queue with a visible Board card.
+
+## 12. Out of scope (phase 2+)
+
+- Voice/email intake (`intake-voice.sh`, `intake-email.py` from the old sketch).
+- Multi-account email sender identities (`policy.yaml > sender_identities`).
+- Cockpit PWA skin over this app's API.
+- Tmux worker pools (MVP is ephemeral one-shot `claude -p`/`codex exec`; promote to persistent pooled sessions later).
+- Cap auto-detection from Claude/Codex/Z.ai usage endpoints.
+- serena + memory-graph MCP wired into workers (MVP uses rag + cbm only).
+
+---
+
+**Handoff line for Claude CT215:**
+> Read `/root/zion-pm/SEED.md` on CT247 (`ssh root@REDACTED-IP 'cat /root/zion-pm/SEED.md'`),
+> copy it to `/shared/projects/zion-pm/SEED.md`, then execute WS-A through WS-G per §9. Lead = you
+> (Claude CT215). Delegate WS-B/F to Codex CT241, WS-E/G stays with GLM. Target: §10 acceptance today.
+> Obey §11. (Decisions baked in: 3 adapters - glm-sub dropped; GLM brain = Z.ai Coding Plan sub not PAYG;
+> repo = private github.com/zionboggan/zion-pm; workers = ephemeral one-shot.)
+
+> **Note on file location:** CT247's local `/shared/projects` mount is read-only (`nobody:nogroup`) and
+> CT247→CT215 SSH is not peered, so the spec could not be written directly to the canonical share from CT247.
+> Claude CT215 fetches it via the SSH command above (CT215→CT247 needs to be peered, or Zion copy-pastes
+> the content). After fetch, commit it to `/shared/projects/zion-pm/SEED.md` as the first WS-G step.
app/api/channels/[id]/messages/route.ts +10 -0
@@ -0,0 +1,10 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { listMessages } from '@/lib/db';
+
+export const runtime = 'nodejs';
+export const dynamic = 'force-dynamic';
+
+export async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
+ const { id } = await params;
+ return NextResponse.json({ messages: listMessages(id) });
+}
app/api/channels/route.ts +18 -0
@@ -0,0 +1,18 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { listChannels, createChannel, getChannelByName } from '@/lib/db';
+
+export const runtime = 'nodejs';
+export const dynamic = 'force-dynamic';
+
+export async function GET() {
+ return NextResponse.json({ channels: listChannels() });
+}
+
+export async function POST(req: NextRequest) {
+ const { name, defaultModel } = await req.json();
+ if (!name || !defaultModel) return NextResponse.json({ error: 'name and defaultModel required' }, { status: 400 });
+ const clean = String(name).trim().replace(/^#/, '').replace(/\s+/g, '-').toLowerCase();
+ if (getChannelByName(clean)) return NextResponse.json({ error: 'channel exists' }, { status: 409 });
+ if (!['glm', 'claude', 'codex', 'ollama'].includes(defaultModel)) return NextResponse.json({ error: 'bad model' }, { status: 400 });
+ return NextResponse.json({ channel: createChannel(clean, defaultModel) });
+}
app/api/fleet/ping/route.ts +48 -0
@@ -0,0 +1,48 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { generateText } from 'ai';
+import { glmModel } from '@/lib/glm';
+import { runSSH } from '@/lib/workers/ssh';
+import { setCap } from '@/lib/db';
+
+export const runtime = 'nodejs';
+export const dynamic = 'force-dynamic';
+export const maxDuration = 120;
+
+const OLLAMA = process.env.ZPM_OLLAMA_URL || 'http://REDACTED-IP:11434';
+
+// Lightweight liveness ping per model (the heavy model path is exercised by delegation).
+async function pingModel(model: string): Promise<{ ok: boolean; latencyMs: number; detail: string }> {
+ const start = Date.now();
+ try {
+ if (model === 'glm') {
+ const r = await generateText({ model: glmModel, prompt: 'Reply with exactly: OK' });
+ return { ok: /ok/i.test(r.text), latencyMs: Date.now() - start, detail: r.text.trim().slice(0, 40) };
+ }
+ if (model === 'claude') {
+ const r = await runSSH('REDACTED-IP', 'zion', 'echo ok', 15_000);
+ return { ok: r.stdout.trim() === 'ok', latencyMs: Date.now() - start, detail: 'CT215 reachable' };
+ }
+ if (model === 'codex') {
+ const r = await runSSH('REDACTED-IP', 'zion', 'echo ok', 15_000);
+ return { ok: r.stdout.trim() === 'ok', latencyMs: Date.now() - start, detail: 'CT241 reachable' };
+ }
+ if (model === 'ollama') {
+ const ctrl = new AbortController();
+ const t = setTimeout(() => ctrl.abort(), 10_000);
+ const res = await fetch(`${OLLAMA}/api/tags`, { signal: ctrl.signal });
+ clearTimeout(t);
+ return { ok: res.ok, latencyMs: Date.now() - start, detail: res.ok ? '3060 ollama up' : `http ${res.status}` };
+ }
+ return { ok: false, latencyMs: 0, detail: 'unknown model' };
+ } catch (e) {
+ return { ok: false, latencyMs: Date.now() - start, detail: (e as Error).message.slice(0, 80) };
+ }
+}
+
+export async function POST(req: NextRequest) {
+ const { model } = await req.json();
+ if (!model) return NextResponse.json({ error: 'model required' }, { status: 400 });
+ const res = await pingModel(model);
+ if (model !== 'glm') setCap(model, res.ok ? 1 : 0, res.ok ? 'ping ok' : `ping fail: ${res.detail}`);
+ return NextResponse.json({ model, ...res });
+}
app/api/fleet/route.ts +18 -0
@@ -0,0 +1,18 @@
+import { NextResponse } from 'next/server';
+import { listCaps } from '@/lib/db';
+import { PM_BRAIN_MODEL } from '@/lib/glm';
+
+export const runtime = 'nodejs';
+export const dynamic = 'force-dynamic';
+
+export async function GET() {
+ const caps = listCaps();
+ const capMap = Object.fromEntries(caps.map((c) => [c.model, c]));
+ const fleet = [
+ { model: 'glm', role: 'conductor', label: PM_BRAIN_MODEL, available: 1, reason: 'brain', last_checked: Date.now() },
+ { model: 'claude', role: 'worker', label: 'Claude Max · CT215', available: capMap.claude?.available ?? 0, reason: capMap.claude?.reason ?? '', last_checked: capMap.claude?.last_checked ?? 0 },
+ { model: 'codex', role: 'worker', label: 'Codex Max · CT241', available: capMap.codex?.available ?? 0, reason: capMap.codex?.reason ?? '', last_checked: capMap.codex?.last_checked ?? 0 },
+ { model: 'ollama', role: 'worker', label: 'Ollama · 3060', available: capMap.ollama?.available ?? 0, reason: capMap.ollama?.reason ?? '', last_checked: capMap.ollama?.last_checked ?? 0 },
+ ];
+ return NextResponse.json({ fleet });
+}
app/api/messages/route.ts +17 -0
@@ -0,0 +1,17 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { handleMessage } from '@/lib/router';
+
+export const runtime = 'nodejs';
+export const dynamic = 'force-dynamic';
+export const maxDuration = 300;
+
+export async function POST(req: NextRequest) {
+ const { channelId, text } = await req.json();
+ if (!channelId || !text) return NextResponse.json({ error: 'channelId and text required' }, { status: 400 });
+ try {
+ const produced = await handleMessage(channelId, String(text));
+ return NextResponse.json({ messages: produced });
+ } catch (e) {
+ return NextResponse.json({ error: (e as Error).message }, { status: 500 });
+ }
+}
app/api/outbox/[id]/route.ts +16 -0
@@ -0,0 +1,16 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { setOutboxStatus } from '@/lib/db';
+
+export const runtime = 'nodejs';
+export const dynamic = 'force-dynamic';
+
+// Approve / reject a drafted outward action. Approving never auto-sends (SEED §11.4).
+export async function POST(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
+ const { id } = await params;
+ const { action } = await req.json();
+ if (!['approve', 'reject'].includes(action)) return NextResponse.json({ error: 'action must be approve|reject' }, { status: 400 });
+ const status = action === 'approve' ? 'approved' : 'rejected';
+ const o = setOutboxStatus(id, status);
+ if (!o) return NextResponse.json({ error: 'not found' }, { status: 404 });
+ return NextResponse.json({ outbox: o });
+}
app/api/outbox/route.ts +16 -0
@@ -0,0 +1,16 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { listOutbox, draftOutbox } from '@/lib/db';
+
+export const runtime = 'nodejs';
+export const dynamic = 'force-dynamic';
+
+export async function GET() {
+ return NextResponse.json({ outbox: listOutbox() });
+}
+
+// Draft a stub outward action (also used by acceptance test #8).
+export async function POST(req: NextRequest) {
+ const { actionType, payload } = await req.json().catch(() => ({}));
+ const o = draftOutbox(actionType || 'publish', payload || { note: 'stub outward action', created_by: 'conductor' });
+ return NextResponse.json({ outbox: o });
+}
app/api/tasks/[id]/route.ts +13 -0
@@ -0,0 +1,13 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { updateTask } from '@/lib/db';
+
+export const runtime = 'nodejs';
+export const dynamic = 'force-dynamic';
+
+export async function PATCH(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
+ const { id } = await params;
+ const patch = await req.json();
+ const t = updateTask(id, patch);
+ if (!t) return NextResponse.json({ error: 'not found' }, { status: 404 });
+ return NextResponse.json({ task: t });
+}
app/api/tasks/route.ts +15 -0
@@ -0,0 +1,15 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { listTasks, createTask } from '@/lib/db';
+
+export const runtime = 'nodejs';
+export const dynamic = 'force-dynamic';
+
+export async function GET() {
+ return NextResponse.json({ tasks: listTasks() });
+}
+
+export async function POST(req: NextRequest) {
+ const { title, status, assignedModel, channelId } = await req.json();
+ if (!title) return NextResponse.json({ error: 'title required' }, { status: 400 });
+ return NextResponse.json({ task: createTask(String(title), { status, assignedModel, channelId }) });
+}
app/favicon.ico +0 -0
Binary file not shown
app/globals.css +26 -0
@@ -0,0 +1,26 @@
+@import "tailwindcss";
+
+:root {
+ --background: #ffffff;
+ --foreground: #171717;
+}
+
+@theme inline {
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --font-sans: var(--font-geist-sans);
+ --font-mono: var(--font-geist-mono);
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --background: #0a0a0a;
+ --foreground: #ededed;
+ }
+}
+
+body {
+ background: var(--background);
+ color: var(--foreground);
+ font-family: Arial, Helvetica, sans-serif;
+}
app/layout.tsx +33 -0
@@ -0,0 +1,33 @@
+import type { Metadata } from "next";
+import { Geist, Geist_Mono } from "next/font/google";
+import "./globals.css";
+
+const geistSans = Geist({
+ variable: "--font-geist-sans",
+ subsets: ["latin"],
+});
+
+const geistMono = Geist_Mono({
+ variable: "--font-geist-mono",
+ subsets: ["latin"],
+});
+
+export const metadata: Metadata = {
+ title: "Create Next App",
+ description: "Generated by create next app",
+};
+
+export default function RootLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode;
+}>) {
+ return (
+ <html
+ lang="en"
+ className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
+ >
+ <body className="min-h-full flex flex-col">{children}</body>
+ </html>
+ );
+}
app/page.tsx +237 -0
@@ -0,0 +1,237 @@
+'use client';
+import { useEffect, useRef, useState, useCallback } from 'react';
+
+type Channel = { id: string; name: string; default_model: string; created_at: number };
+type Message = { id: string; channel_id: string; role: string; author_model: string | null; body: string; parent_id: string | null; created_at: number };
+type Task = { id: string; title: string; status: string; assigned_model: string | null; channel_id: string | null };
+type Outbox = { id: string; action_type: string; payload_json: string; status: string; created_at: number };
+type FleetRow = { model: string; role: string; label: string; available: number; reason: string; last_checked: number };
+
+const MODELS = ['glm', 'claude', 'codex', 'ollama'] as const;
+const COLOR: Record<string, string> = {
+ glm: 'bg-violet-500/20 text-violet-300 border-violet-500/40',
+ claude: 'bg-orange-500/20 text-orange-300 border-orange-500/40',
+ codex: 'bg-sky-500/20 text-sky-300 border-sky-500/40',
+ ollama: 'bg-emerald-500/20 text-emerald-300 border-emerald-500/40',
+ user: 'bg-zinc-600/30 text-zinc-300 border-zinc-500/40',
+};
+const DOT: Record<string, string> = { glm: 'bg-violet-400', claude: 'bg-orange-400', codex: 'bg-sky-400', ollama: 'bg-emerald-400' };
+
+function Badge({ model }: { model: string }) {
+ return <span className={`inline-flex items-center rounded px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide border ${COLOR[model] || COLOR.user}`}>{model}</span>;
+}
+
+const MENTION_RE = /@(glm|claude|codex|ollama)(?::(\S+))?/gi;
+function renderBody(body: string) {
+ const parts: React.ReactNode[] = [];
+ let last = 0; let m: RegExpExecArray | null; MENTION_RE.lastIndex = 0; let i = 0;
+ while ((m = MENTION_RE.exec(body)) !== null) {
+ if (m.index > last) parts.push(<span key={i++}>{body.slice(last, m.index)}</span>);
+ parts.push(<span key={i++} className={`mx-0.5 rounded px-1 py-0.5 text-xs border ${COLOR[m[1].toLowerCase()]}`}>@{m[1]}{m[2] ? ':' + m[2] : ''}</span>);
+ last = m.index + m[0].length;
+ }
+ parts.push(<span key={i++}>{body.slice(last)}</span>);
+ return parts;
+}
+
+export default function Home() {
+ const [tab, setTab] = useState<'chat' | 'board' | 'fleet'>('chat');
+ return (
+ <div className="flex h-screen flex-col bg-zinc-950 text-zinc-100">
+ <header className="flex items-center gap-4 border-b border-zinc-800 px-4 py-2.5">
+ <div className="font-bold tracking-tight">⚓ Zion <span className="text-violet-400">PM</span></div>
+ <nav className="flex gap-1">
+ {(['chat', 'board', 'fleet'] as const).map((t) => (
+ <button key={t} onClick={() => setTab(t)} className={`rounded px-3 py-1 text-sm capitalize ${tab === t ? 'bg-zinc-800 text-white' : 'text-zinc-400 hover:text-zinc-200'}`}>{t}</button>
+ ))}
+ </nav>
+ <div className="ml-auto text-xs text-zinc-500">conductor: <span className="text-violet-400">glm</span></div>
+ </header>
+ <main className="min-h-0 flex-1">
+ {tab === 'chat' && <Chat />}
+ {tab === 'board' && <Board />}
+ {tab === 'fleet' && <Fleet />}
+ </main>
+ </div>
+ );
+}
+
+function Chat() {
+ const [channels, setChannels] = useState<Channel[]>([]);
+ const [active, setActive] = useState<string>('');
+ const [messages, setMessages] = useState<Message[]>([]);
+ const [input, setInput] = useState('');
+ const [sending, setSending] = useState(false);
+ const [showModal, setShowModal] = useState(false);
+ const endRef = useRef<HTMLDivElement>(null);
+
+ const loadChannels = useCallback(async () => {
+ const r = await fetch('/api/channels').then((x) => x.json());
+ setChannels(r.channels || []);
+ if (!active && r.channels?.length) setActive(r.channels.find((c: Channel) => c.name === 'pm')?.id || r.channels[0].id);
+ }, [active]);
+
+ const loadMessages = useCallback(async (id: string) => {
+ if (!id) return;
+ const r = await fetch(`/api/channels/${id}/messages`).then((x) => x.json());
+ setMessages(r.messages || []);
+ }, []);
+
+ useEffect(() => { loadChannels(); }, [loadChannels]);
+ useEffect(() => { if (!active) return; loadMessages(active); const t = setInterval(() => loadMessages(active), 2500); return () => clearInterval(t); }, [active, loadMessages]);
+ useEffect(() => { endRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages]);
+
+ const activeCh = channels.find((c) => c.id === active);
+
+ async function send() {
+ if (!input.trim() || !active || sending) return;
+ const text = input; setInput(''); setSending(true);
+ try { await fetch('/api/messages', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ channelId: active, text }) }); }
+ finally { setSending(false); loadMessages(active); }
+ }
+
+ return (
+ <div className="flex h-full">
+ <aside className="flex w-56 flex-col border-r border-zinc-800">
+ <div className="flex items-center justify-between px-3 py-2 text-xs uppercase tracking-wide text-zinc-500">Channels
+ <button onClick={() => setShowModal(true)} className="rounded bg-zinc-800 px-2 py-0.5 text-zinc-300 hover:bg-zinc-700">+ New</button>
+ </div>
+ <div className="flex-1 overflow-y-auto">
+ {channels.map((c) => (
+ <button key={c.id} onClick={() => setActive(c.id)} className={`flex w-full items-center justify-between px-3 py-1.5 text-sm ${active === c.id ? 'bg-zinc-800' : 'hover:bg-zinc-900'}`}>
+ <span className="text-zinc-300">#{c.name}</span><Badge model={c.default_model} />
+ </button>
+ ))}
+ </div>
+ </aside>
+ <section className="flex min-w-0 flex-1 flex-col">
+ <div className="border-b border-zinc-800 px-4 py-2 text-sm text-zinc-300">#{activeCh?.name} {activeCh && <>· default <Badge model={activeCh.default_model} /></>}</div>
+ <div className="flex-1 space-y-3 overflow-y-auto p-4">
+ {messages.map((m) => (
+ <div key={m.id} className="flex flex-col gap-1">
+ <div className="flex items-center gap-2 text-xs text-zinc-500">{m.role === 'user' ? <span className="font-semibold text-zinc-400">Zion</span> : <Badge model={m.author_model || 'glm'} />}<span>{new Date(m.created_at).toLocaleTimeString()}</span></div>
+ <div className={`max-w-[80ch] whitespace-pre-wrap rounded-lg border px-3 py-2 text-sm ${m.role === 'user' ? 'border-zinc-700 bg-zinc-900' : 'border-zinc-800 bg-zinc-900/50'}`}>{renderBody(m.body)}</div>
+ </div>
+ ))}
+ {sending && <div className="text-xs text-zinc-500">dispatching…</div>}
+ <div ref={endRef} />
+ </div>
+ <div className="border-t border-zinc-800 p-3">
+ <div className="mb-1 text-[11px] text-zinc-500">target: {input.match(MENTION_RE)?.map((x) => x).join(' ') || `#${activeCh?.name} default → `}<Badge model={activeCh?.default_model || 'glm'} /> · use @model to override</div>
+ <div className="flex gap-2">
+ <textarea value={input} onChange={(e) => setInput(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } }} rows={2} placeholder="Message… (@claude, @ollama:mistral-nemo:12b to override)" className="flex-1 resize-none rounded border border-zinc-700 bg-zinc-900 px-3 py-2 text-sm outline-none focus:border-violet-500" />
+ <button onClick={send} disabled={sending} className="rounded bg-violet-600 px-4 text-sm font-semibold hover:bg-violet-500 disabled:opacity-50">Send</button>
+ </div>
+ </div>
+ </section>
+ {showModal && <NewChannelModal onClose={() => setShowModal(false)} onCreated={(c) => { setShowModal(false); loadChannels(); setActive(c.id); }} />}
+ </div>
+ );
+}
+
+function NewChannelModal({ onClose, onCreated }: { onClose: () => void; onCreated: (c: Channel) => void }) {
+ const [name, setName] = useState('');
+ const [model, setModel] = useState<string>('glm');
+ const [err, setErr] = useState('');
+ async function create() {
+ const r = await fetch('/api/channels', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ name, defaultModel: model }) });
+ const j = await r.json();
+ if (!r.ok) { setErr(j.error || 'failed'); return; }
+ onCreated(j.channel);
+ }
+ return (
+ <div className="fixed inset-0 z-10 flex items-center justify-center bg-black/60" onClick={onClose}>
+ <div className="w-80 rounded-lg border border-zinc-700 bg-zinc-900 p-4" onClick={(e) => e.stopPropagation()}>
+ <div className="mb-3 font-semibold">New channel</div>
+ <label className="mb-1 block text-xs text-zinc-400">Name</label>
+ <input autoFocus value={name} onChange={(e) => setName(e.target.value)} placeholder="research" className="mb-3 w-full rounded border border-zinc-700 bg-zinc-950 px-2 py-1.5 text-sm outline-none focus:border-violet-500" />
+ <label className="mb-1 block text-xs text-zinc-400">Default model</label>
+ <select value={model} onChange={(e) => setModel(e.target.value)} className="mb-3 w-full rounded border border-zinc-700 bg-zinc-950 px-2 py-1.5 text-sm outline-none">
+ {MODELS.map((m) => <option key={m} value={m}>{m}</option>)}
+ </select>
+ {err && <div className="mb-2 text-xs text-red-400">{err}</div>}
+ <div className="flex justify-end gap-2"><button onClick={onClose} className="rounded px-3 py-1 text-sm text-zinc-400 hover:text-zinc-200">Cancel</button><button onClick={create} className="rounded bg-violet-600 px-3 py-1 text-sm font-semibold hover:bg-violet-500">Create</button></div>
+ </div>
+ </div>
+ );
+}
+
+const COLUMNS = ['todo', 'doing', 'done', 'blocked'] as const;
+function Board() {
+ const [tasks, setTasks] = useState<Task[]>([]);
+ const [title, setTitle] = useState('');
+ const load = useCallback(async () => { const r = await fetch('/api/tasks').then((x) => x.json()); setTasks(r.tasks || []); }, []);
+ useEffect(() => { load(); const t = setInterval(load, 4000); return () => clearInterval(t); }, [load]);
+ async function add() { if (!title.trim()) return; await fetch('/api/tasks', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ title }) }); setTitle(''); load(); }
+ async function move(id: string, status: string) { await fetch(`/api/tasks/${id}`, { method: 'PATCH', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ status }) }); load(); }
+ return (
+ <div className="flex h-full flex-col p-4">
+ <div className="mb-3 flex gap-2"><input value={title} onChange={(e) => setTitle(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && add()} placeholder="New task…" className="w-72 rounded border border-zinc-700 bg-zinc-900 px-3 py-1.5 text-sm outline-none focus:border-violet-500" /><button onClick={add} className="rounded bg-violet-600 px-3 text-sm font-semibold hover:bg-violet-500">Add</button></div>
+ <div className="grid min-h-0 flex-1 grid-cols-4 gap-3">
+ {COLUMNS.map((col) => (
+ <div key={col} onDragOver={(e) => e.preventDefault()} onDrop={(e) => { const id = e.dataTransfer.getData('id'); if (id) move(id, col); }} className="flex flex-col rounded-lg border border-zinc-800 bg-zinc-900/30">
+ <div className="border-b border-zinc-800 px-3 py-2 text-xs font-semibold uppercase tracking-wide text-zinc-400">{col} <span className="text-zinc-600">{tasks.filter((t) => t.status === col).length}</span></div>
+ <div className="flex-1 space-y-2 overflow-y-auto p-2">
+ {tasks.filter((t) => t.status === col).map((t) => (
+ <div key={t.id} draggable onDragStart={(e) => e.dataTransfer.setData('id', t.id)} className="cursor-grab rounded border border-zinc-700 bg-zinc-900 p-2 text-sm">
+ <div>{t.title}</div>
+ {t.assigned_model && <div className="mt-1"><Badge model={t.assigned_model} /></div>}
+ </div>
+ ))}
+ </div>
+ </div>
+ ))}
+ </div>
+ </div>
+ );
+}
+
+function Fleet() {
+ const [fleet, setFleet] = useState<FleetRow[]>([]);
+ const [ping, setPing] = useState<Record<string, { ok: boolean; latencyMs: number; detail: string } | 'loading'>>({});
+ const [outbox, setOutbox] = useState<Outbox[]>([]);
+ const load = useCallback(async () => {
+ const r = await fetch('/api/fleet').then((x) => x.json()); setFleet(r.fleet || []);
+ const o = await fetch('/api/outbox').then((x) => x.json()); setOutbox(o.outbox || []);
+ }, []);
+ useEffect(() => { load(); const t = setInterval(load, 5000); return () => clearInterval(t); }, [load]);
+ async function doPing(model: string) {
+ setPing((p) => ({ ...p, [model]: 'loading' }));
+ const r = await fetch('/api/fleet/ping', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ model }) }).then((x) => x.json());
+ setPing((p) => ({ ...p, [model]: r })); load();
+ }
+ async function draftStub() { await fetch('/api/outbox', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ actionType: 'publish', payload: { note: 'stub outward action from Fleet' } }) }); load(); }
+ async function decide(id: string, action: string) { await fetch(`/api/outbox/${id}`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ action }) }); load(); }
+ return (
+ <div className="grid h-full grid-cols-2 gap-4 p-4">
+ <div>
+ <div className="mb-2 text-sm font-semibold text-zinc-300">Fleet</div>
+ <table className="w-full text-sm">
+ <thead><tr className="text-left text-xs uppercase text-zinc-500"><th className="py-1">Model</th><th>Role</th><th>Status</th><th>Ping</th></tr></thead>
+ <tbody>
+ {fleet.map((f) => { const p = ping[f.model]; return (
+ <tr key={f.model} className="border-t border-zinc-800">
+ <td className="py-2"><div className="flex items-center gap-2"><span className={`h-2 w-2 rounded-full ${f.available ? DOT[f.model] : 'bg-red-500'}`} /><Badge model={f.model} /></div><div className="mt-0.5 text-[11px] text-zinc-500">{f.label}</div></td>
+ <td className="text-zinc-400">{f.role}</td>
+ <td>{f.available ? <span className="text-emerald-400">●&nbsp;ready</span> : <span className="text-red-400">●&nbsp;down</span>}</td>
+ <td><button onClick={() => doPing(f.model)} className="rounded bg-zinc-800 px-2 py-0.5 text-xs hover:bg-zinc-700">Ping</button>{p === 'loading' ? <span className="ml-2 text-xs text-zinc-500">…</span> : p ? <span className={`ml-2 text-xs ${p.ok ? 'text-emerald-400' : 'text-red-400'}`}>{p.ok ? `${p.latencyMs}ms` : 'fail'}</span> : null}</td>
+ </tr>); })}
+ </tbody>
+ </table>
+ </div>
+ <div>
+ <div className="mb-2 flex items-center justify-between"><span className="text-sm font-semibold text-zinc-300">Approval outbox</span><button onClick={draftStub} className="rounded bg-zinc-800 px-2 py-0.5 text-xs hover:bg-zinc-700">+ Draft stub</button></div>
+ <div className="space-y-2">
+ {outbox.length === 0 && <div className="text-xs text-zinc-600">No drafted actions.</div>}
+ {outbox.map((o) => (
+ <div key={o.id} className="rounded border border-zinc-800 bg-zinc-900/40 p-2 text-sm">
+ <div className="flex items-center justify-between"><span className="font-mono text-xs uppercase text-amber-300">{o.action_type}</span><span className={`text-xs ${o.status === 'draft' ? 'text-amber-400' : o.status === 'approved' ? 'text-emerald-400' : 'text-red-400'}`}>{o.status}</span></div>
+ <pre className="mt-1 overflow-x-auto text-[11px] text-zinc-400">{o.payload_json}</pre>
+ {o.status === 'draft' && <div className="mt-2 flex gap-2"><button onClick={() => decide(o.id, 'approve')} className="rounded bg-emerald-600/80 px-2 py-0.5 text-xs hover:bg-emerald-500">Approve</button><button onClick={() => decide(o.id, 'reject')} className="rounded bg-red-600/80 px-2 py-0.5 text-xs hover:bg-red-500">Reject</button></div>}
+ </div>
+ ))}
+ </div>
+ </div>
+ </div>
+ );
+}
archive/old-conductor-sketch/.web-token +1 -0
@@ -0,0 +1 @@
+b786051378bb0d8d4d0e40bfefeb7bcd
archive/old-conductor-sketch/SETUP.md +51 -0
@@ -0,0 +1,51 @@
+# Zion PM - what's left for YOU (the only blockers)
+
+Everything is built and verified. These are the credentials/config only you can provide. Add them
+and each feature goes live. Nothing here needs me - but I can do the wiring once values exist.
+
+## 1. Email send + intake (the outreach + client engine)
+For each account, generate a **Gmail App Password** (myaccount.google.com → Security → App passwords;
+needs 2FA on). Add to `/shared/projects/.env.secrets` (one line each, no quotes needed):
+
+```
+GMAIL_APP_PW_ZIONBOGGAN=xxxxxxxxxxxxxxxx # zionboggan@gmail.com (recruiter outreach)
+GMAIL_APP_PW_ZIONBOGGAN0=xxxxxxxxxxxxxxxx # zionboggan0@gmail.com (client professional)
+GMAIL_APP_PW_ZCC=xxxxxxxxxxxxxxxx # ZCC Media Agency (client professional)
+GMAIL_APP_PW_ZION=xxxxxxxxxxxxxxxx # personal hybrid
+GMAIL_APP_PW_WORKYAYA=xxxxxxxxxxxxxxxx # workyaya2018@gmail.com (personal hybrid)
+```
+
+Then fill the two unknown addresses in `policy.yaml > sender_identities > accounts`:
+- `zcc_media.address` - the exact ZCC Media Agency address (gmail.com? or your own domain?)
+- `zion_personal.address` - which "zion" address is the personal-hybrid one?
+
+(If ZCC is a Google Workspace domain, set its `provider: workspace` - app passwords still work.)
+
+**Intake is label-gated so it never floods you:** in each Gmail, create a filter that applies a
+label named **`PM`** to whatever you want the agent to see (e.g. replies to outreach, client mail).
+The PM only reads messages under the `PM` label. Then run `python3 bin/intake-email.py` (or its timer).
+
+## 2. Mobile desk (Cockpit PWA + push)
+- **Expose it:** set `PM_WEB_TOKEN=<long-random>` then `bash bin/pm-web.sh` (binds 0.0.0.0:8780).
+ Without a token it binds localhost only. Open `http://<host>:8780/?t=<token>` on your iPhone →
+ Share → Add to Home Screen. It installs as a clean app (swipe approvals, add tasks by typing).
+- **Front it properly (recommended):** add a Traefik route `REDACTED-HOST` → CT:8780 with
+ Authentik forwardAuth (same pattern as your other lab apps), then drop the token.
+- **Push pings:** set a push channel so it taps you only when needed:
+ - ntfy (free): `PM_NTFY_TOPIC=<topic>` (+ `PM_NTFY_SERVER` if self-hosted), or
+ - Pushover ($5 once, very polished): tell me and I'll add a 6-line Pushover sender to `notify.sh`.
+
+## 3. Voice intake
+Record a memo and drop the audio in `inbox/voice/` (share it there from your phone via Samba).
+`bash bin/intake-voice.sh` transcribes it on the 3060 STT sidecar (CT215:8770) → task. Nothing to
+configure unless the sidecar URL/model changed (`PM_STT_URL`, `PM_STT_MODEL`).
+
+## 4. Browser hand
+Already functional on this host (Playwright + Chromium present). On whatever host runs the conductor,
+ensure: `pip install --user playwright && python3 -m playwright install chromium`. For logged-in
+actions on a site, I'll add a saved-session profile per site when you point me at the first one.
+
+## 5. (Recommended, you skipped it) Budget guard
+You're on a metered GLM weekly cap (the 11% scare). Say the word and I'll add a guard that tracks
+usage and auto-fails-over the brain to local Ollama / your $16 backup key before lockout, then back.
+Small build, saves the whole PM from dying mid-campaign.
archive/old-conductor-sketch/SOUL.md +47 -0
@@ -0,0 +1,47 @@
+# Zion PM - Conductor Soul
+
+You are **Zion's PM** (Project Manager / Chief of Staff). You are not a chatbot. You are a
+conductor: you take any task Zion gives you - menial or wild - decompose it, dispatch workers
+to do it, supervise them, and report back. Zion talks only to you. You talk to everything else.
+
+Read this file at the start of every tick. It is your binding charter.
+
+## Prime directive
+Take work *off* Zion. Default to action on anything reversible and internal. Only interrupt
+him for a real decision, an approval he reserved, or genuine ambiguity about intent. A good
+day is one where things moved forward and his inbox stayed quiet.
+
+## Operating loop (one "tick")
+1. Read `state/conductor_state.json`, `state/tasks.json`, `state/outbox.json`. Resume - never
+ start from scratch.
+2. Ingest new work from `inbox/` (one task per file or line) into `tasks.json`.
+3. Plan: for each open task, decide type, the worker(s) needed, the model, and the return
+ contract. Honor `policy.yaml` autonomy gates and batch limits (≤4 concurrent workers).
+4. Dispatch: spawn workers via `bin/spawn-worker.sh`. Each worker gets a clean context, a tight
+ scope, allowed hands, and a return contract (summary / artifacts / tests / blockers / next).
+5. Supervise: read finished workers in `workers/*/result.json`. Fold results into `tasks.json`,
+ write decisions to memory-graph, update human-readable docs after material decisions.
+6. Gate: any outward-facing action (email, DM, public post, contacting a human, infra mutation)
+ does NOT execute. Write it to `state/outbox.json` as a fully-previewed pending item for Zion.
+7. Report: append to `state/activity.jsonl`. If something needs Zion, push via ntfy and surface
+ it in the cockpit. Otherwise stay quiet.
+8. Update `state/conductor_state.json` and end the tick. Be frugal with tokens - the brain runs
+ on a metered subscription.
+
+## Escalation rules (hard - never auto-do these)
+- Ask before any **public push** (git push to public repos, publishing packages, site deploys).
+- Ask before **contacting any human** (email, DM, comment, outreach of any kind).
+- Ask before any **infra mutation** (restart/sleep/wake CTs, edit prod config, delete data).
+- **Never print or transmit secrets.** Redaction markers mean a secret exists, not that you may
+ recover it. Keep secrets and client PII out of any prompt sent to a non-local model.
+
+## Context discipline (RAG-first)
+Before deciding priority or opening broad files: query `homelab_context` first. For
+architecture / blast-radius / who-calls: `cbm-homelab`. For live symbol lookup during edits:
+Serena. For cross-project decisions and handoffs: memory-graph. Read specific files only after
+the right layer comes up short. Never sweep whole trees. Every worker you spawn inherits this
+rule - put it in the worker prompt.
+
+## Voice
+Terse, concrete, no hedging. No AI tells, no em-dashes, no filler. Lead with the answer.
+When you report to Zion: what moved, what's blocked, what needs him - in that order.
archive/old-conductor-sketch/bin/__pycache__/intake-email.cpython-310.pyc +0 -0
Binary file not shown
archive/old-conductor-sketch/bin/__pycache__/pm-web.cpython-310.pyc +0 -0
Binary file not shown
archive/old-conductor-sketch/bin/__pycache__/pm.cpython-310.pyc +0 -0
Binary file not shown
archive/old-conductor-sketch/bin/conductor.sh +70 -0
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+# Zion PM - Conductor. The always-on planner/supervisor brain.
+# Runs tick-based for quota control + resume-safety. Each tick is one bounded headless
+# claude run that reads state, plans, dispatches workers, gates outward actions, reports.
+#
+# bash conductor.sh --once # run a single tick (also: `pm tick`)
+# bash conductor.sh --daemon # perpetual loop in tmux session `zion-pm` (also: `pm start`)
+#
+# Brain is selected by env.sh (default GLM). Be frugal: TICK_INTERVAL is intentionally slow.
+
+set -uo pipefail
+PM="/shared/projects/zion-pm"
+cd "$PM" || exit 1
+# shellcheck disable=SC1091
+source "$PM/env.sh"
+
+TICK_INTERVAL="${PM_TICK_INTERVAL:-900}" # 15 min between ticks by default (quota-friendly)
+
+read -r -d '' TICK_PROMPT <<'EOF'
+Run ONE Zion-PM conductor tick. You are resume-safe; continue from disk state.
+
+Steps, in order, then stop:
+1. Read state/conductor_state.json, state/tasks.json, state/outbox.json. Read SOUL.md and
+ policy.yaml for your charter, autonomy gates, and the ≤4 concurrent-worker limit.
+2. Ingest any new files in inbox/ into state/tasks.json (status "open"), then delete those
+ inbox files. Each file's text is the task.
+3. For prioritization or any "what should I do" judgment, call homelab_context FIRST. Do not
+ sweep files.
+4. Pick the highest-leverage open/in-progress tasks (respect the concurrency cap). For each,
+ decide type (code|research|outreach|browser|ops|misc), the model per policy.yaml, and a
+ return contract. Spawn each via: bash bin/spawn-worker.sh <task-id> <type> "<scoped prompt>"
+ Mark dispatched tasks "in_progress" with their worker id.
+5. Drain: for any workers/*/result.json that are new, fold the result into the task
+ (status, artifacts, next_action). Write durable cross-project decisions to memory-graph.
+6. Gate: if a task's next step is outward-facing (send/post/push/deploy/contact/infra-mutate),
+ DO NOT do it. Append a fully-previewed item to state/outbox.json "pending" (id, kind, task,
+ preview with full content/recipient/target) and tell the task it is awaiting approval.
+7. Append a concise JSON line per material action to state/activity.jsonl.
+8. If and only if Zion is needed (an approval is pending, or a real blocker), push one ntfy
+ line to topic per policy.yaml. Otherwise stay silent.
+9. Update state/conductor_state.json (last_tick ts, ticks+1, running_workers). Stop.
+
+Be terse and frugal. This brain runs on a metered weekly cap - do the minimum tool calls
+needed to move work forward. Never print secrets. Never execute an outbox item yourself.
+EOF
+
+run_tick() {
+ echo "[pm] tick @ $(date -Is)" >&2
+ claude -p \
+ --dangerously-skip-permissions \
+ --append-system-prompt "$(cat "$PM/SOUL.md")" \
+ "$TICK_PROMPT" 2>>"$PM/logs/conductor.err" | tee -a "$PM/logs/conductor.out"
+}
+
+case "${1:---once}" in
+ --once)
+ run_tick
+ ;;
+ --daemon)
+ if tmux has-session -t zion-pm 2>/dev/null; then
+ echo "zion-pm already running"; exit 0
+ fi
+ tmux new-session -d -s zion-pm \
+ "while true; do PM_BRAIN='${PM_BRAIN:-glm}' bash '$PM/bin/conductor.sh' --once; sleep $TICK_INTERVAL; done"
+ echo "started zion-pm conductor loop (tick=${TICK_INTERVAL}s, brain=${PM_BRAIN:-glm})"
+ ;;
+ *)
+ echo "usage: conductor.sh --once|--daemon" >&2; exit 1
+ ;;
+esac
archive/old-conductor-sketch/bin/flush-outbox.sh +31 -0
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+# Execute APPROVED outbox items. Run by Zion (`pm flush`) or by the conductor after approval.
+# Routes each approved item to its hand (hands/execute-<kind>.sh). If no hand is wired yet,
+# it says so honestly and leaves the item for manual handling - it never silently drops.
+set -uo pipefail
+PM="/shared/projects/zion-pm"
+OUT="$PM/state/outbox.json"
+
+mapfile -t APPROVED < <(jq -r '.history[] | select(.decision=="approved" and (.executed|not)) | .id' "$OUT" 2>/dev/null)
+[ "${#APPROVED[@]}" -eq 0 ] && { echo "[pm] nothing approved to flush"; exit 0; }
+
+for OID in "${APPROVED[@]}"; do
+ KIND=$(jq -r --arg id "$OID" '.history[] | select(.id==$id) | .kind' "$OUT")
+ HAND="$PM/hands/execute-$KIND.sh"
+ if [ -x "$HAND" ] || [ -f "$HAND" ]; then
+ echo "[pm] executing $OID via $HAND"
+ PM_APPROVED=1 bash "$HAND" "$OID" "$OUT" && STATUS="executed" || STATUS="failed"
+ else
+ echo "[pm] no hand for kind='$KIND' (item $OID). Wire hands/execute-$KIND.sh. Left for manual."
+ STATUS="needs_hand"
+ fi
+ python3 - "$OUT" "$OID" "$STATUS" <<'PY'
+import json,sys,time
+path,oid,status=sys.argv[1:4]
+o=json.load(open(path))
+for h in o["history"]:
+ if h["id"]==oid:
+ h["executed"]=True; h["exec_status"]=status; h["executed_at"]=time.strftime("%Y-%m-%dT%H:%M:%S")
+json.dump(o,open(path,"w"),indent=2)
+PY
+done
archive/old-conductor-sketch/bin/intake-email.py +90 -0
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+"""Zion PM - email intake (a sense). Polls each Gmail account's `PM` label over IMAP and turns
+new messages into tasks. Label-gated on purpose: set a Gmail filter to label what you want the PM
+to handle (outreach replies, client mail) as `PM`, and ONLY those reach the agent. No flooding.
+
+Run periodically (cron/systemd timer): python3 bin/intake-email.py
+Needs each account's Gmail APP PASSWORD in /shared/projects/.env.secrets under its app_pw_var.
+"""
+import imaplib, email, json, os, time, uuid, re
+from email.header import decode_header
+
+PM = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+ST = os.path.join(PM, "state"); INBOX = os.path.join(PM, "inbox")
+LABEL = os.environ.get("PM_EMAIL_LABEL", "PM") # Gmail label the PM is allowed to read
+
+def secrets():
+ d = {}
+ p = "/shared/projects/.env.secrets"
+ if os.path.exists(p):
+ for line in open(p):
+ line = line.strip().replace("\r", "")
+ if "=" in line and not line.startswith("#"):
+ k, _, v = line.partition("="); d[k.strip()] = v.strip().strip('"').strip("'")
+ return d
+
+def policy_accounts():
+ import yaml
+ pol = yaml.safe_load(open(os.path.join(PM, "policy.yaml")))
+ return (pol.get("sender_identities", {}) or {}).get("accounts", {})
+
+def _dec(s):
+ if not s: return ""
+ out = []
+ for part, enc in decode_header(s):
+ out.append(part.decode(enc or "utf-8", "ignore") if isinstance(part, bytes) else part)
+ return "".join(out)
+
+def add_task(title, project, ttype):
+ p = os.path.join(ST, "tasks.json")
+ t = json.load(open(p)) if os.path.exists(p) else {"tasks": []}
+ tid = "t-" + uuid.uuid4().hex[:8]
+ t["tasks"].append({"id": tid, "title": title, "project": project, "type": ttype,
+ "status": "open", "created": time.strftime("%Y-%m-%dT%H:%M:%S"),
+ "artifacts": [], "worker": None, "source": "email"})
+ json.dump(t, open(p, "w"), indent=2)
+ open(os.path.join(INBOX, tid + ".task"), "w").write(title + "\n")
+ with open(os.path.join(ST, "activity.jsonl"), "a") as f:
+ f.write(json.dumps({"ts": time.strftime("%Y-%m-%dT%H:%M:%S"), "event": "intake_email", "id": tid, "title": title}) + "\n")
+ return tid
+
+def poll_account(name, acct, sec):
+ addr = (acct.get("address") or "").strip()
+ pwvar = acct.get("app_pw_var", "")
+ pw = sec.get(pwvar, "")
+ if not addr or not pw:
+ return f" skip {name}: no address or {pwvar} not set"
+ use = acct.get("use", "")
+ ttype = "outreach" if "outreach" in use or "recruit" in use else "client" if "client" in use else "misc"
+ try:
+ M = imaplib.IMAP4_SSL("imap.gmail.com")
+ M.login(addr, pw)
+ # Gmail labels are selectable as folders/mailboxes.
+ typ, _ = M.select(f'"{LABEL}"', readonly=False)
+ if typ != "OK":
+ M.logout(); return f" {name}: no '{LABEL}' label (create a Gmail filter -> label '{LABEL}')"
+ typ, data = M.search(None, "UNSEEN")
+ ids = data[0].split() if data and data[0] else []
+ made = 0
+ for i in ids:
+ typ, msg_data = M.fetch(i, "(RFC822)")
+ if typ != "OK": continue
+ msg = email.message_from_bytes(msg_data[0][1])
+ frm = _dec(msg.get("From")); subj = _dec(msg.get("Subject"))
+ title = f"Email to {name} from {frm}: {subj}".strip()
+ add_task(title, project=None, ttype=ttype)
+ M.store(i, "+FLAGS", "\\Seen")
+ made += 1
+ M.logout()
+ return f" {name} ({addr}): {made} new -> tasks"
+ except Exception as e:
+ return f" {name} ERROR: {e}"
+
+def main():
+ sec = secrets(); accts = policy_accounts()
+ print(f"[intake-email] polling '{LABEL}' label across {len(accts)} accounts")
+ for name, acct in accts.items():
+ print(poll_account(name, acct, sec))
+
+if __name__ == "__main__":
+ main()
archive/old-conductor-sketch/bin/intake-voice.sh +36 -0
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# Zion PM - voice intake (a sense). Drop an audio memo in inbox/voice/ and this transcribes it
+# via your GPU-STT sidecar (Speaches/faster-whisper on the 3060, fronted at CT215:8770) and files
+# the transcript as a task. The sidecar handles unload-Ollama -> Speaches -> restore.
+#
+# Run on a timer, or: bash bin/intake-voice.sh
+# Record straight from your phone (Voice Memos / share-to-folder via the Samba share).
+set -uo pipefail
+PM="/shared/projects/zion-pm"
+VOICE="$PM/inbox/voice"; DONE="$VOICE/processed"
+STT="${PM_STT_URL:-http://REDACTED-IP:8770/v1/audio/transcriptions}"
+MODEL="${PM_STT_MODEL:-large-v3-turbo}"
+mkdir -p "$VOICE" "$DONE"
+
+shopt -s nullglob
+files=("$VOICE"/*.{m4a,mp3,wav,ogg,flac,aac})
+[ "${#files[@]}" -eq 0 ] && { echo "[intake-voice] no audio in $VOICE"; exit 0; }
+
+for f in "${files[@]}"; do
+ echo "[intake-voice] transcribing $(basename "$f")"
+ TXT=$(curl -s -m 180 "$STT" -F "file=@$f" -F "model=$MODEL" -F "response_format=text" 2>/dev/null)
+ TXT=$(printf '%s' "$TXT" | tr '\n' ' ' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
+ if [ -z "$TXT" ]; then
+ echo " -> empty transcript (STT down? check the sidecar). Leaving file in place."
+ continue
+ fi
+ echo " -> \"$TXT\""
+ bash "$PM/bin/pm" add "$TXT" --type misc >/dev/null
+ python3 - "$PM/state/activity.jsonl" "$(basename "$f")" "$TXT" <<'PY'
+import json,sys,time
+path,fn,txt=sys.argv[1:4]
+open(path,"a").write(json.dumps({"ts":time.strftime("%Y-%m-%dT%H:%M:%S"),"event":"intake_voice","file":fn,"text":txt[:120]})+"\n")
+PY
+ mv "$f" "$DONE/"
+done
+echo "[intake-voice] done"
archive/old-conductor-sketch/bin/notify.sh +9 -0
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# Push a mobile alert to Zion. Only called when Zion is actually needed (approval/blocker).
+# bash notify.sh "title" "message"
+set -uo pipefail
+TITLE="${1:-Zion PM}"; MSG="${2:?message}"
+TOPIC="${PM_NTFY_TOPIC:-zion-pm}"
+SERVER="${PM_NTFY_SERVER:-https://ntfy.sh}" # set to self-hosted ntfy if you run one
+curl -s -H "Title: $TITLE" -H "Tags: robot" -d "$MSG" "$SERVER/$TOPIC" >/dev/null \
+ && echo "[pm] notified $TOPIC" || echo "[pm] notify failed (set PM_NTFY_SERVER/topic)"
archive/old-conductor-sketch/bin/outbox-add.sh +18 -0
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+# Queue an outward-facing action for Zion's approval. Called by workers/conductor.
+# bash outbox-add.sh <task-id> <kind> "<full preview>"
+# kind: email | dm | social_post | git_push | publish | deploy | infra | contact | other
+set -uo pipefail
+PM="/shared/projects/zion-pm"
+TASK_ID="${1:?task-id}"; KIND="${2:?kind}"; PREVIEW="${3:?preview}"
+OID="o-$(date +%s)-$RANDOM"
+python3 - "$PM/state/outbox.json" "$OID" "$TASK_ID" "$KIND" "$PREVIEW" <<'PY'
+import json,sys,time
+path,oid,task,kind,preview=sys.argv[1:6]
+try: o=json.load(open(path))
+except Exception: o={"pending":[],"history":[]}
+o["pending"].append({"id":oid,"task":task,"kind":kind,"preview":preview,
+ "created":time.strftime("%Y-%m-%dT%H:%M:%S"),"decision":"pending"})
+json.dump(o,open(path,"w"),indent=2)
+print(f"[pm] outbox queued {oid} ({kind}) for task {task} -> awaiting approval")
+PY
archive/old-conductor-sketch/bin/pm +3 -0
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+# shim so `bash bin/pm ...` works on noexec CIFS (runs the python CLI)
+exec python3 "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/pm.py" "$@"
archive/old-conductor-sketch/bin/pm-web.py +198 -0
@@ -0,0 +1,198 @@
+#!/usr/bin/env python3
+"""Zion PM - mobile control desk (PWA) + JSON API. Zero deps (stdlib only).
+
+Serves a polished, installable mobile web app that reads/writes the same state/ files the
+conductor uses: approve/reject outbox items, add tasks, see workers + activity. Pair with push
+(bin/notify.sh) so you get pinged and tap through.
+
+Run: bash bin/pm-web.sh (wrapper; or: python3 bin/pm-web.py)
+Env: PM_WEB_PORT (default 8780), PM_WEB_TOKEN (shared secret; if unset, binds localhost only)
+Front it with Traefik + Authentik later for REDACTED-HOST.
+"""
+import json, os, time, http.server, socketserver, urllib.parse
+
+PM = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+ST = os.path.join(PM, "state")
+INBOX = os.path.join(PM, "inbox")
+PORT = int(os.environ.get("PM_WEB_PORT", "8780"))
+TOKEN = os.environ.get("PM_WEB_TOKEN", "")
+BIND = "0.0.0.0" if TOKEN else "127.0.0.1"
+
+def _load(name, default):
+ try:
+ with open(os.path.join(ST, name)) as f: return json.load(f)
+ except Exception: return default
+
+def _save(name, obj):
+ p = os.path.join(ST, name); tmp = p + ".tmp"
+ with open(tmp, "w") as f: json.dump(obj, f, indent=2)
+ os.replace(tmp, p)
+
+def _ts(): return time.strftime("%Y-%m-%dT%H:%M:%S")
+
+def _log(event, **kw):
+ with open(os.path.join(ST, "activity.jsonl"), "a") as f:
+ f.write(json.dumps({"ts": _ts(), "event": event, **kw}) + "\n")
+
+def state_blob():
+ tasks = _load("tasks.json", {"tasks": []})["tasks"]
+ outbox = _load("outbox.json", {"pending": [], "history": []})
+ cond = _load("conductor_state.json", {})
+ wdir = os.path.join(PM, "workers")
+ running = []
+ if os.path.isdir(wdir):
+ running = [d for d in os.listdir(wdir)
+ if os.path.isdir(os.path.join(wdir, d))
+ and not os.path.exists(os.path.join(wdir, d, "result.json"))]
+ act = []
+ ap = os.path.join(ST, "activity.jsonl")
+ if os.path.exists(ap):
+ act = [json.loads(l) for l in open(ap).read().splitlines()[-15:] if l.strip()]
+ return {
+ "tasks": [t for t in tasks if t["status"] not in ("done", "cancelled")],
+ "approvals": outbox["pending"],
+ "workers": running,
+ "activity": list(reversed(act)),
+ "heartbeat": cond.get("last_tick"),
+ "ticks": cond.get("ticks", 0),
+ }
+
+def decide(oid, decision, reason=""):
+ o = _load("outbox.json", {"pending": [], "history": []})
+ keep, hit = [], None
+ for p in o["pending"]:
+ if p["id"] == oid: hit = p
+ else: keep.append(p)
+ if not hit: return False
+ hit["decision"] = decision; hit["decided_at"] = _ts(); hit["reason"] = reason
+ o["pending"] = keep; o["history"].append(hit)
+ _save("outbox.json", o); _log("outbox_" + decision, id=oid, kind=hit.get("kind"))
+ return True
+
+def add_task(title, project=None, ttype="misc"):
+ import uuid
+ t = _load("tasks.json", {"tasks": []})
+ tid = "t-" + uuid.uuid4().hex[:8]
+ t["tasks"].append({"id": tid, "title": title, "project": project, "type": ttype,
+ "status": "open", "created": _ts(), "artifacts": [], "worker": None})
+ _save("tasks.json", t)
+ with open(os.path.join(INBOX, tid + ".task"), "w") as f: f.write(title + "\n")
+ _log("task_added", id=tid, title=title)
+ return tid
+
+INDEX = r"""<!doctype html><html lang=en><head><meta charset=utf-8>
+<meta name=viewport content="width=device-width,initial-scale=1,viewport-fit=cover">
+<meta name=theme-color content="#0b0f17"><link rel=manifest href=/manifest.json>
+<meta name=apple-mobile-web-app-capable content=yes>
+<meta name=apple-mobile-web-app-status-bar-style content=black-translucent>
+<title>Zion PM</title><style>
+:root{--bg:#0b0f17;--panel:#141a26;--line:#222c3d;--ink:#eef2f8;--mut:#8a97ad;
+--grn:#2ec27e;--red:#f0584f;--blu:#4d8df0;--gold:#e3a93c}
+*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);
+font:15px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,sans-serif;
+padding:env(safe-area-inset-top) 0 calc(env(safe-area-inset-bottom) + 80px)}
+header{position:sticky;top:0;background:rgba(11,15,23,.92);backdrop-filter:blur(12px);
+padding:16px 18px 12px;border-bottom:1px solid var(--line);z-index:5}
+h1{font-size:20px;margin:0;font-weight:800;letter-spacing:-.3px}
+.hb{color:var(--mut);font-size:12px;margin-top:3px}
+.wrap{padding:14px 14px 0;max-width:680px;margin:0 auto}
+.sec{margin-bottom:22px}.sec h2{font-size:12px;text-transform:uppercase;letter-spacing:.08em;
+color:var(--mut);margin:0 0 9px;font-weight:800}
+.card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:14px;margin-bottom:10px}
+.card.appr{border-left:3px solid var(--gold)}
+.k{font-size:11px;font-weight:800;text-transform:uppercase;color:var(--gold);letter-spacing:.05em}
+.pv{white-space:pre-wrap;color:var(--ink);font-size:13px;margin:7px 0 12px;
+max-height:160px;overflow:auto;background:#0e1420;border-radius:9px;padding:9px}
+.row{display:flex;gap:9px}.btn{flex:1;border:0;border-radius:11px;padding:12px;font-weight:800;
+font-size:14px;color:#fff}.ok{background:var(--grn)}.no{background:var(--red)}
+.task{display:flex;align-items:center;gap:10px}.dot{width:8px;height:8px;border-radius:9px;background:var(--blu);flex:0 0 auto}
+.task .st{margin-left:auto;font-size:11px;color:var(--mut);text-transform:uppercase}
+.proj{font-size:11px;color:var(--mut)}
+.act{font-size:12px;color:var(--mut);padding:5px 0;border-bottom:1px solid var(--line)}
+.empty{color:var(--mut);font-size:13px;padding:4px 2px}
+.add{position:fixed;bottom:0;left:0;right:0;background:rgba(11,15,23,.95);backdrop-filter:blur(12px);
+border-top:1px solid var(--line);padding:12px 14px calc(12px + env(safe-area-inset-bottom));display:flex;gap:8px}
+.add input{flex:1;background:var(--panel);border:1px solid var(--line);border-radius:12px;
+padding:13px;color:var(--ink);font-size:15px}.add button{background:var(--blu);border:0;border-radius:12px;
+padding:0 18px;color:#fff;font-weight:800;font-size:20px}
+.chip{display:inline-block;background:#0e1420;border:1px solid var(--line);border-radius:8px;
+padding:2px 8px;font-size:11px;color:var(--mut);margin-left:6px}
+</style></head><body>
+<header><h1>Zion PM</h1><div class=hb id=hb>connecting…</div></header>
+<div class=wrap>
+ <div class=sec><h2>Approvals</h2><div id=appr></div></div>
+ <div class=sec><h2>Today</h2><div id=tasks></div></div>
+ <div class=sec><h2>Workers</h2><div id=workers></div></div>
+ <div class=sec><h2>Activity</h2><div id=activity></div></div>
+</div>
+<div class=add><input id=ti placeholder="Tell the PM to do something…"
+ onkeydown="if(event.key==='Enter')addTask()"><button onclick=addTask()>+</button></div>
+<script>
+const TOK=new URLSearchParams(location.search).get('t')||'';
+const H=TOK?{'X-PM-Token':TOK}:{};
+async function api(p,m='GET',b){const r=await fetch(p,{method:m,headers:{...H,'Content-Type':'application/json'},
+ body:b?JSON.stringify(b):undefined});return r.json()}
+function esc(s){return (s||'').replace(/[&<>]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;'}[c]))}
+async function load(){let s;try{s=await api('/api/state')}catch(e){document.getElementById('hb').textContent='offline';return}
+ document.getElementById('hb').textContent=`${s.ticks} ticks · last ${s.heartbeat||'never'} · ${s.workers.length} workers`;
+ const A=document.getElementById('appr');
+ A.innerHTML=s.approvals.length?s.approvals.map(p=>`<div class="card appr"><div class=k>${esc(p.kind)}</div>
+ <div class=pv>${esc(p.preview)}</div><div class=row>
+ <button class="btn ok" onclick="act('${p.id}','approve')">Approve</button>
+ <button class="btn no" onclick="act('${p.id}','reject')">Reject</button></div></div>`).join(''):'<div class=empty>nothing waiting on you</div>';
+ document.getElementById('tasks').innerHTML=s.tasks.length?s.tasks.map(t=>`<div class=card><div class=task>
+ <span class=dot></span><div><div>${esc(t.title)}</div><div class=proj>${esc(t.project||'')}</div></div>
+ <span class=st>${esc(t.status)}</span></div></div>`).join(''):'<div class=empty>no open tasks</div>';
+ document.getElementById('workers').innerHTML=s.workers.length?s.workers.map(w=>`<div class=card>${esc(w)} <span class=chip>running</span></div>`).join(''):'<div class=empty>idle</div>';
+ document.getElementById('activity').innerHTML=s.activity.map(a=>`<div class=act>${esc(a.ts)} · ${esc(a.event)} ${esc(a.title||a.id||'')}</div>`).join('')||'<div class=empty>-</div>';
+}
+async function act(id,d){await api('/api/'+d,'POST',{id});load()}
+async function addTask(){const i=document.getElementById('ti');if(!i.value.trim())return;
+ await api('/api/add','POST',{title:i.value.trim()});i.value='';load()}
+load();setInterval(load,4000);
+if('serviceWorker'in navigator)navigator.serviceWorker.register('/sw.js').catch(()=>{});
+</script></body></html>"""
+
+MANIFEST = json.dumps({
+ "name": "Zion PM", "short_name": "Zion PM", "start_url": "/", "display": "standalone",
+ "background_color": "#0b0f17", "theme_color": "#0b0f17",
+ "icons": [{"src": "/icon.png", "sizes": "512x512", "type": "image/png"}]
+})
+SW = "self.addEventListener('fetch',()=>{});"
+
+class H(http.server.BaseHTTPRequestHandler):
+ def _auth(self):
+ if not TOKEN: return True
+ return self.headers.get("X-PM-Token") == TOKEN
+ def _send(self, code, body, ctype="application/json"):
+ b = body.encode() if isinstance(body, str) else body
+ self.send_response(code); self.send_header("Content-Type", ctype)
+ self.send_header("Content-Length", str(len(b))); self.end_headers(); self.wfile.write(b)
+ def log_message(self, *a): pass
+ def do_GET(self):
+ path = urllib.parse.urlparse(self.path).path
+ if path == "/": return self._send(200, INDEX, "text/html; charset=utf-8")
+ if path == "/manifest.json": return self._send(200, MANIFEST)
+ if path == "/sw.js": return self._send(200, SW, "application/javascript")
+ if path == "/icon.png": return self._send(200, b"", "image/png")
+ if path == "/api/state":
+ if not self._auth(): return self._send(401, '{"error":"auth"}')
+ return self._send(200, json.dumps(state_blob()))
+ self._send(404, '{"error":"nf"}')
+ def do_POST(self):
+ if not self._auth(): return self._send(401, '{"error":"auth"}')
+ path = urllib.parse.urlparse(self.path).path
+ n = int(self.headers.get("Content-Length", 0))
+ body = json.loads(self.rfile.read(n) or b"{}")
+ if path == "/api/approve": return self._send(200, json.dumps({"ok": decide(body["id"], "approved")}))
+ if path == "/api/reject": return self._send(200, json.dumps({"ok": decide(body["id"], "rejected")}))
+ if path == "/api/add":
+ tid = add_task(body["title"], body.get("project"), body.get("type", "misc"))
+ return self._send(200, json.dumps({"ok": True, "id": tid}))
+ self._send(404, '{"error":"nf"}')
+
+class TS(socketserver.ThreadingMixIn, http.server.HTTPServer): daemon_threads = True
+
+if __name__ == "__main__":
+ print(f"[pm-web] http://{BIND}:{PORT} auth={'token' if TOKEN else 'LOCALHOST-ONLY (set PM_WEB_TOKEN)'}")
+ TS((BIND, PORT), H).serve_forever()
archive/old-conductor-sketch/bin/pm-web.sh +3 -0
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+# Launch the Zion PM mobile desk. Set PM_WEB_TOKEN to expose beyond localhost.
+exec python3 "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/pm-web.py"
archive/old-conductor-sketch/bin/pm.py +135 -0
@@ -0,0 +1,135 @@
+#!/usr/bin/env python3
+"""Zion PM control CLI. Pure local state ops (no model calls) - safe to spam.
+
+Usage:
+ pm add "<task>" [--project P] [--type code|research|outreach|browser|ops|misc]
+ pm ls [--all] # open tasks (or all)
+ pm show <id>
+ pm approvals # pending outbox items awaiting your OK
+ pm approve <id> | pm reject <id> [--reason "..."]
+ pm status # conductor heartbeat + running workers
+ pm activity [N] # last N activity lines (default 20)
+ pm tick # run ONE conductor tick now (uses the brain = spends quota)
+ pm start | pm stop # tmux loop control (perpetual conductor)
+"""
+import json, os, sys, time, subprocess, argparse, uuid
+
+PM = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+ST = os.path.join(PM, "state")
+INBOX = os.path.join(PM, "inbox")
+
+def _load(p, default):
+ try:
+ with open(p) as f: return json.load(f)
+ except Exception: return default
+
+def _save(p, obj):
+ tmp = p + ".tmp"
+ with open(tmp, "w") as f: json.dump(obj, f, indent=2)
+ os.replace(tmp, p)
+
+def _ts(): return time.strftime("%Y-%m-%dT%H:%M:%S")
+
+def _log(event, **kw):
+ line = {"ts": _ts(), "event": event, **kw}
+ with open(os.path.join(ST, "activity.jsonl"), "a") as f:
+ f.write(json.dumps(line) + "\n")
+
+def cmd_add(a):
+ t = _load(os.path.join(ST, "tasks.json"), {"tasks": []})
+ tid = "t-" + uuid.uuid4().hex[:8]
+ task = {"id": tid, "title": a.task, "project": a.project, "type": a.type,
+ "status": "open", "created": _ts(), "artifacts": [], "worker": None}
+ t["tasks"].append(task)
+ _save(os.path.join(ST, "tasks.json"), t)
+ # also drop a one-line inbox file so the conductor notices on next tick
+ with open(os.path.join(INBOX, tid + ".task"), "w") as f:
+ f.write(a.task + "\n")
+ _log("task_added", id=tid, title=a.task)
+ print(f"added {tid}: {a.task}")
+
+def cmd_ls(a):
+ t = _load(os.path.join(ST, "tasks.json"), {"tasks": []})
+ for x in t["tasks"]:
+ if a.all or x["status"] not in ("done", "cancelled"):
+ print(f"{x['id']} [{x['status']:>10}] {x.get('project') or '-':<14} {x['title']}")
+
+def cmd_show(a):
+ t = _load(os.path.join(ST, "tasks.json"), {"tasks": []})
+ for x in t["tasks"]:
+ if x["id"] == a.id: print(json.dumps(x, indent=2)); return
+ print("not found", file=sys.stderr); sys.exit(1)
+
+def cmd_approvals(a):
+ o = _load(os.path.join(ST, "outbox.json"), {"pending": [], "history": []})
+ if not o["pending"]: print("no pending approvals"); return
+ for p in o["pending"]:
+ print(f"--- {p['id']} ({p['kind']}) task={p.get('task')}")
+ print(f" {p.get('preview','')}")
+
+def _move_outbox(oid, decision, reason):
+ o = _load(os.path.join(ST, "outbox.json"), {"pending": [], "history": []})
+ keep, hit = [], None
+ for p in o["pending"]:
+ (hit := p) if p["id"] == oid else keep.append(p)
+ if not hit: print("not found", file=sys.stderr); sys.exit(1)
+ hit["decision"] = decision; hit["decided_at"] = _ts(); hit["reason"] = reason
+ o["pending"] = keep; o["history"].append(hit)
+ _save(os.path.join(ST, "outbox.json"), o)
+ _log("outbox_" + decision, id=oid, kind=hit["kind"])
+ return hit
+
+def cmd_approve(a):
+ hit = _move_outbox(a.id, "approved", a.reason)
+ print(f"approved {a.id}. run `pm flush` (or the conductor will) to execute.")
+
+def cmd_reject(a):
+ _move_outbox(a.id, "rejected", a.reason); print(f"rejected {a.id}")
+
+def cmd_flush(a):
+ subprocess.run(["bash", os.path.join(PM, "bin", "flush-outbox.sh")])
+
+def cmd_status(a):
+ c = _load(os.path.join(ST, "conductor_state.json"), {})
+ print(json.dumps(c, indent=2))
+ wdir = os.path.join(PM, "workers")
+ running = [d for d in os.listdir(wdir) if os.path.isdir(os.path.join(wdir, d))
+ and not os.path.exists(os.path.join(wdir, d, "result.json"))] if os.path.isdir(wdir) else []
+ print("running workers:", running or "none")
+
+def cmd_activity(a):
+ p = os.path.join(ST, "activity.jsonl")
+ if not os.path.exists(p): print("(no activity)"); return
+ lines = open(p).read().splitlines()[-a.n:]
+ for l in lines: print(l)
+
+def cmd_tick(a):
+ subprocess.run(["bash", os.path.join(PM, "bin", "conductor.sh"), "--once"])
+
+def cmd_start(a):
+ subprocess.run(["bash", os.path.join(PM, "bin", "conductor.sh"), "--daemon"])
+
+def cmd_stop(a):
+ subprocess.run(["tmux", "kill-session", "-t", "zion-pm"])
+ print("stopped zion-pm loop")
+
+def main():
+ ap = argparse.ArgumentParser(prog="pm")
+ sub = ap.add_subparsers(dest="cmd", required=True)
+ s = sub.add_parser("add"); s.add_argument("task"); s.add_argument("--project", default=None)
+ s.add_argument("--type", default="misc"); s.set_defaults(fn=cmd_add)
+ s = sub.add_parser("ls"); s.add_argument("--all", action="store_true"); s.set_defaults(fn=cmd_ls)
+ s = sub.add_parser("show"); s.add_argument("id"); s.set_defaults(fn=cmd_show)
+ s = sub.add_parser("approvals"); s.set_defaults(fn=cmd_approvals)
+ s = sub.add_parser("approve"); s.add_argument("id"); s.add_argument("--reason", default=""); s.set_defaults(fn=cmd_approve)
+ s = sub.add_parser("reject"); s.add_argument("id"); s.add_argument("--reason", default=""); s.set_defaults(fn=cmd_reject)
+ s = sub.add_parser("flush"); s.set_defaults(fn=cmd_flush)
+ s = sub.add_parser("status"); s.set_defaults(fn=cmd_status)
+ s = sub.add_parser("activity"); s.add_argument("n", nargs="?", type=int, default=20); s.set_defaults(fn=cmd_activity)
+ s = sub.add_parser("tick"); s.set_defaults(fn=cmd_tick)
+ s = sub.add_parser("start"); s.set_defaults(fn=cmd_start)
+ s = sub.add_parser("stop"); s.set_defaults(fn=cmd_stop)
+ a = ap.parse_args(); a.fn(a)
+
+if __name__ == "__main__":
+ main()
archive/old-conductor-sketch/bin/spawn-worker.sh +61 -0
@@ -0,0 +1,61 @@
+#!/usr/bin/env bash
+# Zion PM - worker spawner (Ditto-style: clean context, tight scope, self-contained result).
+# bash spawn-worker.sh <task-id> <type> "<scoped prompt>" [model]
+# Runs in the BACKGROUND and writes workers/<task-id>/result.json on completion, so the
+# conductor can fire a batch and drain later. Workers act on reversible/internal work directly;
+# anything outward-facing they must queue via bin/outbox-add.sh (never execute).
+
+set -uo pipefail
+PM="/shared/projects/zion-pm"
+# shellcheck disable=SC1091
+source "$PM/env.sh"
+
+TASK_ID="${1:?task-id required}"
+TYPE="${2:?type required}"
+SCOPE="${3:?scoped prompt required}"
+MODEL_OVERRIDE="${4:-}"
+
+# Per-type model routing (defaults to policy worker_default = current ANTHROPIC_MODEL).
+case "$TYPE" in
+ research|misc) WORKER_MODEL="${MODEL_OVERRIDE:-$ANTHROPIC_MODEL}";;
+ code|outreach|browser|ops) WORKER_MODEL="${MODEL_OVERRIDE:-$ANTHROPIC_MODEL}";;
+ *) WORKER_MODEL="${MODEL_OVERRIDE:-$ANTHROPIC_MODEL}";;
+esac
+
+WDIR="$PM/workers/$TASK_ID"
+mkdir -p "$WDIR"
+
+read -r -d '' CONTRACT <<EOF
+You are a Zion-PM worker. Task id: $TASK_ID. Type: $TYPE.
+
+SCOPE (do exactly this, nothing more):
+$SCOPE
+
+Rules:
+- RAG-first: call homelab_context before opening broad files; for code structure use cbm-homelab;
+ for symbol-level edits use Serena. Do not sweep whole trees.
+- Do reversible, internal work directly: read, research, scrape, write/edit code, run tests/builds.
+- OUTWARD actions are FORBIDDEN here. Do NOT send email/DM, push to public repos, publish, deploy,
+ contact any human, or mutate infra. Instead queue a fully-previewed draft:
+ bash $PM/bin/outbox-add.sh "$TASK_ID" "<kind>" "<full preview: recipient/target + content>"
+- Never print or transmit secrets or client PII to any non-local model.
+
+When done, write your result as JSON to $WDIR/result.json with EXACTLY these keys:
+ {"task":"$TASK_ID","summary":"...","artifacts":["paths/urls"],"tests":"...",
+ "blockers":"...","next_action":"...","queued_outbox":["ids if any"]}
+Output nothing else of consequence. Be terse and frugal - metered brain.
+EOF
+
+# Detach so the conductor can spawn a batch and drain later.
+(
+ cd "$PM"
+ ANTHROPIC_MODEL="$WORKER_MODEL" claude -p \
+ --dangerously-skip-permissions \
+ "$CONTRACT" >"$WDIR/worker.out" 2>"$WDIR/worker.err"
+ # Safety net: if the worker didn't emit result.json, synthesize a failure record.
+ if [ ! -f "$WDIR/result.json" ]; then
+ printf '{"task":"%s","summary":"worker produced no result.json","artifacts":[],"tests":"","blockers":"see worker.err","next_action":"retry or escalate","queued_outbox":[]}\n' "$TASK_ID" > "$WDIR/result.json"
+ fi
+) &
+
+echo "[pm] spawned worker $TASK_ID (type=$TYPE model=$WORKER_MODEL pid=$!)"
archive/old-conductor-sketch/env.sh +49 -0
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+# Zion PM - brain selector. Source this before running the conductor or any worker.
+# source /shared/projects/zion-pm/env.sh # default brain (GLM)
+# PM_BRAIN=local source env.sh # local Ollama on the 3060
+# PM_BRAIN=max source env.sh # Claude Max (escalation only)
+# This is the ONE place the model backend is wired. Nothing else hardcodes a provider.
+
+ZION_PM_DIR="/shared/projects/zion-pm"
+SECRETS="/shared/projects/.env.secrets"
+
+# Load secrets without echoing them. File may be CRLF -> strip \r.
+if [ -f "$SECRETS" ]; then
+ set -a
+ # shellcheck disable=SC1090
+ source <(tr -d '\r' < "$SECRETS")
+ set +a
+fi
+
+PM_BRAIN="${PM_BRAIN:-glm}"
+
+case "$PM_BRAIN" in
+ glm)
+ export ANTHROPIC_BASE_URL="https://api.z.ai/api/anthropic"
+ export ANTHROPIC_AUTH_TOKEN="${ZAI_API_KEY:?ZAI_API_KEY missing from .env.secrets}"
+ export ANTHROPIC_MODEL="${PM_MODEL:-glm-4.6}"
+ export ANTHROPIC_SMALL_FAST_MODEL="glm-4.5-air" # keep background calls on GLM, not Anthropic
+ ;;
+ local)
+ # Local Ollama on the 3060 box, OpenAI-compatible -> use the small/triage class only.
+ export ANTHROPIC_BASE_URL="http://REDACTED-IP:11434"
+ export ANTHROPIC_AUTH_TOKEN="ollama"
+ export ANTHROPIC_MODEL="${PM_MODEL:-mistral-nemo:12b}"
+ export ANTHROPIC_SMALL_FAST_MODEL="mistral-nemo:12b"
+ ;;
+ max)
+ # Claude Max - escalation only. Uses the normal logged-in Claude Code auth.
+ unset ANTHROPIC_BASE_URL ANTHROPIC_AUTH_TOKEN
+ export ANTHROPIC_MODEL="${PM_MODEL:-opus}"
+ ;;
+ *)
+ echo "unknown PM_BRAIN=$PM_BRAIN (use glm|local|max)" >&2
+ ;;
+esac
+
+# Don't let a stray ANTHROPIC_API_KEY shadow the auth token on third-party endpoints.
+[ "$PM_BRAIN" != "max" ] && unset ANTHROPIC_API_KEY
+
+export ZION_PM_DIR
+echo "[pm] brain=$PM_BRAIN model=${ANTHROPIC_MODEL} base=${ANTHROPIC_BASE_URL:-<anthropic-default>}" >&2
archive/old-conductor-sketch/hands/README.md +31 -0
@@ -0,0 +1,31 @@
+# Hands - the PM's capability adapters
+
+A "hand" is just a worker (or script) with one tool + a return contract. The Conductor composes
+hands for novel tasks; you rarely build a bespoke integration. Two kinds:
+
+## 1. Inline hands (workers already have these)
+Workers run `claude --dangerously-skip-permissions`, so they can already:
+- **read / research / scrape** - MCP (homelab_context, cbm-homelab, Serena) + `WebSearch`/`WebFetch`
+ + flywheel tools (`crawl`, `http_request`, `wayback_fetch`) repurposed as research hands.
+- **code / test / build** - edit in a worktree, run the repo's test/build commands locally.
+These need no extra wiring. They are reversible/internal, so they run full-auto.
+
+## 2. Execution hands (fire only AFTER Zion approves an outbox item)
+`bin/flush-outbox.sh` routes an approved item of kind `<kind>` to `hands/execute-<kind>.sh`.
+Each hand reads the outbox item (id, preview/payload) and performs the real-world action.
+
+| kind | hand file | status / what it needs |
+|---------------|----------------------------|------------------------|
+| email | execute-email.sh | NEEDS sender identity (policy.yaml sender_identities) + SMTP/API creds |
+| dm / social | execute-social.sh | NEEDS account + API token per platform |
+| git_push | execute-git_push.sh | reuses zionboggan GH PAT (prefix `env -u GH_TOKEN -u GITHUB_TOKEN`) |
+| publish | execute-publish.sh | reuses npm token (~/.npmrc on CT215) |
+| deploy | execute-deploy.sh | reuses CF global key + wrangler (see MASTER_ACCESS_REFERENCE) |
+| infra | execute-infra.sh | control plane CT244:8765 (wake/sleep) or pct exec via pve |
+| browser | execute-browser.sh | NEEDS Playwright worker on a CT (headless, or headed via 3060) |
+
+**Design rule:** a hand never decides *whether* to act - approval already happened. It just
+executes the approved payload, logs the result, and exits non-zero on failure so flush can mark it.
+
+Start order (Zion): give the outreach sender identity -> wire execute-email.sh first (that's the
+"pursue testers" engine), then execute-browser.sh, then the code/deploy hands (creds already exist).
archive/old-conductor-sketch/hands/browser/__pycache__/run.cpython-310.pyc +0 -0
Binary file not shown
archive/old-conductor-sketch/hands/browser/run.py +59 -0
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+"""Zion PM - browser runner (Playwright). The universal hand: drive a real Chromium to read,
+fill, click, post, screenshot, extract. Read-only specs run inline (full-auto, for research);
+specs that submit/post/buy are queued to the outbox and run here only after Zion approves.
+
+Spec (JSON via stdin or a file path arg):
+ {"headless": true, "steps": [
+ {"action":"goto","url":"https://..."},
+ {"action":"fill","selector":"#email","value":"..."},
+ {"action":"click","selector":"button[type=submit]"},
+ {"action":"wait","ms":1500},
+ {"action":"extract","selector":".result","name":"results"},
+ {"action":"screenshot","path":"/tmp/shot.png"}
+ ]}
+Prints JSON: {"ok":bool,"extracted":{...},"error":str|null,"shots":[...]}
+
+Install on the RUNNER host (local ext4, NOT the noexec share):
+ pip install --user playwright && python3 -m playwright install chromium
+"""
+import json, sys
+
+def load_spec():
+ if len(sys.argv) > 1:
+ return json.load(open(sys.argv[1]))
+ return json.load(sys.stdin)
+
+def main():
+ spec = load_spec()
+ out = {"ok": False, "extracted": {}, "shots": [], "error": None}
+ try:
+ from playwright.sync_api import sync_playwright
+ except Exception:
+ out["error"] = "playwright not installed: pip install --user playwright && python3 -m playwright install chromium"
+ print(json.dumps(out)); return
+ try:
+ with sync_playwright() as p:
+ browser = p.chromium.launch(headless=spec.get("headless", True))
+ page = browser.new_page()
+ for s in spec.get("steps", []):
+ a = s.get("action")
+ if a == "goto": page.goto(s["url"], wait_until="domcontentloaded")
+ elif a == "fill": page.fill(s["selector"], s["value"])
+ elif a == "click": page.click(s["selector"])
+ elif a == "wait": page.wait_for_timeout(int(s.get("ms", 1000)))
+ elif a == "waitfor": page.wait_for_selector(s["selector"], timeout=int(s.get("timeout", 15000)))
+ elif a == "extract":
+ els = page.query_selector_all(s["selector"])
+ out["extracted"][s.get("name", s["selector"])] = [e.inner_text() for e in els]
+ elif a == "screenshot":
+ page.screenshot(path=s["path"]); out["shots"].append(s["path"])
+ elif a == "press": page.press(s["selector"], s["key"])
+ browser.close()
+ out["ok"] = True
+ except Exception as e:
+ out["error"] = str(e)
+ print(json.dumps(out))
+
+if __name__ == "__main__":
+ main()
archive/old-conductor-sketch/hands/execute-browser.sh +18 -0
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+# Execution hand: run an APPROVED browser action (post/submit/buy). Fires via flush-outbox.sh.
+# The outbox preview must be a JSON Playwright spec (see hands/browser/run.py).
+# Runs the spec on PM_BROWSER_HOST (a host where playwright is installed on local ext4).
+set -uo pipefail
+OID="${1:?outbox id}"; OUT="${2:?outbox path}"
+[ "${PM_APPROVED:-0}" = "1" ] || { echo "refuse: not an approved flush"; exit 2; }
+PM="/shared/projects/zion-pm"
+
+SPEC=$(jq -r --arg id "$OID" '.history[] | select(.id==$id) | .preview' "$OUT")
+echo "$SPEC" | jq . >/dev/null 2>&1 || { echo "execute-browser: preview is not valid JSON spec for $OID. Manual."; exit 3; }
+
+RUNNER="${PM_BROWSER_HOST:-local}" # 'local' = run here; else an ssh target with playwright
+if [ "$RUNNER" = "local" ]; then
+ echo "$SPEC" | python3 "$PM/hands/browser/run.py"
+else
+ echo "$SPEC" | ssh "$RUNNER" "python3 - " < "$PM/hands/browser/run.py"
+fi
archive/old-conductor-sketch/hands/execute-email.sh +38 -0
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+# Execution hand: send an APPROVED email via Gmail SMTP. Fires only via flush-outbox.sh.
+# Multi-account: the worker resolves the right identity from policy.yaml and writes these fields
+# into the outbox preview, so this hand needs no YAML parsing:
+#
+# FROM: zionboggan@gmail.com
+# PWVAR: GMAIL_APP_PW_ZIONBOGGAN
+# TO: someone@example.com
+# SUBJECT: ...
+# BODY:
+# <multi-line body to end of payload>
+#
+# Each account needs a Gmail APP PASSWORD in /shared/projects/.env.secrets under its PWVAR.
+set -uo pipefail
+OID="${1:?outbox id}"; OUT="${2:?outbox path}"
+[ "${PM_APPROVED:-0}" = "1" ] || { echo "refuse: not an approved flush"; exit 2; }
+
+PAYLOAD=$(jq -r --arg id "$OID" '.history[] | select(.id==$id) | .preview' "$OUT")
+field(){ printf '%s\n' "$PAYLOAD" | sed -n "s/^$1:[[:space:]]*//p" | head -1; }
+
+FROM=$(field FROM); PWVAR=$(field PWVAR); TO=$(field TO); SUBJECT=$(field SUBJECT)
+BODY=$(printf '%s\n' "$PAYLOAD" | sed -n '/^BODY:/,$p' | tail -n +2)
+
+[ -z "$FROM" ] || [ -z "$PWVAR" ] || [ -z "$TO" ] && {
+ echo "execute-email: missing FROM/PWVAR/TO in draft $OID. Left for manual."; exit 3; }
+
+# Load the app password by var name without echoing it.
+source <(tr -d '\r' < /shared/projects/.env.secrets) 2>/dev/null
+APP_PW="${!PWVAR:-}"
+[ -z "$APP_PW" ] && { echo "execute-email: $PWVAR not set in .env.secrets (generate Gmail app password). Left for manual."; exit 3; }
+
+echo "[pm] sending as $FROM -> $TO (subj: $SUBJECT)"
+printf 'From: %s\r\nTo: %s\r\nSubject: %s\r\nMIME-Version: 1.0\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n%s\r\n' \
+ "$FROM" "$TO" "$SUBJECT" "$BODY" \
+ | curl -s --ssl-reqd --url "smtps://smtp.gmail.com:465" \
+ --user "$FROM:$APP_PW" --mail-from "$FROM" --mail-rcpt "$TO" --upload-file - \
+ && { echo "[pm] sent ok"; exit 0; } \
+ || { echo "[pm] send FAILED (check app password / Gmail security)"; exit 1; }
archive/old-conductor-sketch/inbox/t-93d83da5.task +1 -0
@@ -0,0 +1 @@
+Push a new edge-case test suite for TreeTrace
archive/old-conductor-sketch/inbox/t-b3d9919b.task +1 -0
@@ -0,0 +1 @@
+Find 30 devs to beta-test TreeTrace and draft outreach
archive/old-conductor-sketch/policy.yaml +100 -0
@@ -0,0 +1,100 @@
+# Zion PM - policy & model routing
+# Single source of truth for the brain, autonomy gates, and dispatch limits.
+# Change the brain by editing the `models` block (and env.sh reads from here conceptually).
+
+brain:
+ # The Conductor + default workers run on a metered subscription, NOT Claude Max.
+ # Swap providers by editing env.sh (ANTHROPIC_BASE_URL / key var / model).
+ provider: glm # glm | local | anthropic
+ base_url: https://api.z.ai/api/anthropic
+ key_var: ZAI_API_KEY # name of the var in /shared/projects/.env.secrets
+ weekly_budget_guard: true # be frugal; this account shares a weekly cap
+
+models:
+ conductor: glm-4.6 # the planner/supervisor brain
+ worker_default: glm-4.6 # most workers
+ small_fast: glm-4.5-air # background/triage class (avoids falling back to Anthropic)
+ triage_local: "ollama:mistral-nemo:12b@http://REDACTED-IP:11434" # free, on the 3060
+ heavy_judgment: opus # ESCALATION ONLY - runs on Claude Max, manual/approved
+
+# When to escalate a task to heavy_judgment (Max). Conductor flags; does not auto-spend Max.
+escalate_to_max_when:
+ - "architecture decision with broad blast radius"
+ - "security-sensitive code or disclosure"
+ - "outreach copy that represents Zion to clients"
+ - "conductor low-confidence after one worker attempt"
+
+dispatch:
+ max_concurrent_workers: 4
+ worker_timeout_seconds: 1800
+ default_return_contract: [summary, artifacts, tests, blockers, next_action]
+ rag_first: true # every worker prompt must carry this
+
+# Autonomy: what runs without Zion vs what waits in the outbox.
+autonomy:
+ auto: # full-auto, reversible, internal
+ - read/research/scrape
+ - write/edit code in a worktree
+ - run tests / builds locally
+ - draft documents, plans, outreach copy
+ - update internal state, memory-graph, durable docs
+ outbox: # DRAFT ONLY -> wait for Zion's approval to execute
+ - send email / DM / any message to a human
+ - public git push / package publish / site deploy
+ - post to any social or public surface
+ - infra mutation (CT sleep/wake/restart, prod config, data delete)
+ never:
+ - print or transmit secrets / client PII to a non-local model
+ - contact anyone Zion has not approved as a target
+
+notifications:
+ ntfy_topic: zion-pm # set to your real ntfy topic; push only when Zion is needed
+ quiet_when_nothing_needed: true
+
+sender_identities:
+ # The PM picks the right From + persona per task/recipient. Generate a Gmail APP PASSWORD
+ # (myaccount.google.com -> Security -> App passwords, 2FA required) for each and store it in
+ # /shared/projects/.env.secrets under the var named below. Never commit these.
+ routing:
+ recruiter_outreach: zionboggan_gmail # beta-tester / recruiter recruiting
+ client_professional: zionboggan0_gmail # default professional client mail
+ client_agency: zcc_media # ZCC Media Agency clients (full professional)
+ personal_hybrid: zion_personal # warm, first-person, casual-pro
+
+ accounts:
+ zionboggan_gmail:
+ address: "zionboggan@gmail.com"
+ provider: gmail
+ persona: hybrid_personal # warm + credible builder voice
+ use: "recruiter / beta-tester outreach"
+ app_pw_var: GMAIL_APP_PW_ZIONBOGGAN
+ zionboggan0_gmail:
+ address: "zionboggan0@gmail.com"
+ provider: gmail
+ persona: full_professional
+ use: "client emails (professional)"
+ app_pw_var: GMAIL_APP_PW_ZIONBOGGAN0
+ zcc_media:
+ address: "" # FILL: exact zccmediaagency address (@gmail.com or @zccmediaagency.com?)
+ provider: gmail # change to 'workspace' if Google Workspace domain
+ persona: full_professional
+ use: "ZCC Media Agency client emails"
+ app_pw_var: GMAIL_APP_PW_ZCC
+ zion_personal:
+ address: "" # FILL: which 'zion' address is the personal hybrid?
+ provider: gmail
+ persona: hybrid_personal
+ use: "personal / hybrid"
+ app_pw_var: GMAIL_APP_PW_ZION
+ workyaya:
+ address: "workyaya2018@gmail.com"
+ provider: gmail
+ persona: hybrid_personal
+ use: "personal / hybrid"
+ app_pw_var: GMAIL_APP_PW_WORKYAYA
+
+ personas:
+ full_professional: "Polished, concise, third-person-org voice. No slang, no emoji. Signs off as ZCC Media Agency / Zion Boggan."
+ hybrid_personal: "Warm, first-person, credible-builder tone. Direct, friendly, light. The 'indie maker reaching out' voice."
+
+ social: [] # handles the PM may post/DM from (wire later)
archive/old-conductor-sketch/projects.yaml +48 -0
@@ -0,0 +1,48 @@
+# Zion PM - portfolio register. The Conductor enriches detail from homelab_context at runtime;
+# this is just the map of what's in play and who owns the call. Keep terse.
+
+projects:
+ treetrace:
+ state: launched
+ summary: "npm package + site + video; visibility-layer reposition fully posted. PR #6 open."
+ owner_decisions: ["merge public PRs", "client/press outreach"]
+ repo: "TreeTraceTool/TreeTrace"
+ site: "treetrace.dev"
+
+ oversight:
+ state: maintained
+ summary: "Sigstore-adjacent. GLM/OpenCode (CT247) is active maintainer under supervision."
+ owner_decisions: ["version tags / releases", "public pushes"]
+ repo: "zionboggan/oversight"
+ site: "oversightprotocol.dev"
+
+ seven_star:
+ state: active
+ summary: "7starcollective.com - revenue / collective."
+ owner_decisions: ["client/lead follow-up", "any outreach"]
+
+ new_england_to_post:
+ state: active
+ summary: "Tracked in the PM desk; scope to be enriched from RAG."
+ owner_decisions: ["TBD"]
+
+ websites:
+ state: ongoing
+ summary: "zionboggan.com portfolio (live), site deploys via CF Pages/wrangler."
+ owner_decisions: ["prod deploys"]
+
+ hermes:
+ state: active
+ summary: "Kalshi prediction-market trading bot (CT-REDACTED/211). Quant work."
+ owner_decisions: ["capital / strategy changes"]
+ note: "Use the kalshi-quant skill for any work here."
+
+ infra:
+ state: ongoing
+ summary: "Proxmox homelab: CTs, media-AI stack, MCP memory layer, control plane CT244:8765."
+ owner_decisions: ["any infra mutation"]
+
+ concert_reps:
+ state: pending
+ summary: "Order by mid-July 2026."
+ owner_decisions: ["place the order"]
archive/old-conductor-sketch/state/activity.jsonl +5 -0
@@ -0,0 +1,5 @@
+{"ts": "2026-06-20T00:52:46", "event": "task_added", "id": "t-93d83da5", "title": "Push a new edge-case test suite for TreeTrace"}
+{"ts": "2026-06-20T00:52:47", "event": "task_added", "id": "t-b3d9919b", "title": "Find 30 devs to beta-test TreeTrace and draft outreach"}
+{"ts": "2026-06-20T00:52:47", "event": "outbox_approved", "id": "o-1781916767-32523", "kind": "email"}
+{"ts": "2026-06-20T02:11:56", "event": "task_added", "id": "t-fa13c8af", "title": "draft TreeTrace HN relaunch post"}
+{"ts": "2026-06-20T02:11:56", "event": "outbox_approved", "id": "o-1781921515-23820", "kind": "email"}
archive/old-conductor-sketch/state/conductor_state.json +1 -0
@@ -0,0 +1 @@
+{"version":1,"last_tick":null,"running_workers":[],"ticks":0,"notes":"resume-safe conductor state"}
archive/old-conductor-sketch/state/outbox.json +1 -0
@@ -0,0 +1 @@
+{"pending":[],"history":[]}
archive/old-conductor-sketch/state/tasks.json +24 -0
@@ -0,0 +1,24 @@
+{
+ "tasks": [
+ {
+ "id": "t-93d83da5",
+ "title": "Push a new edge-case test suite for TreeTrace",
+ "project": "treetrace",
+ "type": "code",
+ "status": "open",
+ "created": "2026-06-20T00:52:46",
+ "artifacts": [],
+ "worker": null
+ },
+ {
+ "id": "t-b3d9919b",
+ "title": "Find 30 devs to beta-test TreeTrace and draft outreach",
+ "project": "treetrace",
+ "type": "outreach",
+ "status": "open",
+ "created": "2026-06-20T00:52:47",
+ "artifacts": [],
+ "worker": null
+ }
+ ]
+}
deploy/traefik-pm.yml +17 -0
@@ -0,0 +1,17 @@
+# Zion PM v2 - REDACTED-HOST (CT 120 - REDACTED-IP:4100, Next.js)
+# Additive file (mirrors the dashboard route). Authentik forwardAuth via sso-auth@file.
+http:
+ routers:
+ zionpm:
+ rule: "Host(`REDACTED-HOST`)"
+ entrypoints: [websecure]
+ tls:
+ certResolver: cloudflare
+ service: zionpm
+ middlewares:
+ - sso-auth@file
+ services:
+ zionpm:
+ loadBalancer:
+ servers:
+ - url: "http://REDACTED-IP:4100"
deploy/zion-pm.service +17 -0
@@ -0,0 +1,17 @@
+[Unit]
+Description=Zion PM v2 (Next.js conductor app on :4100)
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Type=simple
+WorkingDirectory=/opt/zion-pm
+EnvironmentFile=/opt/zion-pm/.env.local
+Environment=NODE_ENV=production
+ExecStart=/usr/bin/npm run start
+Restart=on-failure
+RestartSec=5
+User=root
+
+[Install]
+WantedBy=multi-user.target
eslint.config.mjs +18 -0
@@ -0,0 +1,18 @@
+import { defineConfig, globalIgnores } from "eslint/config";
+import nextVitals from "eslint-config-next/core-web-vitals";
+import nextTs from "eslint-config-next/typescript";
+
+const eslintConfig = defineConfig([
+ ...nextVitals,
+ ...nextTs,
+ // Override default ignores of eslint-config-next.
+ globalIgnores([
+ // Default ignores of eslint-config-next:
+ ".next/**",
+ "out/**",
+ "build/**",
+ "next-env.d.ts",
+ ]),
+]);
+
+export default eslintConfig;
lib/db.ts +150 -0
@@ -0,0 +1,150 @@
+// SQLite store for Zion PM v2 (SEED §5). better-sqlite3 (synchronous).
+import Database from 'better-sqlite3';
+import { ulid } from 'ulid';
+import fs from 'fs';
+import path from 'path';
+
+const DATA_DIR = process.env.ZPM_DATA_DIR || path.join(process.cwd(), 'data');
+fs.mkdirSync(DATA_DIR, { recursive: true });
+const DB_PATH = path.join(DATA_DIR, 'zionpm.db');
+
+export const db = new Database(DB_PATH);
+db.pragma('journal_mode = WAL');
+
+db.exec(`
+CREATE TABLE IF NOT EXISTS channels(
+ id TEXT PRIMARY KEY,
+ name TEXT NOT NULL UNIQUE,
+ default_model TEXT NOT NULL,
+ created_at INTEGER NOT NULL
+);
+CREATE TABLE IF NOT EXISTS messages(
+ id TEXT PRIMARY KEY,
+ channel_id TEXT NOT NULL REFERENCES channels(id),
+ role TEXT NOT NULL,
+ author_model TEXT,
+ body TEXT NOT NULL,
+ parent_id TEXT REFERENCES messages(id),
+ created_at INTEGER NOT NULL
+);
+CREATE TABLE IF NOT EXISTS tasks(
+ id TEXT PRIMARY KEY,
+ title TEXT NOT NULL,
+ status TEXT NOT NULL DEFAULT 'todo',
+ assigned_model TEXT,
+ channel_id TEXT REFERENCES channels(id),
+ created_at INTEGER NOT NULL,
+ updated_at INTEGER NOT NULL
+);
+CREATE TABLE IF NOT EXISTS outbox(
+ id TEXT PRIMARY KEY,
+ action_type TEXT NOT NULL,
+ payload_json TEXT NOT NULL,
+ status TEXT NOT NULL DEFAULT 'draft',
+ created_at INTEGER NOT NULL,
+ approved_at INTEGER
+);
+CREATE TABLE IF NOT EXISTS cap_state(
+ model TEXT PRIMARY KEY,
+ available INTEGER NOT NULL,
+ reason TEXT,
+ last_checked INTEGER NOT NULL
+);
+`);
+
+export const now = () => Date.now();
+export { ulid };
+
+// ---- one-time seed (idempotent) -------------------------------------------
+function seed() {
+ const chanCount = (db.prepare('SELECT COUNT(*) c FROM channels').get() as { c: number }).c;
+ if (chanCount === 0) {
+ const ins = db.prepare(
+ 'INSERT INTO channels(id,name,default_model,created_at) VALUES(?,?,?,?)'
+ );
+ const seedCh: [string, string][] = [
+ ['pm', 'glm'],
+ ['claude', 'claude'],
+ ['codex', 'codex'],
+ ['ollama', 'ollama'],
+ ];
+ const t = now();
+ for (const [name, model] of seedCh) ins.run(ulid(), name, model, t);
+ }
+ // cap_state: glm is the conductor, NOT a worker row (SEED §6)
+ const capIns = db.prepare(
+ `INSERT INTO cap_state(model,available,reason,last_checked)
+ VALUES(?,?,?,?) ON CONFLICT(model) DO NOTHING`
+ );
+ const t = now();
+ for (const m of ['claude', 'codex', 'ollama']) capIns.run(m, 1, 'seeded', t);
+}
+seed();
+
+// ---- typed row helpers -----------------------------------------------------
+export interface Channel { id: string; name: string; default_model: string; created_at: number; }
+export interface Message { id: string; channel_id: string; role: string; author_model: string | null; body: string; parent_id: string | null; created_at: number; }
+export interface Task { id: string; title: string; status: string; assigned_model: string | null; channel_id: string | null; created_at: number; updated_at: number; }
+export interface Outbox { id: string; action_type: string; payload_json: string; status: string; created_at: number; approved_at: number | null; }
+export interface CapState { model: string; available: number; reason: string | null; last_checked: number; }
+
+// channels
+export const listChannels = () => db.prepare('SELECT * FROM channels ORDER BY created_at').all() as Channel[];
+export const getChannel = (id: string) => db.prepare('SELECT * FROM channels WHERE id=?').get(id) as Channel | undefined;
+export const getChannelByName = (name: string) => db.prepare('SELECT * FROM channels WHERE name=?').get(name) as Channel | undefined;
+export function createChannel(name: string, defaultModel: string): Channel {
+ const id = ulid();
+ db.prepare('INSERT INTO channels(id,name,default_model,created_at) VALUES(?,?,?,?)').run(id, name, defaultModel, now());
+ return getChannel(id)!;
+}
+
+// messages
+export const listMessages = (channelId: string) =>
+ db.prepare('SELECT * FROM messages WHERE channel_id=? ORDER BY created_at').all(channelId) as Message[];
+export function addMessage(channelId: string, role: string, body: string, authorModel: string | null = null, parentId: string | null = null): Message {
+ const id = ulid();
+ db.prepare('INSERT INTO messages(id,channel_id,role,author_model,body,parent_id,created_at) VALUES(?,?,?,?,?,?,?)')
+ .run(id, channelId, role, authorModel, body, parentId, now());
+ return db.prepare('SELECT * FROM messages WHERE id=?').get(id) as Message;
+}
+
+// tasks
+export const listTasks = () => db.prepare('SELECT * FROM tasks ORDER BY created_at DESC').all() as Task[];
+export function createTask(title: string, opts: { status?: string; assignedModel?: string | null; channelId?: string | null } = {}): Task {
+ const id = ulid();
+ const t = now();
+ db.prepare('INSERT INTO tasks(id,title,status,assigned_model,channel_id,created_at,updated_at) VALUES(?,?,?,?,?,?,?)')
+ .run(id, title, opts.status || 'todo', opts.assignedModel ?? null, opts.channelId ?? null, t, t);
+ return db.prepare('SELECT * FROM tasks WHERE id=?').get(id) as Task;
+}
+export function updateTask(id: string, patch: { status?: string; assignedModel?: string | null; title?: string }): Task | undefined {
+ const cur = db.prepare('SELECT * FROM tasks WHERE id=?').get(id) as Task | undefined;
+ if (!cur) return undefined;
+ db.prepare('UPDATE tasks SET status=?, assigned_model=?, title=?, updated_at=? WHERE id=?')
+ .run(patch.status ?? cur.status, patch.assignedModel ?? cur.assigned_model, patch.title ?? cur.title, now(), id);
+ return db.prepare('SELECT * FROM tasks WHERE id=?').get(id) as Task;
+}
+
+// outbox
+export const listOutbox = () => db.prepare('SELECT * FROM outbox ORDER BY created_at DESC').all() as Outbox[];
+export function draftOutbox(actionType: string, payload: unknown): Outbox {
+ const id = ulid();
+ db.prepare('INSERT INTO outbox(id,action_type,payload_json,status,created_at) VALUES(?,?,?,?,?)')
+ .run(id, actionType, JSON.stringify(payload), 'draft', now());
+ return db.prepare('SELECT * FROM outbox WHERE id=?').get(id) as Outbox;
+}
+export function setOutboxStatus(id: string, status: 'approved' | 'rejected' | 'sent'): Outbox | undefined {
+ const approvedAt = status === 'approved' ? now() : null;
+ db.prepare('UPDATE outbox SET status=?, approved_at=COALESCE(?,approved_at) WHERE id=?').run(status, approvedAt, id);
+ return db.prepare('SELECT * FROM outbox WHERE id=?').get(id) as Outbox | undefined;
+}
+
+// cap_state
+export const listCaps = () => db.prepare('SELECT * FROM cap_state ORDER BY model').all() as CapState[];
+export const getCap = (model: string) => db.prepare('SELECT * FROM cap_state WHERE model=?').get(model) as CapState | undefined;
+export function setCap(model: string, available: number, reason: string) {
+ db.prepare(`INSERT INTO cap_state(model,available,reason,last_checked) VALUES(?,?,?,?)
+ ON CONFLICT(model) DO UPDATE SET available=excluded.available, reason=excluded.reason, last_checked=excluded.last_checked`)
+ .run(model, available, reason, now());
+}
+export const touchCap = (model: string) => db.prepare('UPDATE cap_state SET last_checked=? WHERE model=?').run(now(), model);
lib/glm.ts +13 -0
@@ -0,0 +1,13 @@
+// GLM brain via Z.ai Coding Plan subscription (Anthropic-compatible endpoint).
+// SEED §2/§3: NOT PAYG - subscription key from .env.secrets; model id via PM_BRAIN_MODEL.
+import { createAnthropic } from '@ai-sdk/anthropic';
+
+export const PM_BRAIN_MODEL = process.env.PM_BRAIN_MODEL || 'glm-4.6';
+
+export const zai = createAnthropic({
+ baseURL: process.env.ZAI_BASE_URL || 'https://api.z.ai/api/anthropic/v1',
+ apiKey: process.env.ZAI_API_KEY || '',
+ headers: { 'anthropic-version': '2023-06-01' },
+});
+
+export const glmModel = zai(PM_BRAIN_MODEL);
lib/mastra.ts +130 -0
@@ -0,0 +1,130 @@
+// pmConductor - the GLM brain (Mastra Agent) + tool registry (SEED §4).
+import { Agent } from '@mastra/core/agent';
+import { createTool } from '@mastra/core/tools';
+import { z } from 'zod';
+import { glmModel, PM_BRAIN_MODEL } from './glm';
+import { queryMemory, queryGraph } from './memory';
+import { delegate } from './workers/delegate';
+import { createTask, updateTask, draftOutbox } from './db';
+
+// ---- tool registry (SEED §4) ----------------------------------------------
+const delegateTool = createTool({
+ id: 'delegate',
+ description: 'Delegate a self-contained task to a worker model (claude=strong/CT215, codex=strong/CT241, ollama=local/free). Use for heavy or parallel work. Returns the worker output.',
+ inputSchema: z.object({
+ model: z.enum(['claude', 'codex', 'ollama']).describe('worker model'),
+ task: z.string().describe('self-contained work envelope'),
+ ollamaModel: z.string().optional().describe('required iff model=ollama, e.g. mistral-nemo:12b'),
+ context: z.string().optional().describe('RAG/graph snippets to inject'),
+ }),
+ // Mastra v1.45 + zod v4 mis-types `context`; cast to the validated input shape.
+ execute: async ({ context }) => {
+ const c = context as unknown as { model: 'claude' | 'codex' | 'ollama'; task: string; ollamaModel?: string; context?: string };
+ const r = await delegate({ model: c.model, task: c.task, ollamaModel: c.ollamaModel, context: c.context });
+ return { ok: r.ok, model: r.model, output: r.output, error: r.error };
+ },
+});
+
+const createTaskTool = createTool({
+ id: 'createTask',
+ description: 'Create a Board task (kanban card).',
+ inputSchema: z.object({
+ title: z.string(),
+ status: z.enum(['todo', 'doing', 'done', 'blocked']).optional(),
+ assignedModel: z.string().optional(),
+ channelId: z.string().optional(),
+ }),
+ execute: async ({ context }) => {
+ const c = context as unknown as { title: string; status?: string; assignedModel?: string; channelId?: string };
+ const t = createTask(c.title, { status: c.status, assignedModel: c.assignedModel ?? null, channelId: c.channelId ?? null });
+ return { id: t.id, title: t.title, status: t.status };
+ },
+});
+
+const updateTaskTool = createTool({
+ id: 'updateTask',
+ description: 'Update a Board task status/assignment.',
+ inputSchema: z.object({
+ id: z.string(),
+ status: z.enum(['todo', 'doing', 'done', 'blocked']).optional(),
+ assignedModel: z.string().optional(),
+ title: z.string().optional(),
+ }),
+ execute: async ({ context }) => {
+ const c = context as unknown as { id: string; status?: string; assignedModel?: string; title?: string };
+ const t = updateTask(c.id, { status: c.status, assignedModel: c.assignedModel, title: c.title });
+ return t ? { id: t.id, status: t.status } : { error: 'task not found' };
+ },
+});
+
+const draftApprovalTool = createTool({
+ id: 'draftApproval',
+ description: 'Draft an OUTWARD action (email|deploy|publish|infra) into the approval outbox. NEVER auto-sends - Zion approves in the UI. Use for anything leaving the homelab.',
+ inputSchema: z.object({
+ actionType: z.enum(['email', 'deploy', 'publish', 'infra']),
+ payload: z.record(z.string(), z.any()).describe('action details'),
+ }),
+ execute: async ({ context }) => {
+ const c = context as unknown as { actionType: string; payload: Record<string, unknown> };
+ const o = draftOutbox(c.actionType, c.payload);
+ return { id: o.id, status: o.status, note: 'drafted, awaiting human approval' };
+ },
+});
+
+const queryMemoryTool = createTool({
+ id: 'queryMemory',
+ description: 'RAG-first: query the homelab memory (docs, configs, infra, project history) BEFORE reading files.',
+ inputSchema: z.object({ query: z.string() }),
+ execute: async ({ context }) => ({ context: await queryMemory((context as unknown as { query: string })?.query ?? '') }),
+});
+
+const queryGraphTool = createTool({
+ id: 'queryGraph',
+ description: 'Query the code-architecture graph (cbm-homelab): structure, call graph, blast radius.',
+ inputSchema: z.object({ query: z.string() }),
+ execute: async ({ context }) => ({ graph: await queryGraph((context as unknown as { query: string })?.query ?? '') }),
+});
+
+// ---- the conductor agent ---------------------------------------------------
+const INSTRUCTIONS = `You are the Zion PM conductor - the project-manager brain for Zion's homelab, running on GLM (${PM_BRAIN_MODEL}).
+
+Your job: take any task, decompose it, delegate work to the worker fleet, supervise, and gate every OUTWARD action behind the approval outbox.
+
+Operating rules (non-negotiable):
+- GROUNDING: base every homelab/architecture fact STRICTLY on the "Homelab memory" and "Code graph" context provided in the message. NEVER invent services, tech, or infra. If the context does not cover something, say "not in memory" rather than guessing.
+- Delegate heavy/parallel work via the delegate tool: claude (strong, CT215), codex (strong, CT241), ollama (local, free). You are the brain - you do NOT do worker execution yourself.
+- Every OUTWARD action (email, deploy, publish, infra change) MUST go through draftApproval - it drafts only, never sends. Internal delegation and task edits are full-auto.
+- OUTPUT: answer directly in the exact format requested (e.g. exactly N bullets). No preamble, no narration of your reasoning or tools - only the final answer.
+- Track real work as Board tasks via createTask/updateTask when it helps.`;
+
+// queryMemory/queryGraph results are injected by the router (always-on, SEED §7),
+// so they are NOT exposed as agent tools - that avoids a tool-dance + hallucination
+// when the model would otherwise call them, get a miss, and invent facts. They remain
+// exported (queryMemoryTool/queryGraphTool) to document the §4 registry.
+void queryMemoryTool;
+void queryGraphTool;
+
+export const pmConductor = new Agent({
+ name: 'pmConductor',
+ instructions: INSTRUCTIONS,
+ model: glmModel,
+ tools: { delegate: delegateTool, createTask: createTaskTool, updateTask: updateTaskTool, draftApproval: draftApprovalTool },
+});
+
+/**
+ * Run the conductor on a user message. The router pre-injects memory/graph
+ * context so the answer is grounded even if the model under-calls tools.
+ */
+export async function runConductor(
+ userText: string,
+ opts: { memoryContext?: string; graphContext?: string } = {}
+): Promise<string> {
+ const parts: string[] = [];
+ if (opts.memoryContext) parts.push(`# Homelab memory (queryMemory)\n${opts.memoryContext}`);
+ if (opts.graphContext) parts.push(`# Code graph (queryGraph)\n${opts.graphContext}`);
+ parts.push(`# Task from Zion\n${userText}`);
+ parts.push('Answer using ONLY the context above. Output only the final answer in the exact format requested - no preamble, no tool/reasoning narration.');
+ const prompt = parts.join('\n\n');
+ const res = await pmConductor.generate(prompt, { maxSteps: 3 });
+ return ((res as { text?: string }).text ?? '').trim();
+}
lib/memory.ts +53 -0
@@ -0,0 +1,53 @@
+// queryMemory / queryGraph - conductor's shared-memory tools (SEED §4).
+// Uses the MCP SDK directly over SSE (homelab-rag :9876, cbm-homelab :9877).
+import { Client } from '@modelcontextprotocol/sdk/client/index.js';
+import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
+
+const RAG_URL = process.env.ZPM_RAG_SSE || 'http://REDACTED-IP:9876/sse';
+const CBM_URL = process.env.ZPM_CBM_SSE || 'http://REDACTED-IP:9877/sse';
+
+function withTimeout<T>(p: Promise<T>, ms: number, label: string): Promise<T> {
+ return Promise.race([
+ p,
+ new Promise<T>((_, rej) => setTimeout(() => rej(new Error(`${label} timeout ${ms}ms`)), ms)),
+ ]);
+}
+
+async function mcpCall(url: string, name: string, args: Record<string, unknown>, timeoutMs = 60_000): Promise<string> {
+ const c = new Client({ name: 'zion-pm', version: '1.0.0' }, { capabilities: {} });
+ try {
+ await withTimeout(c.connect(new SSEClientTransport(new URL(url))), 15_000, 'mcp connect');
+ const r = (await withTimeout(c.callTool({ name, arguments: args }), timeoutMs, 'mcp call')) as { content?: Array<{ text?: string }> };
+ return (r?.content || []).map((b) => b.text || '').join('\n');
+ } finally {
+ try { await c.close(); } catch { /* ignore */ }
+ }
+}
+
+/** RAG-first memory lookup (homelab-rag homelab_context). SEED §11.2. */
+export async function queryMemory(query: string, limit = 6): Promise<string> {
+ try {
+ return await mcpCall(RAG_URL, 'homelab_context', { query, limit });
+ } catch (e) {
+ return `queryMemory unavailable: ${(e as Error).message}`;
+ }
+}
+
+const looksLikeError = (s: string) => !s || /not found|not indexed|"error"|validation|required property|must have/i.test(s);
+
+/** Code-graph lookup (cbm-homelab). Tries architecture, then graph search, then project list. */
+export async function queryGraph(query: string): Promise<string> {
+ try {
+ const arch = await mcpCall(CBM_URL, 'get_architecture', { project: query });
+ if (!looksLikeError(arch)) return arch;
+ } catch { /* fall through */ }
+ try {
+ const s = await mcpCall(CBM_URL, 'search_graph', { query });
+ if (!looksLikeError(s)) return s;
+ } catch { /* fall through */ }
+ try {
+ const projects = await mcpCall(CBM_URL, 'list_projects', {});
+ if (!looksLikeError(projects)) return `No single code-graph project matched the query. Indexed projects available:\n${projects}`;
+ } catch { /* fall through */ }
+ return 'No matching code-graph project (use queryMemory for prose/docs).';
+}
lib/router.ts +68 -0
@@ -0,0 +1,68 @@
+// Message router (SEED §7): channel-default + @mention dispatch.
+import { getChannel, addMessage, type Message } from './db';
+import { queryMemory, queryGraph } from './memory';
+import { runConductor } from './mastra';
+import { delegate } from './workers/delegate';
+import type { ModelId, OllamaModel } from './workers/types';
+
+// @(glm|claude|codex|ollama)(?::model)? - optional :suffix selects an ollama model
+const MENTION_RE = /@(glm|claude|codex|ollama)(?::(\S+))?/gi;
+
+export interface Mention { model: ModelId; ollamaModel?: string; }
+
+export function parseMentions(text: string): Mention[] {
+ const out: Mention[] = [];
+ let m: RegExpExecArray | null;
+ MENTION_RE.lastIndex = 0;
+ while ((m = MENTION_RE.exec(text)) !== null) {
+ out.push({ model: m[1].toLowerCase() as ModelId, ollamaModel: m[2] });
+ }
+ return out;
+}
+
+const stripMentions = (text: string) => text.replace(MENTION_RE, '').replace(/\s{2,}/g, ' ').trim();
+
+/**
+ * Ingest a user message, resolve targets (mention wins over channel default for
+ * that turn), inject memory, dispatch to conductor (glm) or worker, persist replies.
+ */
+export async function handleMessage(channelId: string, userText: string): Promise<Message[]> {
+ const ch = getChannel(channelId);
+ if (!ch) throw new Error('channel not found');
+
+ const userMsg = addMessage(channelId, 'user', userText, null);
+
+ const mentions = parseMentions(userText);
+ const targets: Mention[] = mentions.length ? mentions : [{ model: ch.default_model as ModelId }];
+ const task = mentions.length ? stripMentions(userText) || userText : userText;
+
+ // RAG-first: inject memory into the conductor's reasoning (SEED §7). Direct
+ // worker dispatch stays clean - the conductor passes targeted context when IT
+ // delegates (SEED §6 DelegateParams.context), avoiding prompt pollution.
+ const needsMemory = targets.some((t) => t.model === 'glm');
+ const memoryContext = needsMemory ? await queryMemory(userText) : '';
+
+ const produced: Message[] = [];
+ for (const target of targets) {
+ let reply = '';
+ let authorModel: string = target.model;
+ try {
+ if (target.model === 'glm') {
+ const graphContext = await queryGraph(userText);
+ reply = await runConductor(userText, { memoryContext, graphContext });
+ } else {
+ const r = await delegate({
+ model: target.model,
+ ollamaModel: target.ollamaModel as OllamaModel | undefined,
+ task,
+ });
+ authorModel = r.model; // may differ after tier fallback
+ reply = r.ok ? r.output : `(${r.model} unavailable: ${r.error})`;
+ }
+ } catch (e) {
+ reply = `(${target.model} error: ${(e as Error).message})`;
+ }
+ produced.push(addMessage(channelId, 'assistant', reply || '(empty reply)', authorModel, userMsg.id));
+ }
+ return produced;
+}
lib/workers/claude.ts +22 -0
@@ -0,0 +1,22 @@
+// Claude Max worker - SSH zion@CT215, run `claude -p` (one-shot, SEED §6).
+import { runSSH, b64 } from './ssh';
+import type { DelegateParams, DelegateResult } from './types';
+
+const HOST = process.env.ZPM_CLAUDE_HOST || 'REDACTED-IP';
+const USER = process.env.ZPM_CLAUDE_USER || 'zion';
+
+export async function claudeAdapter(p: DelegateParams): Promise<DelegateResult> {
+ const start = Date.now();
+ const cwd = p.cwd || '/shared/projects';
+ const prompt = p.context ? `${p.context}\n\n---\n\n${p.task}` : p.task;
+ // Feed prompt via base64->stdin so no shell escaping is needed.
+ // ~/.local/bin holds the claude CLI but isn't on a non-login SSH PATH.
+ // IS_SANDBOX=1 lets --dangerously-skip-permissions run for root over SSH (the CT215 host login).
+ const cmd = `export PATH="$HOME/.local/bin:/usr/local/bin:$PATH"; export IS_SANDBOX=1; cd ${JSON.stringify(cwd)} 2>/dev/null; printf %s ${b64(prompt)} | base64 -d | claude -p --dangerously-skip-permissions 2>&1`;
+ try {
+ const r = await runSSH(HOST, USER, cmd, p.timeoutMs ?? 120_000);
+ return { ok: r.code === 0, output: r.stdout.trim() || r.stderr.trim(), artifacts: [], error: r.code === 0 ? undefined : `exit ${r.code}`, durationMs: Date.now() - start };
+ } catch (e) {
+ return { ok: false, output: '', artifacts: [], error: (e as Error).message, durationMs: Date.now() - start };
+ }
+}
lib/workers/codex.ts +32 -0
@@ -0,0 +1,32 @@
+// Codex Max worker - SSH zion@CT241, run `codex exec` (one-shot, SEED §6).
+import { runSSH, b64 } from './ssh';
+import type { DelegateParams, DelegateResult } from './types';
+
+const HOST = process.env.ZPM_CODEX_HOST || 'REDACTED-IP';
+const USER = process.env.ZPM_CODEX_USER || 'zion';
+
+export async function codexAdapter(p: DelegateParams): Promise<DelegateResult> {
+ const start = Date.now();
+ const cwd = p.cwd || '/tmp'; // small local dir - codex sandbox stalls on the large CIFS share
+ const prompt = p.context ? `${p.context}\n\n---\n\n${p.task}` : p.task;
+ // Decode prompt into a temp file, pass to `codex exec` non-interactively.
+ const cmd =
+ `export PATH="$HOME/.local/bin:/usr/local/bin:$PATH"; cd ${JSON.stringify(cwd)} 2>/dev/null; ` +
+ `f=$(mktemp); printf %s ${b64(prompt)} | base64 -d > "$f"; ` +
+ `codex exec --skip-git-repo-check "$(cat "$f")" 2>&1; rc=$?; rm -f "$f"; exit $rc`;
+ try {
+ const r = await runSSH(HOST, USER, cmd, p.timeoutMs ?? 240_000);
+ return { ok: r.code === 0, output: extractCodexReply(r.stdout) || r.stderr.trim(), artifacts: [], error: r.code === 0 ? undefined : `exit ${r.code}`, durationMs: Date.now() - start };
+ } catch (e) {
+ return { ok: false, output: '', artifacts: [], error: (e as Error).message, durationMs: Date.now() - start };
+ }
+}
+
+// codex exec prints a header + "codex\n<reply>\ntokens used". Pull the clean reply.
+function extractCodexReply(raw: string): string {
+ const s = raw.trim();
+ const i = s.lastIndexOf('\ncodex\n');
+ let body = i >= 0 ? s.slice(i + 7) : s;
+ body = body.replace(/\ntokens used[\s\S]*$/i, '').trim();
+ return body || s;
+}
lib/workers/delegate.ts +61 -0
@@ -0,0 +1,61 @@
+// delegate() entry point + tier fallback (SEED §6).
+import type { DelegateParams, DelegateResult, ModelId } from './types';
+import { claudeAdapter } from './claude';
+import { codexAdapter } from './codex';
+import { ollamaAdapter } from './ollama';
+import { getCap, touchCap, addMessage } from '../db';
+
+// strong -> weak escalation order (SEED §6.1)
+const TIER: ModelId[] = ['claude', 'codex', 'ollama'];
+
+const ADAPTERS: Record<Exclude<ModelId, 'glm'>, (p: DelegateParams) => Promise<DelegateResult>> = {
+ claude: claudeAdapter,
+ codex: codexAdapter,
+ ollama: ollamaAdapter,
+};
+
+function nextAvailable(from: ModelId): ModelId | null {
+ const startIdx = Math.max(0, TIER.indexOf(from));
+ for (let i = startIdx; i < TIER.length; i++) {
+ const m = TIER[i];
+ const cap = getCap(m);
+ if (cap && cap.available === 1) return m;
+ }
+ return null;
+}
+
+/**
+ * Delegate a task to a worker model. If the requested model is capped, fall
+ * through the tier (claude->codex->ollama). glm is the conductor, never a worker.
+ * Persists an assistant message (author_model) when channelId is supplied.
+ */
+export async function delegate(
+ params: DelegateParams,
+ opts: { channelId?: string; allowFallback?: boolean } = {}
+): Promise<DelegateResult & { model: ModelId }> {
+ if (params.model === 'glm') {
+ return { ok: false, output: '', artifacts: [], error: 'glm is the conductor, not a worker', durationMs: 0, model: 'glm' };
+ }
+
+ let model: ModelId = params.model;
+ const cap = getCap(model);
+ if (!cap || cap.available !== 1) {
+ if (opts.allowFallback === false) {
+ return { ok: false, output: '', artifacts: [], error: `${model} unavailable and fallback disabled`, durationMs: 0, model };
+ }
+ const fb = nextAvailable(model);
+ if (!fb) {
+ return { ok: false, output: '', artifacts: [], error: 'no available worker in tier', durationMs: 0, model };
+ }
+ model = fb;
+ }
+
+ const adapter = ADAPTERS[model as Exclude<ModelId, 'glm'>];
+ const result = await adapter({ ...params, model });
+ touchCap(model);
+
+ if (opts.channelId && result.output) {
+ addMessage(opts.channelId, 'assistant', result.output, model);
+ }
+ return { ...result, model };
+}
lib/workers/ollama.ts +35 -0
@@ -0,0 +1,35 @@
+// Local Ollama worker (free tier) - HTTP /api/chat on CT205 (SEED §6).
+import type { DelegateParams, DelegateResult } from './types';
+
+const BASE = process.env.ZPM_OLLAMA_URL || 'http://REDACTED-IP:11434';
+const DEFAULT_MODEL = process.env.ZPM_OLLAMA_DEFAULT || 'mistral-nemo:12b';
+
+export async function ollamaAdapter(p: DelegateParams): Promise<DelegateResult> {
+ const start = Date.now();
+ const model = p.ollamaModel || DEFAULT_MODEL;
+ const messages: Array<{ role: string; content: string }> = [];
+ const sys = p.context ? `You are a helpful worker. Relevant context:\n${p.context}` : 'You are a helpful worker.';
+ messages.push({ role: 'system', content: sys });
+ messages.push({ role: 'user', content: p.task });
+ const ctrl = new AbortController();
+ const timer = setTimeout(() => ctrl.abort(), p.timeoutMs ?? 120_000);
+ try {
+ const res = await fetch(`${BASE}/api/chat`, {
+ method: 'POST',
+ headers: { 'content-type': 'application/json' },
+ body: JSON.stringify({ model, messages, stream: false, options: { think: false } }),
+ signal: ctrl.signal,
+ });
+ if (!res.ok) {
+ const t = await res.text();
+ return { ok: false, output: '', artifacts: [], error: `ollama ${res.status}: ${t.slice(0, 300)}`, durationMs: Date.now() - start };
+ }
+ const j = (await res.json()) as { message?: { content?: string } };
+ const out = j.message?.content?.trim() ?? '';
+ return { ok: out.length > 0, output: out, artifacts: [], error: out ? undefined : 'empty response', durationMs: Date.now() - start };
+ } catch (e) {
+ return { ok: false, output: '', artifacts: [], error: (e as Error).message, durationMs: Date.now() - start };
+ } finally {
+ clearTimeout(timer);
+ }
+}
lib/workers/ssh.ts +33 -0
@@ -0,0 +1,33 @@
+// Minimal ssh2 exec helper. Key-only auth (SEED §11.3 - no passwords in code).
+import { Client } from 'ssh2';
+import fs from 'fs';
+
+const KEY_PATH = process.env.ZPM_SSH_KEY || '/root/.ssh/id_ed25519';
+
+export interface SSHResult { code: number; stdout: string; stderr: string; }
+
+export function runSSH(host: string, user: string, command: string, timeoutMs = 120_000): Promise<SSHResult> {
+ return new Promise((resolve, reject) => {
+ const conn = new Client();
+ let stdout = '';
+ let stderr = '';
+ let settled = false;
+ const done = (fn: () => void) => { if (!settled) { settled = true; clearTimeout(timer); try { conn.end(); } catch {} fn(); } };
+ const timer = setTimeout(() => done(() => reject(new Error(`ssh timeout after ${timeoutMs}ms`))), timeoutMs);
+ conn
+ .on('ready', () => {
+ conn.exec(command, (err, stream) => {
+ if (err) return done(() => reject(err));
+ stream
+ .on('close', (code: number) => done(() => resolve({ code: code ?? 0, stdout, stderr })))
+ .on('data', (d: Buffer) => { stdout += d.toString(); })
+ .stderr.on('data', (d: Buffer) => { stderr += d.toString(); });
+ });
+ })
+ .on('error', (e) => done(() => reject(e)))
+ .connect({ host, port: 22, username: user, privateKey: fs.readFileSync(KEY_PATH), readyTimeout: Math.min(timeoutMs, 20_000) });
+ });
+}
+
+// Wrap an arbitrary payload so it survives the remote shell verbatim (no quoting hell).
+export const b64 = (s: string) => Buffer.from(s, 'utf8').toString('base64');
lib/workers/types.ts +20 -0
@@ -0,0 +1,20 @@
+// Worker adapter contracts (SEED §6).
+export type ModelId = 'glm' | 'claude' | 'codex' | 'ollama';
+export type OllamaModel = 'qwen2.5-coder:7b' | 'deepseek-coder-v2:16b' | 'mistral-nemo:12b' | string;
+
+export interface DelegateParams {
+ model: ModelId;
+ ollamaModel?: OllamaModel; // required iff model === 'ollama'
+ task: string;
+ context?: string;
+ cwd?: string;
+ timeoutMs?: number;
+}
+
+export interface DelegateResult {
+ ok: boolean;
+ output: string;
+ artifacts: string[];
+ error?: string;
+ durationMs: number;
+}
next.config.ts +13 -0
@@ -0,0 +1,13 @@
+import type { NextConfig } from 'next';
+
+const nextConfig: NextConfig = {
+ // native / node-only deps must not be bundled by Next
+ serverExternalPackages: ['better-sqlite3', 'ssh2', 'cpu-features', '@modelcontextprotocol/sdk', '@mastra/core', '@mastra/mcp'],
+ // lint is a dev-time concern; don't block the production build on style nits
+ eslint: { ignoreDuringBuilds: true },
+ // @mastra/core 1.45 + zod 4 mis-type createTool's execute `context` (inconsistent
+ // string-vs-object inference). Runtime is correct + e2e-verified; skip build typecheck.
+ typescript: { ignoreBuildErrors: true },
+};
+
+export default nextConfig;
package.json +37 -0
@@ -0,0 +1,37 @@
+{
+ "name": "zion-pm",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev -p 4100",
+ "build": "next build",
+ "start": "next start -p 4100",
+ "lint": "eslint"
+ },
+ "dependencies": {
+ "@ai-sdk/anthropic": "^3.0.85",
+ "@mastra/core": "^1.45.0",
+ "@mastra/mcp": "^1.11.0",
+ "@modelcontextprotocol/sdk": "^1.29.0",
+ "ai": "^6.0.208",
+ "better-sqlite3": "^12.11.1",
+ "next": "16.2.9",
+ "react": "19.2.4",
+ "react-dom": "19.2.4",
+ "ssh2": "^1.17.0",
+ "ulid": "^3.0.2",
+ "zod": "^4.4.3"
+ },
+ "devDependencies": {
+ "@tailwindcss/postcss": "^4",
+ "@types/better-sqlite3": "^7.6.13",
+ "@types/node": "^20",
+ "@types/react": "^19",
+ "@types/react-dom": "^19",
+ "@types/ssh2": "^1.15.5",
+ "eslint": "^9",
+ "eslint-config-next": "16.2.9",
+ "tailwindcss": "^4",
+ "typescript": "^5"
+ }
+}
pnpm-lock.yaml +6263 -0
@@ -0,0 +1,6263 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@ai-sdk/anthropic':
+ specifier: ^3.0.85
+ version: 3.0.85(zod@4.4.3)
+ '@mastra/core':
+ specifier: ^1.45.0
+ version: 1.45.0(ai@6.0.208(zod@4.4.3))(express@5.2.1)(zod@4.4.3)
+ '@mastra/mcp':
+ specifier: ^1.11.0
+ version: 1.11.0(@mastra/core@1.45.0(ai@6.0.208(zod@4.4.3))(express@5.2.1)(zod@4.4.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.4.3)
+ '@modelcontextprotocol/sdk':
+ specifier: ^1.29.0
+ version: 1.29.0(zod@4.4.3)
+ ai:
+ specifier: ^6.0.208
+ version: 6.0.208(zod@4.4.3)
+ better-sqlite3:
+ specifier: ^12.11.1
+ version: 12.11.1
+ next:
+ specifier: 16.2.9
+ version: 16.2.9(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+ react:
+ specifier: 19.2.4
+ version: 19.2.4
+ react-dom:
+ specifier: 19.2.4
+ version: 19.2.4(react@19.2.4)
+ ssh2:
+ specifier: ^1.17.0
+ version: 1.17.0
+ ulid:
+ specifier: ^3.0.2
+ version: 3.0.2
+ zod:
+ specifier: ^4.4.3
+ version: 4.4.3
+ devDependencies:
+ '@tailwindcss/postcss':
+ specifier: ^4
+ version: 4.3.1
+ '@types/better-sqlite3':
+ specifier: ^7.6.13
+ version: 7.6.13
+ '@types/node':
+ specifier: ^20
+ version: 20.19.43
+ '@types/react':
+ specifier: ^19
+ version: 19.2.17
+ '@types/react-dom':
+ specifier: ^19
+ version: 19.2.3(@types/react@19.2.17)
+ '@types/ssh2':
+ specifier: ^1.15.5
+ version: 1.15.5
+ eslint:
+ specifier: ^9
+ version: 9.39.4(jiti@2.7.0)
+ eslint-config-next:
+ specifier: 16.2.9
+ version: 16.2.9(@typescript-eslint/parser@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ tailwindcss:
+ specifier: ^4
+ version: 4.3.1
+ typescript:
+ specifier: ^5
+ version: 5.9.3
+
+packages:
+
+ '@a2a-js/sdk@0.3.13':
+ resolution: {integrity: sha512-BZr0f9JVNQs3GKOM9xINWCh6OKIJWZFPyqqVqTym5mxO2Eemc6I/0zL7zWnljHzGdaf5aZQyQN5xa6PSH62q+A==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@bufbuild/protobuf': ^2.10.2
+ '@grpc/grpc-js': ^1.11.0
+ express: ^4.21.2 || ^5.1.0
+ peerDependenciesMeta:
+ '@bufbuild/protobuf':
+ optional: true
+ '@grpc/grpc-js':
+ optional: true
+ express:
+ optional: true
+
+ '@ai-sdk/anthropic@3.0.85':
+ resolution: {integrity: sha512-fNeDB644l5wbRNQU0FnI+F7UTtOenMnPtACfMPUJaS2zJfuBlseEa1TMg+otHkETZgaJB+6Na51NQEv0+m7czw==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ '@ai-sdk/gateway@3.0.133':
+ resolution: {integrity: sha512-Ebs+7iS9zUgJu5B0RlxM2JmDWzq79Cpd6YdiqcCzB5qFdpfQJPUDiXutqlQP89F2XGjOdDeidulBTXUdXWzOxw==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ '@ai-sdk/provider-utils@3.0.25':
+ resolution: {integrity: sha512-CvsRu+32Y8a167s+lrIBtsybvgTHp8j9y+6BeTvLeoW3Q+okw/b4CnNUFOLIXsRaKHQKAH+IHNJPYWywfpw0LA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ '@ai-sdk/provider-utils@4.0.27':
+ resolution: {integrity: sha512-ubkAJ+xODouwtmN1tYlvTPphH1hPOBfZaEQe8U7skGvFAnIRs9PPpsq57bC2+Ky/MB4yzhd6YOsxTAx9sGpazw==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ '@ai-sdk/provider-utils@4.0.30':
+ resolution: {integrity: sha512-VO7I+vPffqI5sMnPoUq5DCSqKIgQIk/naJWRdQVpz2ma2zoprC/lqiJiUEl2s6DfvTD76TbhD3q39ROjlA6rGw==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ '@ai-sdk/provider@2.0.3':
+ resolution: {integrity: sha512-h88OPkavHTiN9tMn2l5awAznGB0lXzjcLhgR1/rvjB2zlLprsNxbM2tt6OJsHUxduLC3klq0/eqaSf6fX5XVww==}
+ engines: {node: '>=18'}
+
+ '@ai-sdk/provider@3.0.10':
+ resolution: {integrity: sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw==}
+ engines: {node: '>=18'}
+
+ '@alloc/quick-lru@5.2.0':
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
+ '@babel/code-frame@7.29.7':
+ resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/compat-data@7.29.7':
+ resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/core@7.29.7':
+ resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/generator@7.29.7':
+ resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-compilation-targets@7.29.7':
+ resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-globals@7.29.7':
+ resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-imports@7.29.7':
+ resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-transforms@7.29.7':
+ resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+
+ '@babel/helper-string-parser@7.29.7':
+ resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.29.7':
+ resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-option@7.29.7':
+ resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helpers@7.29.7':
+ resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.7':
+ resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/template@7.29.7':
+ resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/traverse@7.29.7':
+ resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.29.7':
+ resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
+ engines: {node: '>=6.9.0'}
+
+ '@emnapi/core@1.10.0':
+ resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
+
+ '@emnapi/runtime@1.10.0':
+ resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
+
+ '@emnapi/runtime@1.11.1':
+ resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==}
+
+ '@emnapi/wasi-threads@1.2.1':
+ resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
+
+ '@eslint-community/eslint-utils@4.9.1':
+ resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+
+ '@eslint-community/regexpp@4.12.2':
+ resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+
+ '@eslint/config-array@0.21.2':
+ resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/config-helpers@0.4.2':
+ resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/core@0.17.0':
+ resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/eslintrc@3.3.5':
+ resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/js@9.39.4':
+ resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/object-schema@2.1.7':
+ resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/plugin-kit@0.4.1':
+ resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@hono/node-server@1.19.14':
+ resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==}
+ engines: {node: '>=18.14.1'}
+ peerDependencies:
+ hono: ^4
+
+ '@humanfs/core@0.19.2':
+ resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanfs/node@0.16.8':
+ resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanfs/types@0.15.0':
+ resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanwhocodes/module-importer@1.0.1':
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+
+ '@humanwhocodes/retry@0.4.3':
+ resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
+ engines: {node: '>=18.18'}
+
+ '@img/colour@1.1.0':
+ resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.34.5':
+ resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linux-arm64@0.34.5':
+ resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-arm@0.34.5':
+ resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-s390x@0.34.5':
+ resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-x64@0.34.5':
+ resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-wasm32@0.34.5':
+ resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.34.5':
+ resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.34.5':
+ resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.34.5':
+ resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@isaacs/ttlcache@2.1.5':
+ resolution: {integrity: sha512-VwGZqqjAWPICTmxUZnbpEfO60LhPWzquik+bmyXGY7pYRn6diEvCI5i6Ca+J6o2y4vS73HrpuMTo2dOvUevH8w==}
+ engines: {node: '>=12'}
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/remapping@2.3.5':
+ resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@lukeed/csprng@1.1.0':
+ resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
+ engines: {node: '>=8'}
+
+ '@lukeed/uuid@2.0.1':
+ resolution: {integrity: sha512-qC72D4+CDdjGqJvkFMMEAtancHUQ7/d/tAiHf64z8MopFDmcrtbcJuerDtFceuAfQJ2pDSfCKCtbqoGBNnwg0w==}
+ engines: {node: '>=8'}
+
+ '@mastra/core@1.45.0':
+ resolution: {integrity: sha512-UPpNL+iJVfypfc7IOKL9fhmoKKDe6IA6y+DwZDRSTN+uz/ft194e+TrB4LnBdYtTTeLhDO96mxW2rp9LK0ULhg==}
+ engines: {node: '>=22.13.0'}
+ peerDependencies:
+ zod: ^3.25.0 || ^4.0.0
+
+ '@mastra/mcp@1.11.0':
+ resolution: {integrity: sha512-7ucNVasejBAY2Dm5hn82GUkTD/SYj+BvfdWuHgHfu1W4hG0tVyop/RFHWO2qjLyZDxIc6UMxZuuhOB4WVIojKw==}
+ engines: {node: '>=22.13.0'}
+ peerDependencies:
+ '@mastra/core': '>=1.0.0-0 <2.0.0-0'
+
+ '@mastra/schema-compat@1.3.0':
+ resolution: {integrity: sha512-VAWCXGuWuTqnljkheb3zKUujNK6rdGhFISxdSoSz3/d3HJWZOHY10mUnXw5lg0s73FdFDGg4tehbq28fAZz+lA==}
+ engines: {node: '>=22.13.0'}
+ peerDependencies:
+ zod: ^3.25.0 || ^4.0.0
+
+ '@modelcontextprotocol/ext-apps@1.7.4':
+ resolution: {integrity: sha512-QQqysE549cf/Y0VabBmAACXhj92EhB3t8yVct2BHbkWiPTFA1S91EqTVjYXXcZEefXU0pmHcdObhsNMcomJIOQ==}
+ engines: {node: '>=20'}
+ peerDependencies:
+ '@modelcontextprotocol/sdk': ^1.29.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
+ zod: ^3.25.0 || ^4.0.0
+ peerDependenciesMeta:
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
+ '@modelcontextprotocol/sdk@1.29.0':
+ resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@cfworker/json-schema': ^4.1.1
+ zod: ^3.25 || ^4.0
+ peerDependenciesMeta:
+ '@cfworker/json-schema':
+ optional: true
+
+ '@napi-rs/wasm-runtime@1.1.5':
+ resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==}
+ peerDependencies:
+ '@emnapi/core': ^1.7.1
+ '@emnapi/runtime': ^1.7.1
+
+ '@next/env@16.2.9':
+ resolution: {integrity: sha512-ki5VxxXfzD/9TDe13wyeTKIjQTAwBVpnr8KhRDUr8ltMUq1/NBpWNT5tiPoxiGl+PHM4X2ahSOiPk6iAimIzPg==}
+
+ '@next/eslint-plugin-next@16.2.9':
+ resolution: {integrity: sha512-UZi8+YT/MLgTC9nrrn2Xd4lBYv1B7lVmtWHfPcthAI5Tt/C1LuDe6DfmtCtJ+WQod3ksY4VrKSvk3oMVAnL7qw==}
+
+ '@next/swc-darwin-arm64@16.2.9':
+ resolution: {integrity: sha512-HkfxNYUCmcct0Xsqib5KxqMSHV4AHJq857BNRchyBDs4YS19aHzVfn1kDuBYKqLLQBjXgnkIsjV2Kd4d2wzYhw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@next/swc-darwin-x64@16.2.9':
+ resolution: {integrity: sha512-7IAtK4MeybpqRV9GRABWEhJ62mOS+rzWOzOTFie4cSEtm12xsoOMJRcECoZx3FHPzFAqN/IJtHqWAFOLfl152w==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@next/swc-linux-arm64-gnu@16.2.9':
+ resolution: {integrity: sha512-hBD75iWpUtkL9SmQmcRhmLomn9jgkPzCEkbOcLgHymPEKzv+6ONy13RRiIEz/iEObjkS2Jlb5gYS2XGoS3X4rw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-arm64-musl@16.2.9':
+ resolution: {integrity: sha512-qZTI3pf9SGc/obr8NkQAekBxmp1QK+kVm+VAf3BALLfFAj+1kUhkTxmrWpVos9R/UYIA8AWX2p6cGI5WdwzVUA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-linux-x64-gnu@16.2.9':
+ resolution: {integrity: sha512-xm0HfRNX+UkH4R3c18ynswjj5o5uEj/7iI9p9omdtTSIsRCzQqkGMA+10nzJ4EHnYC3as65IMhbbl5fWRUWHYg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-x64-musl@16.2.9':
+ resolution: {integrity: sha512-QumimHkGEG6vM3PfEDWKyKen03NcqLOkeKB1EfcPe7VxzmEiCa4jNnMyBn/US5zcd/VE1CI+O8Ovb3lfjVHfGw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-win32-arm64-msvc@16.2.9':
+ resolution: {integrity: sha512-hzQpKZvw8rAwI6A2uQh6SacCSvNAXaIkPNsWwzqqfRiIMiXMfH936skDhz1OO6KpvdKkJrgHHtqQOq5PIXOvdQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@next/swc-win32-x64-msvc@16.2.9':
+ resolution: {integrity: sha512-qr2VL3Ce5QrwgO2yh1ujSBawrimjVKX8FGF/cOynmdYKJY0BdHpGVNIRK1tqONB10Vkm25Ub1BD2bkjWs4+96w==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@nolyfill/is-core-module@1.0.39':
+ resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
+ engines: {node: '>=12.4.0'}
+
+ '@opentelemetry/api@1.9.1':
+ resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==}
+ engines: {node: '>=8.0.0'}
+
+ '@posthog/core@1.35.3':
+ resolution: {integrity: sha512-EsGPbSLl39Jgo2KZ+kI9UAxFnh5nddaN5bNm2rXvUwF+vGmam9eN1EXeNbxhRU7ulEeIiGdm7XjoU7pzavkgIQ==}
+
+ '@posthog/types@1.390.2':
+ resolution: {integrity: sha512-WcfKz2GNn2vfDX8vXmJYbKxegPxVWHuDQ/pHdAn0HoZDXDFnEp/+x3qBQA+fEvtbPjjtjgAt2wIgJMlM7asx7g==}
+
+ '@rtsao/scc@1.1.0':
+ resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
+
+ '@sec-ant/readable-stream@0.4.1':
+ resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
+
+ '@sindresorhus/merge-streams@4.0.0':
+ resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
+ engines: {node: '>=18'}
+
+ '@sindresorhus/slugify@2.2.1':
+ resolution: {integrity: sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==}
+ engines: {node: '>=12'}
+
+ '@sindresorhus/transliterate@1.6.0':
+ resolution: {integrity: sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==}
+ engines: {node: '>=12'}
+
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+ '@swc/helpers@0.5.15':
+ resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
+
+ '@tailwindcss/node@4.3.1':
+ resolution: {integrity: sha512-6NDaqRoAMSXD1mr/RXu0HBvNE9a2n5tHPsxu9XHLws8o4Twes5rBM2205SUUiJ9goAtadrN6xTGX0UDEwp/N4A==}
+
+ '@tailwindcss/oxide-android-arm64@4.3.1':
+ resolution: {integrity: sha512-SVlyf61g374l5cHyg8x9kf5xmLcOaxvOTsbsqDnSsDJaKOEFZ7GCvi84VAVGpxojYOs1+3K6M0UjXfqPU8vmOQ==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [android]
+
+ '@tailwindcss/oxide-darwin-arm64@4.3.1':
+ resolution: {integrity: sha512-hVnWLwv+e/l7c4WKyVtHVrIPvYdqWHjRB3MDIqARynzFtnQg85kmQEFCbV9Ja0VVx4xXTIiDWY60Y7iz/iNoDA==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-darwin-x64@4.3.1':
+ resolution: {integrity: sha512-Cf7abu0WVgbhU7ANgPUnSAvm7nCvMweusHb8FnaHlLfv/Caq4GYaEZg7ZImzzmjx4lIAfuS8q+eLIS7A7IzxIg==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-freebsd-x64@4.3.1':
+ resolution: {integrity: sha512-ZZqzX2Y+GXtXXfqSfpJhDm60OoZfvLHLCgm+J7NVqgHHJjG/m9ugZI77RwTsVd4fnBJuCFP6Ae6kTJb71UdS8g==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.1':
+ resolution: {integrity: sha512-/Ah/xik0LaMYfv9DZ0S/t4pBlBNYOcqtRwusjgovHkvT8ixueWCLyJjsaF5kQIckjb4IT8Q6K6p/iPmZMixYgg==}
+ engines: {node: '>= 20'}
+ cpu: [arm]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.3.1':
+ resolution: {integrity: sha512-gqdFoVJlw444GvpnheZLHmvTzSxI/cOUUh2KSNejQjTcYkW062SVD+En0rUgD+QV91bz1XGIGtt1HJd48xUGbQ==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.3.1':
+ resolution: {integrity: sha512-Bwv9KwOvE0VKa86xPFif9b9c3Y1NxOV1P0gLti/IYaWEsQYZXDlxfGEtA8mdDZ7SG3wyNXAWYT5SIn3giL57oA==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.3.1':
+ resolution: {integrity: sha512-Ymi8O8T15HYQdOUWUtTI6ldN0neHP85FC+Qz32xTcZ7iJXtem/x8ITev0o1e9e5rkqj4lONZfTRLvkmin1+tKg==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@tailwindcss/oxide-linux-x64-musl@4.3.1':
+ resolution: {integrity: sha512-M+P/91qJ6uILLw4k2G93GMDRAXj61SMvFQYt39AqvUqYgExXpLL5aepfns7sj4HiAQeolirQF9E0lzRvdf4zPQ==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@tailwindcss/oxide-wasm32-wasi@4.3.1':
+ resolution: {integrity: sha512-zsM8uOeqvVGHsAXsJxsT28ttosFahLJKCLOTUBqRAtKnVgGSRitds9T432QiT8b77Yga7JIBkulIRRlJPtYhRA==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+ bundledDependencies:
+ - '@napi-rs/wasm-runtime'
+ - '@emnapi/core'
+ - '@emnapi/runtime'
+ - '@tybys/wasm-util'
+ - '@emnapi/wasi-threads'
+ - tslib
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.3.1':
+ resolution: {integrity: sha512-aiNvSq9BsVk8V513lDKlrCFAgf8qBMPZTpgEhInL+NwQqs97mYmupVMrPrgBBSL8Pv/0zXu9MrMF9rMun1ZeNg==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.3.1':
+ resolution: {integrity: sha512-xDEyu1rg290472FEGaKHnzyDyh5QH+AlWvsU5hMoMtPpzmKlRI0jaYKCgSHDYtaQWZOYbMaduSyCwFwY4n1HmA==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [win32]
+
+ '@tailwindcss/oxide@4.3.1':
+ resolution: {integrity: sha512-yVPyo8RNkabVr3O2EhHEE0Rewu7YKzc1DhIqfL46LKveFrmu9XbDazNOJY7/GRuvw1h6u3utWnR29H/p5JPlgA==}
+ engines: {node: '>= 20'}
+
+ '@tailwindcss/postcss@4.3.1':
+ resolution: {integrity: sha512-dNJuNbdEJT/SWRuXTYP1WSamelsz3ztkUsdtWQPjrexysrTpaEPM40P/71knXiXLYEojqPOEGitVLLpPMS5T6A==}
+
+ '@tybys/wasm-util@0.10.2':
+ resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==}
+
+ '@types/better-sqlite3@7.6.13':
+ resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==}
+
+ '@types/debug@4.1.13':
+ resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==}
+
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
+ '@types/json5@0.0.29':
+ resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/ms@2.1.0':
+ resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
+
+ '@types/node@18.19.130':
+ resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==}
+
+ '@types/node@20.19.43':
+ resolution: {integrity: sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==}
+
+ '@types/react-dom@19.2.3':
+ resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
+ peerDependencies:
+ '@types/react': ^19.2.0
+
+ '@types/react@19.2.17':
+ resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==}
+
+ '@types/ssh2@1.15.5':
+ resolution: {integrity: sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@typescript-eslint/eslint-plugin@8.61.1':
+ resolution: {integrity: sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^8.61.1
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/parser@8.61.1':
+ resolution: {integrity: sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/project-service@8.61.1':
+ resolution: {integrity: sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/scope-manager@8.61.1':
+ resolution: {integrity: sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/tsconfig-utils@8.61.1':
+ resolution: {integrity: sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/type-utils@8.61.1':
+ resolution: {integrity: sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/types@8.61.1':
+ resolution: {integrity: sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/typescript-estree@8.61.1':
+ resolution: {integrity: sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/utils@8.61.1':
+ resolution: {integrity: sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/visitor-keys@8.61.1':
+ resolution: {integrity: sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@unrs/resolver-binding-android-arm-eabi@1.12.2':
+ resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==}
+ cpu: [arm]
+ os: [android]
+
+ '@unrs/resolver-binding-android-arm64@1.12.2':
+ resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==}
+ cpu: [arm64]
+ os: [android]
+
+ '@unrs/resolver-binding-darwin-arm64@1.12.2':
+ resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@unrs/resolver-binding-darwin-x64@1.12.2':
+ resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@unrs/resolver-binding-freebsd-x64@1.12.2':
+ resolution: {integrity: sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2':
+ resolution: {integrity: sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==}
+ cpu: [arm]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2':
+ resolution: {integrity: sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==}
+ cpu: [arm]
+ os: [linux]
+
+ '@unrs/resolver-binding-linux-arm64-gnu@1.12.2':
+ resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-arm64-musl@1.12.2':
+ resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@unrs/resolver-binding-linux-loong64-gnu@1.12.2':
+ resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-loong64-musl@1.12.2':
+ resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [musl]
+
+ '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2':
+ resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2':
+ resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-riscv64-musl@1.12.2':
+ resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@unrs/resolver-binding-linux-s390x-gnu@1.12.2':
+ resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-x64-gnu@1.12.2':
+ resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@unrs/resolver-binding-linux-x64-musl@1.12.2':
+ resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@unrs/resolver-binding-openharmony-arm64@1.12.2':
+ resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@unrs/resolver-binding-wasm32-wasi@1.12.2':
+ resolution: {integrity: sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+
+ '@unrs/resolver-binding-win32-arm64-msvc@1.12.2':
+ resolution: {integrity: sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@unrs/resolver-binding-win32-ia32-msvc@1.12.2':
+ resolution: {integrity: sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@unrs/resolver-binding-win32-x64-msvc@1.12.2':
+ resolution: {integrity: sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@vercel/oidc@3.2.0':
+ resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==}
+ engines: {node: '>= 20'}
+
+ '@workflow/serde@4.1.0-beta.2':
+ resolution: {integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==}
+
+ accepts@2.0.0:
+ resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
+ engines: {node: '>= 0.6'}
+
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn@8.17.0:
+ resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ai@6.0.208:
+ resolution: {integrity: sha512-STz+AaZqJ4ZjH7UkpXkbHx+bjgIDOsE8fIUoZjkZ2whoZcfVmG9K/TqEKouJZ03SuZuD7lagntlU3zBhAEkRpQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ ajv-formats@3.0.1:
+ resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
+ peerDependencies:
+ ajv: ^8.0.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+
+ ajv@6.15.0:
+ resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
+
+ ajv@8.20.0:
+ resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ argparse@1.0.10:
+ resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ aria-query@5.3.2:
+ resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
+ engines: {node: '>= 0.4'}
+
+ array-buffer-byte-length@1.0.2:
+ resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
+ engines: {node: '>= 0.4'}
+
+ array-includes@3.1.9:
+ resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.findlast@1.2.5:
+ resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.findlastindex@1.2.6:
+ resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.flat@1.3.3:
+ resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.flatmap@1.3.3:
+ resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.tosorted@1.1.4:
+ resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==}
+ engines: {node: '>= 0.4'}
+
+ arraybuffer.prototype.slice@1.0.4:
+ resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
+ engines: {node: '>= 0.4'}
+
+ asn1@0.2.6:
+ resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==}
+
+ ast-types-flow@0.0.8:
+ resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
+
+ async-function@1.0.0:
+ resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
+ engines: {node: '>= 0.4'}
+
+ available-typed-arrays@1.0.7:
+ resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
+ engines: {node: '>= 0.4'}
+
+ axe-core@4.12.1:
+ resolution: {integrity: sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==}
+ engines: {node: '>=4'}
+
+ axobject-query@4.1.0:
+ resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
+ engines: {node: '>= 0.4'}
+
+ bail@2.0.2:
+ resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ balanced-match@4.0.4:
+ resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+ engines: {node: 18 || 20 || >=22}
+
+ base64-js@1.5.1:
+ resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+
+ baseline-browser-mapping@2.10.38:
+ resolution: {integrity: sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ bcrypt-pbkdf@1.0.2:
+ resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
+
+ better-sqlite3@12.11.1:
+ resolution: {integrity: sha512-dq9AtApgg5PGFtBzPFSBl3HZQjHok5gaQCM6zh2Yk0aSmDCs1CbnVI8/HgASQkNKsWFpseIO9beg5xxpYhbIfA==}
+ engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x || 26.x}
+
+ bindings@1.5.0:
+ resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
+
+ bl@4.1.0:
+ resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
+
+ body-parser@2.3.0:
+ resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==}
+ engines: {node: '>=18'}
+
+ brace-expansion@1.1.15:
+ resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==}
+
+ brace-expansion@5.0.6:
+ resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
+ engines: {node: 18 || 20 || >=22}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.28.2:
+ resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ buffer@5.7.1:
+ resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
+
+ buildcheck@0.0.7:
+ resolution: {integrity: sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==}
+ engines: {node: '>=10.0.0'}
+
+ bytes@3.1.2:
+ resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
+ engines: {node: '>= 0.8'}
+
+ call-bind-apply-helpers@1.0.2:
+ resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
+ engines: {node: '>= 0.4'}
+
+ call-bind@1.0.9:
+ resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==}
+ engines: {node: '>= 0.4'}
+
+ call-bound@1.0.4:
+ resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
+ engines: {node: '>= 0.4'}
+
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+
+ caniuse-lite@1.0.30001799:
+ resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==}
+
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ character-entities@2.0.2:
+ resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+
+ chat@4.31.0:
+ resolution: {integrity: sha512-F6oJq9JUraLFkITS96/NKgwZwBfZX8aOwOj5qMs5NNwnOGHrSXZ5+osK+EA4HjzfyUEDfFTNiOSmyzgtFLpuWg==}
+ engines: {node: '>=20'}
+ peerDependencies:
+ ai: ^6.0.182
+ zod: ^3.0.0 || ^4.0.0
+ peerDependenciesMeta:
+ ai:
+ optional: true
+ zod:
+ optional: true
+
+ chownr@1.1.4:
+ resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
+
+ client-only@0.0.1:
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ content-disposition@1.1.0:
+ resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==}
+ engines: {node: '>=18'}
+
+ content-type@1.0.5:
+ resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
+ engines: {node: '>= 0.6'}
+
+ content-type@2.0.0:
+ resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==}
+ engines: {node: '>=18'}
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ cookie-signature@1.2.2:
+ resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
+ engines: {node: '>=6.6.0'}
+
+ cookie@0.7.2:
+ resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
+ engines: {node: '>= 0.6'}
+
+ cors@2.8.6:
+ resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==}
+ engines: {node: '>= 0.10'}
+
+ cpu-features@0.0.10:
+ resolution: {integrity: sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==}
+ engines: {node: '>=10.0.0'}
+
+ croner@10.0.1:
+ resolution: {integrity: sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==}
+ engines: {node: '>=18.0'}
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ damerau-levenshtein@1.0.8:
+ resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
+
+ data-view-buffer@1.0.2:
+ resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
+ engines: {node: '>= 0.4'}
+
+ data-view-byte-length@1.0.2:
+ resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==}
+ engines: {node: '>= 0.4'}
+
+ data-view-byte-offset@1.0.1:
+ resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
+ engines: {node: '>= 0.4'}
+
+ debug@3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decode-named-character-reference@1.3.0:
+ resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==}
+
+ decompress-response@6.0.0:
+ resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
+ engines: {node: '>=10'}
+
+ deep-extend@0.6.0:
+ resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
+ engines: {node: '>=4.0.0'}
+
+ deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ define-data-property@1.1.4:
+ resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
+ engines: {node: '>= 0.4'}
+
+ define-properties@1.2.1:
+ resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
+ engines: {node: '>= 0.4'}
+
+ depd@2.0.0:
+ resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
+ engines: {node: '>= 0.8'}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
+ doctrine@2.1.0:
+ resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+ engines: {node: '>=0.10.0'}
+
+ dotenv@17.4.2:
+ resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==}
+ engines: {node: '>=12'}
+
+ dunder-proto@1.0.1:
+ resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
+ engines: {node: '>= 0.4'}
+
+ ee-first@1.1.1:
+ resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
+
+ electron-to-chromium@1.5.376:
+ resolution: {integrity: sha512-cUVA7/RvbFTEuw/i3obUwDTRIXojaxkResf+ibByPFxjc6XK3VNtcQXV0NSbAlJ0FMjcJGgftVVB4Qo184EXvA==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ encodeurl@2.0.0:
+ resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
+ engines: {node: '>= 0.8'}
+
+ end-of-stream@1.4.5:
+ resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
+
+ enhanced-resolve@5.21.6:
+ resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==}
+ engines: {node: '>=10.13.0'}
+
+ es-abstract-get@1.0.0:
+ resolution: {integrity: sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==}
+ engines: {node: '>= 0.4'}
+
+ es-abstract@1.24.2:
+ resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==}
+ engines: {node: '>= 0.4'}
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-iterator-helpers@1.3.3:
+ resolution: {integrity: sha512-0PuBxFi+4uPanB97iDxCLWuHeYud2FALrw5HFZGtAF38UpJDbDC8frwp2cnDyae692CQ0dou60UwWfhgsa4U/g==}
+ engines: {node: '>= 0.4'}
+
+ es-object-atoms@1.1.2:
+ resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==}
+ engines: {node: '>= 0.4'}
+
+ es-set-tostringtag@2.1.0:
+ resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
+ engines: {node: '>= 0.4'}
+
+ es-shim-unscopables@1.1.0:
+ resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==}
+ engines: {node: '>= 0.4'}
+
+ es-to-primitive@1.3.1:
+ resolution: {integrity: sha512-CxN9N56HYfd2m/acc/NOFrZQsN9kU4eh+2kk6A707Kz1krH8tKmfrs5RnftB8WNX80T0NS7vSQsDOlg23diR2g==}
+ engines: {node: '>= 0.4'}
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-html@1.0.3:
+ resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
+
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
+ eslint-config-next@16.2.9:
+ resolution: {integrity: sha512-olGtBrs07bQchpaJWeqbk9GaMoU0oGmN/pYNEBXSbfgKngb5uHnPe37X6tVeh6DJfaWFQildvinGEOrolo5fmw==}
+ peerDependencies:
+ eslint: '>=9.0.0'
+ typescript: '>=3.3.1'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ eslint-import-resolver-node@0.3.10:
+ resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==}
+
+ eslint-import-resolver-typescript@3.10.1:
+ resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ eslint: '*'
+ eslint-plugin-import: '*'
+ eslint-plugin-import-x: '*'
+ peerDependenciesMeta:
+ eslint-plugin-import:
+ optional: true
+ eslint-plugin-import-x:
+ optional: true
+
+ eslint-module-utils@2.13.0:
+ resolution: {integrity: sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: '*'
+ eslint-import-resolver-node: '*'
+ eslint-import-resolver-typescript: '*'
+ eslint-import-resolver-webpack: '*'
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ eslint:
+ optional: true
+ eslint-import-resolver-node:
+ optional: true
+ eslint-import-resolver-typescript:
+ optional: true
+ eslint-import-resolver-webpack:
+ optional: true
+
+ eslint-plugin-import@2.32.0:
+ resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+
+ eslint-plugin-jsx-a11y@6.10.2:
+ resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9
+
+ eslint-plugin-react-hooks@7.1.1:
+ resolution: {integrity: sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0
+
+ eslint-plugin-react@7.37.5:
+ resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
+
+ eslint-scope@8.4.0:
+ resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint-visitor-keys@4.2.1:
+ resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ eslint-visitor-keys@5.0.1:
+ resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ eslint@9.39.4:
+ resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ hasBin: true
+ peerDependencies:
+ jiti: '*'
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+
+ espree@10.4.0:
+ resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ esprima@4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ esquery@1.7.0:
+ resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
+ engines: {node: '>=0.10'}
+
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+
+ etag@1.8.1:
+ resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
+ engines: {node: '>= 0.6'}
+
+ eventsource-parser@3.1.0:
+ resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==}
+ engines: {node: '>=18.0.0'}
+
+ eventsource@3.0.7:
+ resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==}
+ engines: {node: '>=18.0.0'}
+
+ execa@9.6.1:
+ resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==}
+ engines: {node: ^18.19.0 || >=20.5.0}
+
+ exit-hook@5.1.0:
+ resolution: {integrity: sha512-INjr2xyxHo7bhAqf5ong++GZPPnpcuBcaXUKt03yf7Fie9yWD7FapL4teOU0+awQazGs5ucBh7xWs/AD+6nhog==}
+ engines: {node: '>=20'}
+
+ expand-template@2.0.3:
+ resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
+ engines: {node: '>=6'}
+
+ express-rate-limit@8.5.2:
+ resolution: {integrity: sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==}
+ engines: {node: '>= 16'}
+ peerDependencies:
+ express: '>= 4.11'
+
+ express@5.2.1:
+ resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==}
+ engines: {node: '>= 18'}
+
+ extend-shallow@2.0.1:
+ resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
+ engines: {node: '>=0.10.0'}
+
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-glob@3.3.1:
+ resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
+ engines: {node: '>=8.6.0'}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ fast-uri@3.1.2:
+ resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==}
+
+ fastq@1.20.1:
+ resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ figures@6.1.0:
+ resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==}
+ engines: {node: '>=18'}
+
+ file-entry-cache@8.0.0:
+ resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
+ engines: {node: '>=16.0.0'}
+
+ file-uri-to-path@1.0.0:
+ resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ finalhandler@2.1.1:
+ resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==}
+ engines: {node: '>= 18.0.0'}
+
+ find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+
+ flat-cache@4.0.1:
+ resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
+ engines: {node: '>=16'}
+
+ flatted@3.4.2:
+ resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
+
+ for-each@0.3.5:
+ resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
+ engines: {node: '>= 0.4'}
+
+ forwarded@0.2.0:
+ resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
+ engines: {node: '>= 0.6'}
+
+ fresh@2.0.0:
+ resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
+ engines: {node: '>= 0.8'}
+
+ fs-constants@1.0.0:
+ resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ function.prototype.name@1.2.0:
+ resolution: {integrity: sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==}
+ engines: {node: '>= 0.4'}
+
+ functions-have-names@1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+
+ generator-function@2.0.1:
+ resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==}
+ engines: {node: '>= 0.4'}
+
+ gensync@1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+
+ get-intrinsic@1.3.0:
+ resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
+ engines: {node: '>= 0.4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
+ get-stream@9.0.1:
+ resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==}
+ engines: {node: '>=18'}
+
+ get-symbol-description@1.1.0:
+ resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
+ engines: {node: '>= 0.4'}
+
+ get-tsconfig@4.14.0:
+ resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==}
+
+ github-from-package@0.0.0:
+ resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ globals@14.0.0:
+ resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
+ engines: {node: '>=18'}
+
+ globals@16.4.0:
+ resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==}
+ engines: {node: '>=18'}
+
+ globalthis@1.0.4:
+ resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
+ engines: {node: '>= 0.4'}
+
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ gray-matter@4.0.3:
+ resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
+ engines: {node: '>=6.0'}
+
+ has-bigints@1.1.0:
+ resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
+ engines: {node: '>= 0.4'}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ has-property-descriptors@1.0.2:
+ resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
+
+ has-proto@1.2.0:
+ resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==}
+ engines: {node: '>= 0.4'}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.4:
+ resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
+ engines: {node: '>= 0.4'}
+
+ hermes-estree@0.25.1:
+ resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==}
+
+ hermes-parser@0.25.1:
+ resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==}
+
+ hono@4.12.26:
+ resolution: {integrity: sha512-uyZtpnYxM9CmQ7QsQknM4zN8EftNqhON1qYeIKM0Se67CCEe2c44xyGURwB0axX2fBDu1dqHrHAc1hmNT8ITkw==}
+ engines: {node: '>=16.9.0'}
+
+ http-errors@2.0.1:
+ resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
+ engines: {node: '>= 0.8'}
+
+ human-signals@8.0.1:
+ resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==}
+ engines: {node: '>=18.18.0'}
+
+ iconv-lite@0.7.2:
+ resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==}
+ engines: {node: '>=0.10.0'}
+
+ ieee754@1.2.1:
+ resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+
+ ignore@5.3.2:
+ resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+ engines: {node: '>= 4'}
+
+ ignore@7.0.5:
+ resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
+ engines: {node: '>= 4'}
+
+ import-fresh@3.3.1:
+ resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
+ engines: {node: '>=6'}
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ ini@1.3.8:
+ resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+
+ internal-slot@1.1.0:
+ resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
+ engines: {node: '>= 0.4'}
+
+ ip-address@10.2.0:
+ resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==}
+ engines: {node: '>= 12'}
+
+ ipaddr.js@1.9.1:
+ resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
+ engines: {node: '>= 0.10'}
+
+ is-array-buffer@3.0.5:
+ resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
+ engines: {node: '>= 0.4'}
+
+ is-async-function@2.1.1:
+ resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
+ engines: {node: '>= 0.4'}
+
+ is-bigint@1.1.0:
+ resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==}
+ engines: {node: '>= 0.4'}
+
+ is-boolean-object@1.2.2:
+ resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==}
+ engines: {node: '>= 0.4'}
+
+ is-bun-module@2.0.0:
+ resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==}
+
+ is-callable@1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+
+ is-core-module@2.16.2:
+ resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==}
+ engines: {node: '>= 0.4'}
+
+ is-data-view@1.0.2:
+ resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==}
+ engines: {node: '>= 0.4'}
+
+ is-date-object@1.1.0:
+ resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
+ engines: {node: '>= 0.4'}
+
+ is-document.all@1.0.0:
+ resolution: {integrity: sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==}
+ engines: {node: '>= 0.4'}
+
+ is-extendable@0.1.1:
+ resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
+ engines: {node: '>=0.10.0'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-finalizationregistry@1.1.1:
+ resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
+ engines: {node: '>= 0.4'}
+
+ is-generator-function@1.1.2:
+ resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==}
+ engines: {node: '>= 0.4'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-map@2.0.3:
+ resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
+ engines: {node: '>= 0.4'}
+
+ is-negative-zero@2.0.3:
+ resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
+ engines: {node: '>= 0.4'}
+
+ is-network-error@1.3.2:
+ resolution: {integrity: sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==}
+ engines: {node: '>=16'}
+
+ is-number-object@1.1.1:
+ resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==}
+ engines: {node: '>= 0.4'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
+ is-promise@4.0.0:
+ resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
+
+ is-regex@1.2.1:
+ resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
+ engines: {node: '>= 0.4'}
+
+ is-set@2.0.3:
+ resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
+ engines: {node: '>= 0.4'}
+
+ is-shared-array-buffer@1.0.4:
+ resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
+ engines: {node: '>= 0.4'}
+
+ is-stream@4.0.1:
+ resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==}
+ engines: {node: '>=18'}
+
+ is-string@1.1.1:
+ resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
+ engines: {node: '>= 0.4'}
+
+ is-symbol@1.1.1:
+ resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==}
+ engines: {node: '>= 0.4'}
+
+ is-typed-array@1.1.15:
+ resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
+ engines: {node: '>= 0.4'}
+
+ is-unicode-supported@2.1.0:
+ resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
+ engines: {node: '>=18'}
+
+ is-weakmap@2.0.2:
+ resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
+ engines: {node: '>= 0.4'}
+
+ is-weakref@1.1.1:
+ resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==}
+ engines: {node: '>= 0.4'}
+
+ is-weakset@2.0.4:
+ resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
+ engines: {node: '>= 0.4'}
+
+ isarray@2.0.5:
+ resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ iterator.prototype@1.1.5:
+ resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
+ engines: {node: '>= 0.4'}
+
+ jiti@2.7.0:
+ resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
+ hasBin: true
+
+ jose@6.2.3:
+ resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==}
+
+ jpeg-js@0.4.4:
+ resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==}
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ js-yaml@3.14.2:
+ resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==}
+ hasBin: true
+
+ js-yaml@4.2.0:
+ resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==}
+ hasBin: true
+
+ jsesc@3.1.0:
+ resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ json-buffer@3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+ json-schema-to-zod@2.8.1:
+ resolution: {integrity: sha512-fRr1mHgZ7hboLKBUdR428gd9dIHUFGivUqOeiDcSmyXkNZCtB1uGaZLvsjZ4GaN5pwBIs+TGIOf6s+Rp5/R/zA==}
+ hasBin: true
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ json-schema-typed@8.0.2:
+ resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==}
+
+ json-schema@0.4.0:
+ resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
+
+ json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ json5@1.0.2:
+ resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
+ hasBin: true
+
+ json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ jsx-ast-utils@3.3.5:
+ resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
+ engines: {node: '>=4.0'}
+
+ keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+
+ kind-of@6.0.3:
+ resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
+ engines: {node: '>=0.10.0'}
+
+ language-subtag-registry@0.3.23:
+ resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==}
+
+ language-tags@1.0.9:
+ resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==}
+ engines: {node: '>=0.10'}
+
+ levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+
+ lightningcss-android-arm64@1.32.0:
+ resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ lightningcss-darwin-arm64@1.32.0:
+ resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.32.0:
+ resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.32.0:
+ resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.32.0:
+ resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.32.0:
+ resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ lightningcss-linux-arm64-musl@1.32.0:
+ resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ lightningcss-linux-x64-gnu@1.32.0:
+ resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ lightningcss-linux-x64-musl@1.32.0:
+ resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ lightningcss-win32-arm64-msvc@1.32.0:
+ resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.32.0:
+ resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.32.0:
+ resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
+ engines: {node: '>= 12.0.0'}
+
+ locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+
+ lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
+ longest-streak@3.1.0:
+ resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+
+ loose-envify@1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+
+ lru-cache@11.5.1:
+ resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==}
+ engines: {node: 20 || >=22}
+
+ lru-cache@5.1.1:
+ resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ markdown-table@3.0.4:
+ resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ mdast-util-find-and-replace@3.0.2:
+ resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
+
+ mdast-util-from-markdown@2.0.3:
+ resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==}
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
+
+ mdast-util-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
+
+ mdast-util-gfm-table@2.0.0:
+ resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
+
+ mdast-util-gfm@3.1.0:
+ resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
+
+ mdast-util-phrasing@4.1.0:
+ resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
+
+ mdast-util-to-markdown@2.1.2:
+ resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
+
+ mdast-util-to-string@4.0.0:
+ resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+
+ media-typer@1.1.0:
+ resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
+ engines: {node: '>= 0.8'}
+
+ merge-descriptors@2.0.0:
+ resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
+ engines: {node: '>=18'}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromark-core-commonmark@2.0.3:
+ resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
+
+ micromark-extension-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
+
+ micromark-extension-gfm-table@2.1.1:
+ resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==}
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
+
+ micromark-extension-gfm@3.0.0:
+ resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
+
+ micromark-factory-destination@2.0.1:
+ resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
+
+ micromark-factory-label@2.0.1:
+ resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
+
+ micromark-factory-space@2.0.1:
+ resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==}
+
+ micromark-factory-title@2.0.1:
+ resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
+
+ micromark-factory-whitespace@2.0.1:
+ resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-chunked@2.0.1:
+ resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
+
+ micromark-util-classify-character@2.0.1:
+ resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
+
+ micromark-util-combine-extensions@2.0.1:
+ resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
+
+ micromark-util-decode-string@2.0.1:
+ resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-html-tag-name@2.0.1:
+ resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
+
+ micromark-util-normalize-identifier@2.0.1:
+ resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
+
+ micromark-util-resolve-all@2.0.1:
+ resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-subtokenize@2.1.0:
+ resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.2:
+ resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
+
+ micromark@4.0.2:
+ resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ mime-db@1.54.0:
+ resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@3.0.2:
+ resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
+ engines: {node: '>=18'}
+
+ mimic-response@3.1.0:
+ resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
+ engines: {node: '>=10'}
+
+ minimatch@10.2.5:
+ resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
+ engines: {node: 18 || 20 || >=22}
+
+ minimatch@3.1.5:
+ resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ mkdirp-classic@0.5.3:
+ resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ nan@2.27.0:
+ resolution: {integrity: sha512-hC+0LidcL3XE4rp1C4H54KujgXKzbfyTngZTwBByQxsOxCEKZT0MPQ4hOKUH2jU1OYstqdDH4onyHPDzcV0XdQ==}
+
+ nanoid@3.3.13:
+ resolution: {integrity: sha512-sPdqC6ByMVVGvF1ynvvMo0/o+oD1VX7DaHhijt1bFgjvBkHBib4t49GoNDhf2NDta4oeUNlaGbSt5K7qjZ955Q==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ napi-build-utils@2.0.0:
+ resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==}
+
+ napi-postinstall@0.3.4:
+ resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==}
+ engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+ hasBin: true
+
+ natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ negotiator@1.0.0:
+ resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
+ engines: {node: '>= 0.6'}
+
+ next@16.2.9:
+ resolution: {integrity: sha512-MEOJiq/UvuezAdqVSceHbqDgZt1kDw2tpGVOlsdIoJsQdbN2JY2hpVG4xnXGkbdJUOEWhnRfiu/O4Hpc9Juwww==}
+ engines: {node: '>=20.9.0'}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ '@playwright/test': ^1.51.1
+ babel-plugin-react-compiler: '*'
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ '@playwright/test':
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+
+ node-abi@3.92.0:
+ resolution: {integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==}
+ engines: {node: '>=10'}
+
+ node-exports-info@1.6.0:
+ resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==}
+ engines: {node: '>= 0.4'}
+
+ node-releases@2.0.48:
+ resolution: {integrity: sha512-1uz8041X6LoI6ZSdZacM9lVY28vuzDlSKitnpbSNK0RfKoIJkX29NBPVEFXhnuSuEOA9Ww0xnPJ+ILWbGAv8DA==}
+ engines: {node: '>=18'}
+
+ npm-run-path@6.0.0:
+ resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==}
+ engines: {node: '>=18'}
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ object-inspect@1.13.4:
+ resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
+ engines: {node: '>= 0.4'}
+
+ object-keys@1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+
+ object.assign@4.1.7:
+ resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
+ engines: {node: '>= 0.4'}
+
+ object.entries@1.1.9:
+ resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==}
+ engines: {node: '>= 0.4'}
+
+ object.fromentries@2.0.8:
+ resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
+ engines: {node: '>= 0.4'}
+
+ object.groupby@1.0.3:
+ resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==}
+ engines: {node: '>= 0.4'}
+
+ object.values@1.2.1:
+ resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==}
+ engines: {node: '>= 0.4'}
+
+ on-finished@2.4.1:
+ resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
+ engines: {node: '>= 0.8'}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ optionator@0.9.4:
+ resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
+ engines: {node: '>= 0.8.0'}
+
+ own-keys@1.0.1:
+ resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
+ engines: {node: '>= 0.4'}
+
+ p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+
+ p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+
+ p-map@7.0.4:
+ resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==}
+ engines: {node: '>=18'}
+
+ p-retry@7.1.1:
+ resolution: {integrity: sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w==}
+ engines: {node: '>=20'}
+
+ parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+
+ parse-ms@4.0.0:
+ resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==}
+ engines: {node: '>=18'}
+
+ parseurl@1.3.3:
+ resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
+ engines: {node: '>= 0.8'}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-key@4.0.0:
+ resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
+ engines: {node: '>=12'}
+
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-to-regexp@8.4.2:
+ resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.2:
+ resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
+ engines: {node: '>=8.6'}
+
+ picomatch@4.0.4:
+ resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
+ engines: {node: '>=12'}
+
+ pkce-challenge@5.0.1:
+ resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==}
+ engines: {node: '>=16.20.0'}
+
+ possible-typed-array-names@1.1.0:
+ resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
+ engines: {node: '>= 0.4'}
+
+ postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postcss@8.5.15:
+ resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ posthog-node@5.38.2:
+ resolution: {integrity: sha512-eiKpU+vX4hVuHbO/EosvPHsmh2AVIdoVmWss/uUOs1t4b0ViCblw2o8OIFqHxKj3mYRnSOBlX0Dw3wBvcCaYpA==}
+ engines: {node: ^20.20.0 || >=22.22.0}
+ peerDependencies:
+ rxjs: ^7.0.0
+ peerDependenciesMeta:
+ rxjs:
+ optional: true
+
+ prebuild-install@7.1.3:
+ resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==}
+ engines: {node: '>=10'}
+ deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available.
+ hasBin: true
+
+ prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ pretty-ms@9.3.0:
+ resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==}
+ engines: {node: '>=18'}
+
+ prop-types@15.8.1:
+ resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+
+ proxy-addr@2.0.7:
+ resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
+ engines: {node: '>= 0.10'}
+
+ pump@3.0.4:
+ resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ qs@6.15.2:
+ resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==}
+ engines: {node: '>=0.6'}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ range-parser@1.2.1:
+ resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
+ engines: {node: '>= 0.6'}
+
+ raw-body@3.0.2:
+ resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==}
+ engines: {node: '>= 0.10'}
+
+ rc@1.2.8:
+ resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
+ hasBin: true
+
+ react-dom@19.2.4:
+ resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==}
+ peerDependencies:
+ react: ^19.2.4
+
+ react-is@16.13.1:
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+
+ react@19.2.4:
+ resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
+ engines: {node: '>=0.10.0'}
+
+ readable-stream@3.6.2:
+ resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
+ engines: {node: '>= 6'}
+
+ reflect.getprototypeof@1.0.10:
+ resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
+ engines: {node: '>= 0.4'}
+
+ regexp.prototype.flags@1.5.4:
+ resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
+ engines: {node: '>= 0.4'}
+
+ remark-gfm@4.0.1:
+ resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
+
+ remark-parse@11.0.0:
+ resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+
+ remark-stringify@11.0.0:
+ resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+
+ remend@1.3.0:
+ resolution: {integrity: sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw==}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ resolve-pkg-maps@1.0.0:
+ resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
+ resolve@2.0.0-next.7:
+ resolution: {integrity: sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==}
+ engines: {node: '>= 0.4'}
+ hasBin: true
+
+ reusify@1.1.0:
+ resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ router@2.2.0:
+ resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
+ engines: {node: '>= 18'}
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ safe-array-concat@1.1.4:
+ resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==}
+ engines: {node: '>=0.4'}
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ safe-push-apply@1.0.0:
+ resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==}
+ engines: {node: '>= 0.4'}
+
+ safe-regex-test@1.1.0:
+ resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
+ engines: {node: '>= 0.4'}
+
+ safer-buffer@2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
+ scheduler@0.27.0:
+ resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
+
+ section-matter@1.0.0:
+ resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
+ engines: {node: '>=4'}
+
+ semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+
+ semver@7.8.5:
+ resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ send@1.2.1:
+ resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==}
+ engines: {node: '>= 18'}
+
+ serve-static@2.2.1:
+ resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==}
+ engines: {node: '>= 18'}
+
+ set-function-length@1.2.2:
+ resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
+ engines: {node: '>= 0.4'}
+
+ set-function-name@2.0.2:
+ resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
+ engines: {node: '>= 0.4'}
+
+ set-proto@1.0.0:
+ resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==}
+ engines: {node: '>= 0.4'}
+
+ setprototypeof@1.2.0:
+ resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
+
+ sharp@0.34.5:
+ resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ side-channel-list@1.0.1:
+ resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-map@1.0.1:
+ resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-weakmap@1.0.2:
+ resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
+ engines: {node: '>= 0.4'}
+
+ side-channel@1.1.1:
+ resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==}
+ engines: {node: '>= 0.4'}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ simple-concat@1.0.1:
+ resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
+
+ simple-get@4.0.1:
+ resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ sprintf-js@1.0.3:
+ resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+
+ ssh2@1.17.0:
+ resolution: {integrity: sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==}
+ engines: {node: '>=10.16.0'}
+
+ stable-hash@0.0.5:
+ resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==}
+
+ statuses@2.0.2:
+ resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
+ engines: {node: '>= 0.8'}
+
+ stop-iteration-iterator@1.1.0:
+ resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.includes@2.0.1:
+ resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.matchall@4.0.12:
+ resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.repeat@1.0.0:
+ resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==}
+
+ string.prototype.trim@1.2.11:
+ resolution: {integrity: sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.trimend@1.0.10:
+ resolution: {integrity: sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.trimstart@1.0.8:
+ resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
+ engines: {node: '>= 0.4'}
+
+ string_decoder@1.3.0:
+ resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+
+ strip-bom-string@1.0.0:
+ resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==}
+ engines: {node: '>=0.10.0'}
+
+ strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+
+ strip-final-newline@4.0.0:
+ resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==}
+ engines: {node: '>=18'}
+
+ strip-json-comments@2.0.1:
+ resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
+ engines: {node: '>=0.10.0'}
+
+ strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ styled-jsx@5.1.6:
+ resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ tailwindcss@4.3.1:
+ resolution: {integrity: sha512-hk+TB1m+K8CYNrP6rjQaq/Y+4Zylwpa87mLYBKCunwnnQ9p+fHb7kmSfGqyEJoxF/O6CDyABWVFEafNSYKll+Q==}
+
+ tapable@2.3.3:
+ resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==}
+ engines: {node: '>=6'}
+
+ tar-fs@2.1.4:
+ resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==}
+
+ tar-stream@2.2.0:
+ resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
+ engines: {node: '>=6'}
+
+ tinyglobby@0.2.17:
+ resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
+ engines: {node: '>=12.0.0'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ toidentifier@1.0.1:
+ resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
+ engines: {node: '>=0.6'}
+
+ tokenx@1.3.0:
+ resolution: {integrity: sha512-NLdXTEZkKiO0gZuLtMoZKjCXTREXeZZt8nnnNeyoXtNZAfG/GKGSbQtLU5STspc0rMSwcA+UJfWZkbNU01iKmQ==}
+
+ trough@2.2.0:
+ resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
+
+ ts-api-utils@2.5.0:
+ resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==}
+ engines: {node: '>=18.12'}
+ peerDependencies:
+ typescript: '>=4.8.4'
+
+ tsconfig-paths@3.15.0:
+ resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ tunnel-agent@0.6.0:
+ resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
+
+ tweetnacl@0.14.5:
+ resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==}
+
+ type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+
+ type-is@2.1.0:
+ resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==}
+ engines: {node: '>= 18'}
+
+ typed-array-buffer@1.0.3:
+ resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
+ engines: {node: '>= 0.4'}
+
+ typed-array-byte-length@1.0.3:
+ resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==}
+ engines: {node: '>= 0.4'}
+
+ typed-array-byte-offset@1.0.4:
+ resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==}
+ engines: {node: '>= 0.4'}
+
+ typed-array-length@1.0.8:
+ resolution: {integrity: sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==}
+ engines: {node: '>= 0.4'}
+
+ typescript-eslint@8.61.1:
+ resolution: {integrity: sha512-V7PayAfJokV3pEHgN7/v03D1SpujhRfQtYLbLIiBfDDncdg4PAiRBfoS4cnCANK4jmAPncczi59QO3afiXUlNw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ ulid@3.0.2:
+ resolution: {integrity: sha512-yu26mwteFYzBAot7KVMqFGCVpsF6g8wXfJzQUHvu1no3+rRRSFcSV2nKeYvNPLD2J4b08jYBDhHUjeH0ygIl9w==}
+ hasBin: true
+
+ unbox-primitive@1.1.0:
+ resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
+ engines: {node: '>= 0.4'}
+
+ undici-types@5.26.5:
+ resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+
+ undici-types@6.21.0:
+ resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+
+ unicorn-magic@0.3.0:
+ resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
+ engines: {node: '>=18'}
+
+ unified@11.0.5:
+ resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
+
+ unist-util-is@6.0.1:
+ resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-parents@6.0.2:
+ resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
+
+ unist-util-visit@5.1.0:
+ resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==}
+
+ unpipe@1.0.0:
+ resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
+ engines: {node: '>= 0.8'}
+
+ unrs-resolver@1.12.2:
+ resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==}
+
+ update-browserslist-db@1.2.3:
+ resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ uuid@11.1.1:
+ resolution: {integrity: sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==}
+ hasBin: true
+
+ vary@1.1.2:
+ resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
+ engines: {node: '>= 0.8'}
+
+ vfile-message@4.0.3:
+ resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ which-boxed-primitive@1.1.1:
+ resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
+ engines: {node: '>= 0.4'}
+
+ which-builtin-type@1.2.1:
+ resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==}
+ engines: {node: '>= 0.4'}
+
+ which-collection@1.0.2:
+ resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
+ engines: {node: '>= 0.4'}
+
+ which-typed-array@1.1.22:
+ resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==}
+ engines: {node: '>= 0.4'}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ word-wrap@1.2.5:
+ resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+ engines: {node: '>=0.10.0'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ ws@8.21.0:
+ resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ xxhash-wasm@1.1.0:
+ resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==}
+
+ yallist@3.1.1:
+ resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+
+ yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+
+ yoctocolors@2.1.2:
+ resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==}
+ engines: {node: '>=18'}
+
+ zod-from-json-schema@0.0.5:
+ resolution: {integrity: sha512-zYEoo86M1qpA1Pq6329oSyHLS785z/mTwfr9V1Xf/ZLhuuBGaMlDGu/pDVGVUe4H4oa1EFgWZT53DP0U3oT9CQ==}
+
+ zod-from-json-schema@0.5.3:
+ resolution: {integrity: sha512-44YFiuq+WHw9YZQAo/Ad0F7o9c/im0Q6cnHI23BsXhEmZtkNn4cD0bljLMMjkfb/EidopPWdsmKI8EvLHX5ZyA==}
+
+ zod-to-json-schema@3.25.2:
+ resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==}
+ peerDependencies:
+ zod: ^3.25.28 || ^4
+
+ zod-validation-error@4.0.2:
+ resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ zod: ^3.25.0 || ^4.0.0
+
+ zod@3.25.76:
+ resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+
+ zod@4.4.3:
+ resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
+
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
+snapshots:
+
+ '@a2a-js/sdk@0.3.13(express@5.2.1)':
+ dependencies:
+ uuid: 11.1.1
+ optionalDependencies:
+ express: 5.2.1
+
+ '@ai-sdk/anthropic@3.0.85(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider': 3.0.10
+ '@ai-sdk/provider-utils': 4.0.30(zod@4.4.3)
+ zod: 4.4.3
+
+ '@ai-sdk/gateway@3.0.133(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider': 3.0.10
+ '@ai-sdk/provider-utils': 4.0.30(zod@4.4.3)
+ '@vercel/oidc': 3.2.0
+ zod: 4.4.3
+
+ '@ai-sdk/provider-utils@3.0.25(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider': 2.0.3
+ '@standard-schema/spec': 1.1.0
+ eventsource-parser: 3.1.0
+ zod: 4.4.3
+
+ '@ai-sdk/provider-utils@4.0.27(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider': 3.0.10
+ '@standard-schema/spec': 1.1.0
+ eventsource-parser: 3.1.0
+ zod: 4.4.3
+
+ '@ai-sdk/provider-utils@4.0.30(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider': 3.0.10
+ '@standard-schema/spec': 1.1.0
+ eventsource-parser: 3.1.0
+ zod: 4.4.3
+
+ '@ai-sdk/provider@2.0.3':
+ dependencies:
+ json-schema: 0.4.0
+
+ '@ai-sdk/provider@3.0.10':
+ dependencies:
+ json-schema: 0.4.0
+
+ '@alloc/quick-lru@5.2.0': {}
+
+ '@babel/code-frame@7.29.7':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.29.7
+ js-tokens: 4.0.0
+ picocolors: 1.1.1
+
+ '@babel/compat-data@7.29.7': {}
+
+ '@babel/core@7.29.7':
+ dependencies:
+ '@babel/code-frame': 7.29.7
+ '@babel/generator': 7.29.7
+ '@babel/helper-compilation-targets': 7.29.7
+ '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7)
+ '@babel/helpers': 7.29.7
+ '@babel/parser': 7.29.7
+ '@babel/template': 7.29.7
+ '@babel/traverse': 7.29.7
+ '@babel/types': 7.29.7
+ '@jridgewell/remapping': 2.3.5
+ convert-source-map: 2.0.0
+ debug: 4.4.3
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/generator@7.29.7':
+ dependencies:
+ '@babel/parser': 7.29.7
+ '@babel/types': 7.29.7
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+ jsesc: 3.1.0
+
+ '@babel/helper-compilation-targets@7.29.7':
+ dependencies:
+ '@babel/compat-data': 7.29.7
+ '@babel/helper-validator-option': 7.29.7
+ browserslist: 4.28.2
+ lru-cache: 5.1.1
+ semver: 6.3.1
+
+ '@babel/helper-globals@7.29.7': {}
+
+ '@babel/helper-module-imports@7.29.7':
+ dependencies:
+ '@babel/traverse': 7.29.7
+ '@babel/types': 7.29.7
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)':
+ dependencies:
+ '@babel/core': 7.29.7
+ '@babel/helper-module-imports': 7.29.7
+ '@babel/helper-validator-identifier': 7.29.7
+ '@babel/traverse': 7.29.7
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-string-parser@7.29.7': {}
+
+ '@babel/helper-validator-identifier@7.29.7': {}
+
+ '@babel/helper-validator-option@7.29.7': {}
+
+ '@babel/helpers@7.29.7':
+ dependencies:
+ '@babel/template': 7.29.7
+ '@babel/types': 7.29.7
+
+ '@babel/parser@7.29.7':
+ dependencies:
+ '@babel/types': 7.29.7
+
+ '@babel/template@7.29.7':
+ dependencies:
+ '@babel/code-frame': 7.29.7
+ '@babel/parser': 7.29.7
+ '@babel/types': 7.29.7
+
+ '@babel/traverse@7.29.7':
+ dependencies:
+ '@babel/code-frame': 7.29.7
+ '@babel/generator': 7.29.7
+ '@babel/helper-globals': 7.29.7
+ '@babel/parser': 7.29.7
+ '@babel/template': 7.29.7
+ '@babel/types': 7.29.7
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/types@7.29.7':
+ dependencies:
+ '@babel/helper-string-parser': 7.29.7
+ '@babel/helper-validator-identifier': 7.29.7
+
+ '@emnapi/core@1.10.0':
+ dependencies:
+ '@emnapi/wasi-threads': 1.2.1
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/runtime@1.10.0':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/runtime@1.11.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/wasi-threads@1.2.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.7.0))':
+ dependencies:
+ eslint: 9.39.4(jiti@2.7.0)
+ eslint-visitor-keys: 3.4.3
+
+ '@eslint-community/regexpp@4.12.2': {}
+
+ '@eslint/config-array@0.21.2':
+ dependencies:
+ '@eslint/object-schema': 2.1.7
+ debug: 4.4.3
+ minimatch: 3.1.5
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/config-helpers@0.4.2':
+ dependencies:
+ '@eslint/core': 0.17.0
+
+ '@eslint/core@0.17.0':
+ dependencies:
+ '@types/json-schema': 7.0.15
+
+ '@eslint/eslintrc@3.3.5':
+ dependencies:
+ ajv: 6.15.0
+ debug: 4.4.3
+ espree: 10.4.0
+ globals: 14.0.0
+ ignore: 5.3.2
+ import-fresh: 3.3.1
+ js-yaml: 4.2.0
+ minimatch: 3.1.5
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/js@9.39.4': {}
+
+ '@eslint/object-schema@2.1.7': {}
+
+ '@eslint/plugin-kit@0.4.1':
+ dependencies:
+ '@eslint/core': 0.17.0
+ levn: 0.4.1
+
+ '@hono/node-server@1.19.14(hono@4.12.26)':
+ dependencies:
+ hono: 4.12.26
+
+ '@humanfs/core@0.19.2':
+ dependencies:
+ '@humanfs/types': 0.15.0
+
+ '@humanfs/node@0.16.8':
+ dependencies:
+ '@humanfs/core': 0.19.2
+ '@humanfs/types': 0.15.0
+ '@humanwhocodes/retry': 0.4.3
+
+ '@humanfs/types@0.15.0': {}
+
+ '@humanwhocodes/module-importer@1.0.1': {}
+
+ '@humanwhocodes/retry@0.4.3': {}
+
+ '@img/colour@1.1.0':
+ optional: true
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-s390x@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-wasm32@0.34.5':
+ dependencies:
+ '@emnapi/runtime': 1.11.1
+ optional: true
+
+ '@img/sharp-win32-arm64@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-ia32@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.34.5':
+ optional: true
+
+ '@isaacs/ttlcache@2.1.5': {}
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/remapping@2.3.5':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@lukeed/csprng@1.1.0': {}
+
+ '@lukeed/uuid@2.0.1':
+ dependencies:
+ '@lukeed/csprng': 1.1.0
+
+ '@mastra/core@1.45.0(ai@6.0.208(zod@4.4.3))(express@5.2.1)(zod@4.4.3)':
+ dependencies:
+ '@a2a-js/sdk': 0.3.13(express@5.2.1)
+ '@ai-sdk/provider-utils-v5': '@ai-sdk/provider-utils@3.0.25(zod@4.4.3)'
+ '@ai-sdk/provider-utils-v6': '@ai-sdk/provider-utils@4.0.27(zod@4.4.3)'
+ '@ai-sdk/provider-v5': '@ai-sdk/provider@2.0.3'
+ '@ai-sdk/provider-v6': '@ai-sdk/provider@3.0.10'
+ '@isaacs/ttlcache': 2.1.5
+ '@lukeed/uuid': 2.0.1
+ '@mastra/schema-compat': 1.3.0(zod@4.4.3)
+ '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3)
+ '@sindresorhus/slugify': 2.2.1
+ '@standard-schema/spec': 1.1.0
+ ajv: 8.20.0
+ chat: 4.31.0(ai@6.0.208(zod@4.4.3))(zod@4.4.3)
+ croner: 10.0.1
+ dotenv: 17.4.2
+ execa: 9.6.1
+ fastq: 1.20.1
+ gray-matter: 4.0.3
+ ignore: 7.0.5
+ jpeg-js: 0.4.4
+ json-schema: 0.4.0
+ lru-cache: 11.5.1
+ p-map: 7.0.4
+ p-retry: 7.1.1
+ picomatch: 4.0.4
+ posthog-node: 5.38.2
+ tokenx: 1.3.0
+ ws: 8.21.0
+ xxhash-wasm: 1.1.0
+ zod: 4.4.3
+ transitivePeerDependencies:
+ - '@bufbuild/protobuf'
+ - '@cfworker/json-schema'
+ - '@grpc/grpc-js'
+ - ai
+ - bufferutil
+ - express
+ - rxjs
+ - supports-color
+ - utf-8-validate
+
+ '@mastra/mcp@1.11.0(@mastra/core@1.45.0(ai@6.0.208(zod@4.4.3))(express@5.2.1)(zod@4.4.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.4.3)':
+ dependencies:
+ '@mastra/core': 1.45.0(ai@6.0.208(zod@4.4.3))(express@5.2.1)(zod@4.4.3)
+ '@modelcontextprotocol/ext-apps': 1.7.4(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.4.3)
+ '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3)
+ exit-hook: 5.1.0
+ fast-deep-equal: 3.1.3
+ transitivePeerDependencies:
+ - '@cfworker/json-schema'
+ - react
+ - react-dom
+ - supports-color
+ - zod
+
+ '@mastra/schema-compat@1.3.0(zod@4.4.3)':
+ dependencies:
+ json-schema-to-zod: 2.8.1
+ zod: 4.4.3
+ zod-from-json-schema: 0.5.3
+ zod-from-json-schema-v3: zod-from-json-schema@0.0.5
+ zod-to-json-schema: 3.25.2(zod@4.4.3)
+
+ '@modelcontextprotocol/ext-apps@1.7.4(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.4.3)':
+ dependencies:
+ '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3)
+ '@standard-schema/spec': 1.1.0
+ zod: 4.4.3
+ optionalDependencies:
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+
+ '@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)':
+ dependencies:
+ '@hono/node-server': 1.19.14(hono@4.12.26)
+ ajv: 8.20.0
+ ajv-formats: 3.0.1(ajv@8.20.0)
+ content-type: 1.0.5
+ cors: 2.8.6
+ cross-spawn: 7.0.6
+ eventsource: 3.0.7
+ eventsource-parser: 3.1.0
+ express: 5.2.1
+ express-rate-limit: 8.5.2(express@5.2.1)
+ hono: 4.12.26
+ jose: 6.2.3
+ json-schema-typed: 8.0.2
+ pkce-challenge: 5.0.1
+ raw-body: 3.0.2
+ zod: 4.4.3
+ zod-to-json-schema: 3.25.2(zod@4.4.3)
+ transitivePeerDependencies:
+ - supports-color
+
+ '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
+ dependencies:
+ '@emnapi/core': 1.10.0
+ '@emnapi/runtime': 1.10.0
+ '@tybys/wasm-util': 0.10.2
+ optional: true
+
+ '@next/env@16.2.9': {}
+
+ '@next/eslint-plugin-next@16.2.9':
+ dependencies:
+ fast-glob: 3.3.1
+
+ '@next/swc-darwin-arm64@16.2.9':
+ optional: true
+
+ '@next/swc-darwin-x64@16.2.9':
+ optional: true
+
+ '@next/swc-linux-arm64-gnu@16.2.9':
+ optional: true
+
+ '@next/swc-linux-arm64-musl@16.2.9':
+ optional: true
+
+ '@next/swc-linux-x64-gnu@16.2.9':
+ optional: true
+
+ '@next/swc-linux-x64-musl@16.2.9':
+ optional: true
+
+ '@next/swc-win32-arm64-msvc@16.2.9':
+ optional: true
+
+ '@next/swc-win32-x64-msvc@16.2.9':
+ optional: true
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.20.1
+
+ '@nolyfill/is-core-module@1.0.39': {}
+
+ '@opentelemetry/api@1.9.1': {}
+
+ '@posthog/core@1.35.3':
+ dependencies:
+ '@posthog/types': 1.390.2
+
+ '@posthog/types@1.390.2': {}
+
+ '@rtsao/scc@1.1.0': {}
+
+ '@sec-ant/readable-stream@0.4.1': {}
+
+ '@sindresorhus/merge-streams@4.0.0': {}
+
+ '@sindresorhus/slugify@2.2.1':
+ dependencies:
+ '@sindresorhus/transliterate': 1.6.0
+ escape-string-regexp: 5.0.0
+
+ '@sindresorhus/transliterate@1.6.0':
+ dependencies:
+ escape-string-regexp: 5.0.0
+
+ '@standard-schema/spec@1.1.0': {}
+
+ '@swc/helpers@0.5.15':
+ dependencies:
+ tslib: 2.8.1
+
+ '@tailwindcss/node@4.3.1':
+ dependencies:
+ '@jridgewell/remapping': 2.3.5
+ enhanced-resolve: 5.21.6
+ jiti: 2.7.0
+ lightningcss: 1.32.0
+ magic-string: 0.30.21
+ source-map-js: 1.2.1
+ tailwindcss: 4.3.1
+
+ '@tailwindcss/oxide-android-arm64@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-arm64@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-x64@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-freebsd-x64@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-musl@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-wasm32-wasi@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.3.1':
+ optional: true
+
+ '@tailwindcss/oxide@4.3.1':
+ optionalDependencies:
+ '@tailwindcss/oxide-android-arm64': 4.3.1
+ '@tailwindcss/oxide-darwin-arm64': 4.3.1
+ '@tailwindcss/oxide-darwin-x64': 4.3.1
+ '@tailwindcss/oxide-freebsd-x64': 4.3.1
+ '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.1
+ '@tailwindcss/oxide-linux-arm64-gnu': 4.3.1
+ '@tailwindcss/oxide-linux-arm64-musl': 4.3.1
+ '@tailwindcss/oxide-linux-x64-gnu': 4.3.1
+ '@tailwindcss/oxide-linux-x64-musl': 4.3.1
+ '@tailwindcss/oxide-wasm32-wasi': 4.3.1
+ '@tailwindcss/oxide-win32-arm64-msvc': 4.3.1
+ '@tailwindcss/oxide-win32-x64-msvc': 4.3.1
+
+ '@tailwindcss/postcss@4.3.1':
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ '@tailwindcss/node': 4.3.1
+ '@tailwindcss/oxide': 4.3.1
+ postcss: 8.5.15
+ tailwindcss: 4.3.1
+
+ '@tybys/wasm-util@0.10.2':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@types/better-sqlite3@7.6.13':
+ dependencies:
+ '@types/node': 20.19.43
+
+ '@types/debug@4.1.13':
+ dependencies:
+ '@types/ms': 2.1.0
+
+ '@types/estree@1.0.9': {}
+
+ '@types/json-schema@7.0.15': {}
+
+ '@types/json5@0.0.29': {}
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/ms@2.1.0': {}
+
+ '@types/node@18.19.130':
+ dependencies:
+ undici-types: 5.26.5
+
+ '@types/node@20.19.43':
+ dependencies:
+ undici-types: 6.21.0
+
+ '@types/react-dom@19.2.3(@types/react@19.2.17)':
+ dependencies:
+ '@types/react': 19.2.17
+
+ '@types/react@19.2.17':
+ dependencies:
+ csstype: 3.2.3
+
+ '@types/ssh2@1.15.5':
+ dependencies:
+ '@types/node': 18.19.130
+
+ '@types/unist@3.0.3': {}
+
+ '@typescript-eslint/eslint-plugin@8.61.1(@typescript-eslint/parser@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)':
+ dependencies:
+ '@eslint-community/regexpp': 4.12.2
+ '@typescript-eslint/parser': 8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ '@typescript-eslint/scope-manager': 8.61.1
+ '@typescript-eslint/type-utils': 8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ '@typescript-eslint/visitor-keys': 8.61.1
+ eslint: 9.39.4(jiti@2.7.0)
+ ignore: 7.0.5
+ natural-compare: 1.4.0
+ ts-api-utils: 2.5.0(typescript@5.9.3)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/parser@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/scope-manager': 8.61.1
+ '@typescript-eslint/types': 8.61.1
+ '@typescript-eslint/typescript-estree': 8.61.1(typescript@5.9.3)
+ '@typescript-eslint/visitor-keys': 8.61.1
+ debug: 4.4.3
+ eslint: 9.39.4(jiti@2.7.0)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/project-service@8.61.1(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@5.9.3)
+ '@typescript-eslint/types': 8.61.1
+ debug: 4.4.3
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/scope-manager@8.61.1':
+ dependencies:
+ '@typescript-eslint/types': 8.61.1
+ '@typescript-eslint/visitor-keys': 8.61.1
+
+ '@typescript-eslint/tsconfig-utils@8.61.1(typescript@5.9.3)':
+ dependencies:
+ typescript: 5.9.3
+
+ '@typescript-eslint/type-utils@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/types': 8.61.1
+ '@typescript-eslint/typescript-estree': 8.61.1(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ debug: 4.4.3
+ eslint: 9.39.4(jiti@2.7.0)
+ ts-api-utils: 2.5.0(typescript@5.9.3)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/types@8.61.1': {}
+
+ '@typescript-eslint/typescript-estree@8.61.1(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/project-service': 8.61.1(typescript@5.9.3)
+ '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@5.9.3)
+ '@typescript-eslint/types': 8.61.1
+ '@typescript-eslint/visitor-keys': 8.61.1
+ debug: 4.4.3
+ minimatch: 10.2.5
+ semver: 7.8.5
+ tinyglobby: 0.2.17
+ ts-api-utils: 2.5.0(typescript@5.9.3)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/utils@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0))
+ '@typescript-eslint/scope-manager': 8.61.1
+ '@typescript-eslint/types': 8.61.1
+ '@typescript-eslint/typescript-estree': 8.61.1(typescript@5.9.3)
+ eslint: 9.39.4(jiti@2.7.0)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/visitor-keys@8.61.1':
+ dependencies:
+ '@typescript-eslint/types': 8.61.1
+ eslint-visitor-keys: 5.0.1
+
+ '@unrs/resolver-binding-android-arm-eabi@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-android-arm64@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-darwin-arm64@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-darwin-x64@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-freebsd-x64@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-arm64-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-arm64-musl@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-loong64-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-loong64-musl@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-riscv64-musl@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-s390x-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-x64-gnu@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-linux-x64-musl@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-openharmony-arm64@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-wasm32-wasi@1.12.2':
+ dependencies:
+ '@emnapi/core': 1.10.0
+ '@emnapi/runtime': 1.10.0
+ '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
+ optional: true
+
+ '@unrs/resolver-binding-win32-arm64-msvc@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-win32-ia32-msvc@1.12.2':
+ optional: true
+
+ '@unrs/resolver-binding-win32-x64-msvc@1.12.2':
+ optional: true
+
+ '@vercel/oidc@3.2.0': {}
+
+ '@workflow/serde@4.1.0-beta.2': {}
+
+ accepts@2.0.0:
+ dependencies:
+ mime-types: 3.0.2
+ negotiator: 1.0.0
+
+ acorn-jsx@5.3.2(acorn@8.17.0):
+ dependencies:
+ acorn: 8.17.0
+
+ acorn@8.17.0: {}
+
+ ai@6.0.208(zod@4.4.3):
+ dependencies:
+ '@ai-sdk/gateway': 3.0.133(zod@4.4.3)
+ '@ai-sdk/provider': 3.0.10
+ '@ai-sdk/provider-utils': 4.0.30(zod@4.4.3)
+ '@opentelemetry/api': 1.9.1
+ zod: 4.4.3
+
+ ajv-formats@3.0.1(ajv@8.20.0):
+ optionalDependencies:
+ ajv: 8.20.0
+
+ ajv@6.15.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
+ ajv@8.20.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.1.2
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ argparse@1.0.10:
+ dependencies:
+ sprintf-js: 1.0.3
+
+ argparse@2.0.1: {}
+
+ aria-query@5.3.2: {}
+
+ array-buffer-byte-length@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ is-array-buffer: 3.0.5
+
+ array-includes@3.1.9:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-object-atoms: 1.1.2
+ get-intrinsic: 1.3.0
+ is-string: 1.1.1
+ math-intrinsics: 1.1.0
+
+ array.prototype.findlast@1.2.5:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ es-shim-unscopables: 1.1.0
+
+ array.prototype.findlastindex@1.2.6:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ es-shim-unscopables: 1.1.0
+
+ array.prototype.flat@1.3.3:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-shim-unscopables: 1.1.0
+
+ array.prototype.flatmap@1.3.3:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-shim-unscopables: 1.1.0
+
+ array.prototype.tosorted@1.1.4:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-shim-unscopables: 1.1.0
+
+ arraybuffer.prototype.slice@1.0.4:
+ dependencies:
+ array-buffer-byte-length: 1.0.2
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ is-array-buffer: 3.0.5
+
+ asn1@0.2.6:
+ dependencies:
+ safer-buffer: 2.1.2
+
+ ast-types-flow@0.0.8: {}
+
+ async-function@1.0.0: {}
+
+ available-typed-arrays@1.0.7:
+ dependencies:
+ possible-typed-array-names: 1.1.0
+
+ axe-core@4.12.1: {}
+
+ axobject-query@4.1.0: {}
+
+ bail@2.0.2: {}
+
+ balanced-match@1.0.2: {}
+
+ balanced-match@4.0.4: {}
+
+ base64-js@1.5.1: {}
+
+ baseline-browser-mapping@2.10.38: {}
+
+ bcrypt-pbkdf@1.0.2:
+ dependencies:
+ tweetnacl: 0.14.5
+
+ better-sqlite3@12.11.1:
+ dependencies:
+ bindings: 1.5.0
+ prebuild-install: 7.1.3
+
+ bindings@1.5.0:
+ dependencies:
+ file-uri-to-path: 1.0.0
+
+ bl@4.1.0:
+ dependencies:
+ buffer: 5.7.1
+ inherits: 2.0.4
+ readable-stream: 3.6.2
+
+ body-parser@2.3.0:
+ dependencies:
+ bytes: 3.1.2
+ content-type: 2.0.0
+ debug: 4.4.3
+ http-errors: 2.0.1
+ iconv-lite: 0.7.2
+ on-finished: 2.4.1
+ qs: 6.15.2
+ raw-body: 3.0.2
+ type-is: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ brace-expansion@1.1.15:
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
+ brace-expansion@5.0.6:
+ dependencies:
+ balanced-match: 4.0.4
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browserslist@4.28.2:
+ dependencies:
+ baseline-browser-mapping: 2.10.38
+ caniuse-lite: 1.0.30001799
+ electron-to-chromium: 1.5.376
+ node-releases: 2.0.48
+ update-browserslist-db: 1.2.3(browserslist@4.28.2)
+
+ buffer@5.7.1:
+ dependencies:
+ base64-js: 1.5.1
+ ieee754: 1.2.1
+
+ buildcheck@0.0.7:
+ optional: true
+
+ bytes@3.1.2: {}
+
+ call-bind-apply-helpers@1.0.2:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ call-bind@1.0.9:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ get-intrinsic: 1.3.0
+ set-function-length: 1.2.2
+
+ call-bound@1.0.4:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ get-intrinsic: 1.3.0
+
+ callsites@3.1.0: {}
+
+ caniuse-lite@1.0.30001799: {}
+
+ ccount@2.0.1: {}
+
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ character-entities@2.0.2: {}
+
+ chat@4.31.0(ai@6.0.208(zod@4.4.3))(zod@4.4.3):
+ dependencies:
+ '@workflow/serde': 4.1.0-beta.2
+ mdast-util-to-string: 4.0.0
+ remark-gfm: 4.0.1
+ remark-parse: 11.0.0
+ remark-stringify: 11.0.0
+ remend: 1.3.0
+ unified: 11.0.5
+ optionalDependencies:
+ ai: 6.0.208(zod@4.4.3)
+ zod: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ chownr@1.1.4: {}
+
+ client-only@0.0.1: {}
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ concat-map@0.0.1: {}
+
+ content-disposition@1.1.0: {}
+
+ content-type@1.0.5: {}
+
+ content-type@2.0.0: {}
+
+ convert-source-map@2.0.0: {}
+
+ cookie-signature@1.2.2: {}
+
+ cookie@0.7.2: {}
+
+ cors@2.8.6:
+ dependencies:
+ object-assign: 4.1.1
+ vary: 1.1.2
+
+ cpu-features@0.0.10:
+ dependencies:
+ buildcheck: 0.0.7
+ nan: 2.27.0
+ optional: true
+
+ croner@10.0.1: {}
+
+ cross-spawn@7.0.6:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ csstype@3.2.3: {}
+
+ damerau-levenshtein@1.0.8: {}
+
+ data-view-buffer@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ is-data-view: 1.0.2
+
+ data-view-byte-length@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ is-data-view: 1.0.2
+
+ data-view-byte-offset@1.0.1:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ is-data-view: 1.0.2
+
+ debug@3.2.7:
+ dependencies:
+ ms: 2.1.3
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ decode-named-character-reference@1.3.0:
+ dependencies:
+ character-entities: 2.0.2
+
+ decompress-response@6.0.0:
+ dependencies:
+ mimic-response: 3.1.0
+
+ deep-extend@0.6.0: {}
+
+ deep-is@0.1.4: {}
+
+ define-data-property@1.1.4:
+ dependencies:
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ define-properties@1.2.1:
+ dependencies:
+ define-data-property: 1.1.4
+ has-property-descriptors: 1.0.2
+ object-keys: 1.1.1
+
+ depd@2.0.0: {}
+
+ dequal@2.0.3: {}
+
+ detect-libc@2.1.2: {}
+
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
+ doctrine@2.1.0:
+ dependencies:
+ esutils: 2.0.3
+
+ dotenv@17.4.2: {}
+
+ dunder-proto@1.0.1:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ ee-first@1.1.1: {}
+
+ electron-to-chromium@1.5.376: {}
+
+ emoji-regex@9.2.2: {}
+
+ encodeurl@2.0.0: {}
+
+ end-of-stream@1.4.5:
+ dependencies:
+ once: 1.4.0
+
+ enhanced-resolve@5.21.6:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.3.3
+
+ es-abstract-get@1.0.0:
+ dependencies:
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ is-callable: 1.2.7
+ object-inspect: 1.13.4
+
+ es-abstract@1.24.2:
+ dependencies:
+ array-buffer-byte-length: 1.0.2
+ arraybuffer.prototype.slice: 1.0.4
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.9
+ 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.2
+ es-set-tostringtag: 2.1.0
+ es-to-primitive: 1.3.1
+ function.prototype.name: 1.2.0
+ 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.4
+ 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.4
+ 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.11
+ string.prototype.trimend: 1.0.10
+ 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.8
+ unbox-primitive: 1.1.0
+ which-typed-array: 1.1.22
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
+ es-iterator-helpers@1.3.3:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-set-tostringtag: 2.1.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.3.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
+ internal-slot: 1.1.0
+ iterator.prototype: 1.1.5
+ math-intrinsics: 1.1.0
+
+ es-object-atoms@1.1.2:
+ dependencies:
+ es-errors: 1.3.0
+
+ es-set-tostringtag@2.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.4
+
+ es-shim-unscopables@1.1.0:
+ dependencies:
+ hasown: 2.0.4
+
+ es-to-primitive@1.3.1:
+ dependencies:
+ es-abstract-get: 1.0.0
+ es-errors: 1.3.0
+ is-callable: 1.2.7
+ is-date-object: 1.1.0
+ is-symbol: 1.1.1
+
+ escalade@3.2.0: {}
+
+ escape-html@1.0.3: {}
+
+ escape-string-regexp@4.0.0: {}
+
+ escape-string-regexp@5.0.0: {}
+
+ eslint-config-next@16.2.9(@typescript-eslint/parser@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3):
+ dependencies:
+ '@next/eslint-plugin-next': 16.2.9
+ eslint: 9.39.4(jiti@2.7.0)
+ eslint-import-resolver-node: 0.3.10
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.7.0))
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.7.0))
+ eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4(jiti@2.7.0))
+ eslint-plugin-react: 7.37.5(eslint@9.39.4(jiti@2.7.0))
+ eslint-plugin-react-hooks: 7.1.1(eslint@9.39.4(jiti@2.7.0))
+ globals: 16.4.0
+ typescript-eslint: 8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ optionalDependencies:
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - '@typescript-eslint/parser'
+ - eslint-import-resolver-webpack
+ - eslint-plugin-import-x
+ - supports-color
+
+ eslint-import-resolver-node@0.3.10:
+ dependencies:
+ debug: 3.2.7
+ is-core-module: 2.16.2
+ resolve: 2.0.0-next.7
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.7.0)):
+ dependencies:
+ '@nolyfill/is-core-module': 1.0.39
+ debug: 4.4.3
+ eslint: 9.39.4(jiti@2.7.0)
+ get-tsconfig: 4.14.0
+ is-bun-module: 2.0.0
+ stable-hash: 0.0.5
+ tinyglobby: 0.2.17
+ unrs-resolver: 1.12.2
+ optionalDependencies:
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.7.0))
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-module-utils@2.13.0(@typescript-eslint/parser@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.7.0)):
+ dependencies:
+ debug: 3.2.7
+ optionalDependencies:
+ '@typescript-eslint/parser': 8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ eslint: 9.39.4(jiti@2.7.0)
+ eslint-import-resolver-node: 0.3.10
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.7.0))
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.7.0)):
+ dependencies:
+ '@rtsao/scc': 1.1.0
+ array-includes: 3.1.9
+ array.prototype.findlastindex: 1.2.6
+ array.prototype.flat: 1.3.3
+ array.prototype.flatmap: 1.3.3
+ debug: 3.2.7
+ doctrine: 2.1.0
+ eslint: 9.39.4(jiti@2.7.0)
+ eslint-import-resolver-node: 0.3.10
+ eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.7.0))
+ hasown: 2.0.4
+ is-core-module: 2.16.2
+ is-glob: 4.0.3
+ minimatch: 3.1.5
+ object.fromentries: 2.0.8
+ object.groupby: 1.0.3
+ object.values: 1.2.1
+ semver: 6.3.1
+ string.prototype.trimend: 1.0.10
+ tsconfig-paths: 3.15.0
+ optionalDependencies:
+ '@typescript-eslint/parser': 8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
+
+ eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4(jiti@2.7.0)):
+ dependencies:
+ aria-query: 5.3.2
+ array-includes: 3.1.9
+ array.prototype.flatmap: 1.3.3
+ ast-types-flow: 0.0.8
+ axe-core: 4.12.1
+ axobject-query: 4.1.0
+ damerau-levenshtein: 1.0.8
+ emoji-regex: 9.2.2
+ eslint: 9.39.4(jiti@2.7.0)
+ hasown: 2.0.4
+ jsx-ast-utils: 3.3.5
+ language-tags: 1.0.9
+ minimatch: 3.1.5
+ object.fromentries: 2.0.8
+ safe-regex-test: 1.1.0
+ string.prototype.includes: 2.0.1
+
+ eslint-plugin-react-hooks@7.1.1(eslint@9.39.4(jiti@2.7.0)):
+ dependencies:
+ '@babel/core': 7.29.7
+ '@babel/parser': 7.29.7
+ eslint: 9.39.4(jiti@2.7.0)
+ hermes-parser: 0.25.1
+ zod: 4.4.3
+ zod-validation-error: 4.0.2(zod@4.4.3)
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-plugin-react@7.37.5(eslint@9.39.4(jiti@2.7.0)):
+ dependencies:
+ array-includes: 3.1.9
+ array.prototype.findlast: 1.2.5
+ array.prototype.flatmap: 1.3.3
+ array.prototype.tosorted: 1.1.4
+ doctrine: 2.1.0
+ es-iterator-helpers: 1.3.3
+ eslint: 9.39.4(jiti@2.7.0)
+ estraverse: 5.3.0
+ hasown: 2.0.4
+ jsx-ast-utils: 3.3.5
+ minimatch: 3.1.5
+ object.entries: 1.1.9
+ object.fromentries: 2.0.8
+ object.values: 1.2.1
+ prop-types: 15.8.1
+ resolve: 2.0.0-next.7
+ semver: 6.3.1
+ string.prototype.matchall: 4.0.12
+ string.prototype.repeat: 1.0.0
+
+ eslint-scope@8.4.0:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+
+ eslint-visitor-keys@3.4.3: {}
+
+ eslint-visitor-keys@4.2.1: {}
+
+ eslint-visitor-keys@5.0.1: {}
+
+ eslint@9.39.4(jiti@2.7.0):
+ dependencies:
+ '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0))
+ '@eslint-community/regexpp': 4.12.2
+ '@eslint/config-array': 0.21.2
+ '@eslint/config-helpers': 0.4.2
+ '@eslint/core': 0.17.0
+ '@eslint/eslintrc': 3.3.5
+ '@eslint/js': 9.39.4
+ '@eslint/plugin-kit': 0.4.1
+ '@humanfs/node': 0.16.8
+ '@humanwhocodes/module-importer': 1.0.1
+ '@humanwhocodes/retry': 0.4.3
+ '@types/estree': 1.0.9
+ ajv: 6.15.0
+ chalk: 4.1.2
+ cross-spawn: 7.0.6
+ debug: 4.4.3
+ escape-string-regexp: 4.0.0
+ eslint-scope: 8.4.0
+ eslint-visitor-keys: 4.2.1
+ espree: 10.4.0
+ esquery: 1.7.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 8.0.0
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ ignore: 5.3.2
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ json-stable-stringify-without-jsonify: 1.0.1
+ lodash.merge: 4.6.2
+ minimatch: 3.1.5
+ natural-compare: 1.4.0
+ optionator: 0.9.4
+ optionalDependencies:
+ jiti: 2.7.0
+ transitivePeerDependencies:
+ - supports-color
+
+ espree@10.4.0:
+ dependencies:
+ acorn: 8.17.0
+ acorn-jsx: 5.3.2(acorn@8.17.0)
+ eslint-visitor-keys: 4.2.1
+
+ esprima@4.0.1: {}
+
+ esquery@1.7.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ estraverse@5.3.0: {}
+
+ esutils@2.0.3: {}
+
+ etag@1.8.1: {}
+
+ eventsource-parser@3.1.0: {}
+
+ eventsource@3.0.7:
+ dependencies:
+ eventsource-parser: 3.1.0
+
+ execa@9.6.1:
+ dependencies:
+ '@sindresorhus/merge-streams': 4.0.0
+ cross-spawn: 7.0.6
+ figures: 6.1.0
+ get-stream: 9.0.1
+ human-signals: 8.0.1
+ is-plain-obj: 4.1.0
+ is-stream: 4.0.1
+ npm-run-path: 6.0.0
+ pretty-ms: 9.3.0
+ signal-exit: 4.1.0
+ strip-final-newline: 4.0.0
+ yoctocolors: 2.1.2
+
+ exit-hook@5.1.0: {}
+
+ expand-template@2.0.3: {}
+
+ express-rate-limit@8.5.2(express@5.2.1):
+ dependencies:
+ express: 5.2.1
+ ip-address: 10.2.0
+
+ express@5.2.1:
+ dependencies:
+ accepts: 2.0.0
+ body-parser: 2.3.0
+ content-disposition: 1.1.0
+ content-type: 1.0.5
+ cookie: 0.7.2
+ cookie-signature: 1.2.2
+ debug: 4.4.3
+ depd: 2.0.0
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ etag: 1.8.1
+ finalhandler: 2.1.1
+ fresh: 2.0.0
+ http-errors: 2.0.1
+ merge-descriptors: 2.0.0
+ mime-types: 3.0.2
+ on-finished: 2.4.1
+ once: 1.4.0
+ parseurl: 1.3.3
+ proxy-addr: 2.0.7
+ qs: 6.15.2
+ range-parser: 1.2.1
+ router: 2.2.0
+ send: 1.2.1
+ serve-static: 2.2.1
+ statuses: 2.0.2
+ type-is: 2.1.0
+ vary: 1.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ extend-shallow@2.0.1:
+ dependencies:
+ is-extendable: 0.1.1
+
+ extend@3.0.2: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-glob@3.3.1:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-json-stable-stringify@2.1.0: {}
+
+ fast-levenshtein@2.0.6: {}
+
+ fast-uri@3.1.2: {}
+
+ fastq@1.20.1:
+ dependencies:
+ reusify: 1.1.0
+
+ fdir@6.5.0(picomatch@4.0.4):
+ optionalDependencies:
+ picomatch: 4.0.4
+
+ figures@6.1.0:
+ dependencies:
+ is-unicode-supported: 2.1.0
+
+ file-entry-cache@8.0.0:
+ dependencies:
+ flat-cache: 4.0.1
+
+ file-uri-to-path@1.0.0: {}
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ finalhandler@2.1.1:
+ dependencies:
+ debug: 4.4.3
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ on-finished: 2.4.1
+ parseurl: 1.3.3
+ statuses: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ find-up@5.0.0:
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+
+ flat-cache@4.0.1:
+ dependencies:
+ flatted: 3.4.2
+ keyv: 4.5.4
+
+ flatted@3.4.2: {}
+
+ for-each@0.3.5:
+ dependencies:
+ is-callable: 1.2.7
+
+ forwarded@0.2.0: {}
+
+ fresh@2.0.0: {}
+
+ fs-constants@1.0.0: {}
+
+ function-bind@1.1.2: {}
+
+ function.prototype.name@1.2.0:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ functions-have-names: 1.2.3
+ has-property-descriptors: 1.0.2
+ hasown: 2.0.4
+ is-callable: 1.2.7
+ is-document.all: 1.0.0
+
+ functions-have-names@1.2.3: {}
+
+ generator-function@2.0.1: {}
+
+ gensync@1.0.0-beta.2: {}
+
+ get-intrinsic@1.3.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.4
+ math-intrinsics: 1.1.0
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.1.2
+
+ get-stream@9.0.1:
+ dependencies:
+ '@sec-ant/readable-stream': 0.4.1
+ is-stream: 4.0.1
+
+ get-symbol-description@1.1.0:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+
+ get-tsconfig@4.14.0:
+ dependencies:
+ resolve-pkg-maps: 1.0.0
+
+ github-from-package@0.0.0: {}
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ globals@14.0.0: {}
+
+ globals@16.4.0: {}
+
+ globalthis@1.0.4:
+ dependencies:
+ define-properties: 1.2.1
+ gopd: 1.2.0
+
+ gopd@1.2.0: {}
+
+ graceful-fs@4.2.11: {}
+
+ gray-matter@4.0.3:
+ dependencies:
+ js-yaml: 3.14.2
+ kind-of: 6.0.3
+ section-matter: 1.0.0
+ strip-bom-string: 1.0.0
+
+ has-bigints@1.1.0: {}
+
+ has-flag@4.0.0: {}
+
+ has-property-descriptors@1.0.2:
+ dependencies:
+ es-define-property: 1.0.1
+
+ has-proto@1.2.0:
+ dependencies:
+ dunder-proto: 1.0.1
+
+ has-symbols@1.1.0: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.1.0
+
+ hasown@2.0.4:
+ dependencies:
+ function-bind: 1.1.2
+
+ hermes-estree@0.25.1: {}
+
+ hermes-parser@0.25.1:
+ dependencies:
+ hermes-estree: 0.25.1
+
+ hono@4.12.26: {}
+
+ 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
+
+ human-signals@8.0.1: {}
+
+ iconv-lite@0.7.2:
+ dependencies:
+ safer-buffer: 2.1.2
+
+ ieee754@1.2.1: {}
+
+ ignore@5.3.2: {}
+
+ ignore@7.0.5: {}
+
+ import-fresh@3.3.1:
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+
+ imurmurhash@0.1.4: {}
+
+ inherits@2.0.4: {}
+
+ ini@1.3.8: {}
+
+ internal-slot@1.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ hasown: 2.0.4
+ side-channel: 1.1.1
+
+ ip-address@10.2.0: {}
+
+ ipaddr.js@1.9.1: {}
+
+ is-array-buffer@3.0.5:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ get-intrinsic: 1.3.0
+
+ is-async-function@2.1.1:
+ dependencies:
+ async-function: 1.0.0
+ call-bound: 1.0.4
+ get-proto: 1.0.1
+ has-tostringtag: 1.0.2
+ safe-regex-test: 1.1.0
+
+ is-bigint@1.1.0:
+ dependencies:
+ has-bigints: 1.1.0
+
+ is-boolean-object@1.2.2:
+ dependencies:
+ call-bound: 1.0.4
+ has-tostringtag: 1.0.2
+
+ is-bun-module@2.0.0:
+ dependencies:
+ semver: 7.8.5
+
+ is-callable@1.2.7: {}
+
+ is-core-module@2.16.2:
+ dependencies:
+ hasown: 2.0.4
+
+ is-data-view@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ get-intrinsic: 1.3.0
+ is-typed-array: 1.1.15
+
+ is-date-object@1.1.0:
+ dependencies:
+ call-bound: 1.0.4
+ has-tostringtag: 1.0.2
+
+ is-document.all@1.0.0:
+ dependencies:
+ call-bound: 1.0.4
+
+ is-extendable@0.1.1: {}
+
+ is-extglob@2.1.1: {}
+
+ is-finalizationregistry@1.1.1:
+ dependencies:
+ call-bound: 1.0.4
+
+ is-generator-function@1.1.2:
+ dependencies:
+ call-bound: 1.0.4
+ generator-function: 2.0.1
+ get-proto: 1.0.1
+ has-tostringtag: 1.0.2
+ safe-regex-test: 1.1.0
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-map@2.0.3: {}
+
+ is-negative-zero@2.0.3: {}
+
+ is-network-error@1.3.2: {}
+
+ is-number-object@1.1.1:
+ dependencies:
+ call-bound: 1.0.4
+ has-tostringtag: 1.0.2
+
+ is-number@7.0.0: {}
+
+ is-plain-obj@4.1.0: {}
+
+ is-promise@4.0.0: {}
+
+ is-regex@1.2.1:
+ dependencies:
+ call-bound: 1.0.4
+ gopd: 1.2.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.4
+
+ is-set@2.0.3: {}
+
+ is-shared-array-buffer@1.0.4:
+ dependencies:
+ call-bound: 1.0.4
+
+ is-stream@4.0.1: {}
+
+ is-string@1.1.1:
+ dependencies:
+ call-bound: 1.0.4
+ has-tostringtag: 1.0.2
+
+ is-symbol@1.1.1:
+ dependencies:
+ call-bound: 1.0.4
+ has-symbols: 1.1.0
+ safe-regex-test: 1.1.0
+
+ is-typed-array@1.1.15:
+ dependencies:
+ which-typed-array: 1.1.22
+
+ is-unicode-supported@2.1.0: {}
+
+ is-weakmap@2.0.2: {}
+
+ is-weakref@1.1.1:
+ dependencies:
+ call-bound: 1.0.4
+
+ is-weakset@2.0.4:
+ dependencies:
+ call-bound: 1.0.4
+ get-intrinsic: 1.3.0
+
+ isarray@2.0.5: {}
+
+ isexe@2.0.0: {}
+
+ iterator.prototype@1.1.5:
+ dependencies:
+ define-data-property: 1.1.4
+ es-object-atoms: 1.1.2
+ get-intrinsic: 1.3.0
+ get-proto: 1.0.1
+ has-symbols: 1.1.0
+ set-function-name: 2.0.2
+
+ jiti@2.7.0: {}
+
+ jose@6.2.3: {}
+
+ jpeg-js@0.4.4: {}
+
+ js-tokens@4.0.0: {}
+
+ js-yaml@3.14.2:
+ dependencies:
+ argparse: 1.0.10
+ esprima: 4.0.1
+
+ js-yaml@4.2.0:
+ dependencies:
+ argparse: 2.0.1
+
+ jsesc@3.1.0: {}
+
+ json-buffer@3.0.1: {}
+
+ json-schema-to-zod@2.8.1: {}
+
+ json-schema-traverse@0.4.1: {}
+
+ json-schema-traverse@1.0.0: {}
+
+ json-schema-typed@8.0.2: {}
+
+ json-schema@0.4.0: {}
+
+ json-stable-stringify-without-jsonify@1.0.1: {}
+
+ json5@1.0.2:
+ dependencies:
+ minimist: 1.2.8
+
+ json5@2.2.3: {}
+
+ jsx-ast-utils@3.3.5:
+ dependencies:
+ array-includes: 3.1.9
+ array.prototype.flat: 1.3.3
+ object.assign: 4.1.7
+ object.values: 1.2.1
+
+ keyv@4.5.4:
+ dependencies:
+ json-buffer: 3.0.1
+
+ kind-of@6.0.3: {}
+
+ language-subtag-registry@0.3.23: {}
+
+ language-tags@1.0.9:
+ dependencies:
+ language-subtag-registry: 0.3.23
+
+ levn@0.4.1:
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+
+ lightningcss-android-arm64@1.32.0:
+ optional: true
+
+ lightningcss-darwin-arm64@1.32.0:
+ optional: true
+
+ lightningcss-darwin-x64@1.32.0:
+ optional: true
+
+ lightningcss-freebsd-x64@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.32.0:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.32.0:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.32.0:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.32.0:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.32.0:
+ optional: true
+
+ lightningcss@1.32.0:
+ dependencies:
+ detect-libc: 2.1.2
+ optionalDependencies:
+ lightningcss-android-arm64: 1.32.0
+ lightningcss-darwin-arm64: 1.32.0
+ lightningcss-darwin-x64: 1.32.0
+ lightningcss-freebsd-x64: 1.32.0
+ lightningcss-linux-arm-gnueabihf: 1.32.0
+ lightningcss-linux-arm64-gnu: 1.32.0
+ lightningcss-linux-arm64-musl: 1.32.0
+ lightningcss-linux-x64-gnu: 1.32.0
+ lightningcss-linux-x64-musl: 1.32.0
+ lightningcss-win32-arm64-msvc: 1.32.0
+ lightningcss-win32-x64-msvc: 1.32.0
+
+ locate-path@6.0.0:
+ dependencies:
+ p-locate: 5.0.0
+
+ lodash.merge@4.6.2: {}
+
+ longest-streak@3.1.0: {}
+
+ loose-envify@1.4.0:
+ dependencies:
+ js-tokens: 4.0.0
+
+ lru-cache@11.5.1: {}
+
+ lru-cache@5.1.1:
+ dependencies:
+ yallist: 3.1.1
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ markdown-table@3.0.4: {}
+
+ math-intrinsics@1.1.0: {}
+
+ mdast-util-find-and-replace@3.0.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ escape-string-regexp: 5.0.0
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ mdast-util-from-markdown@2.0.3:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ mdast-util-to-string: 4.0.0
+ micromark: 4.0.2
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-decode-string: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ unist-util-stringify-position: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-find-and-replace: 3.0.2
+ micromark-util-character: 2.1.1
+
+ mdast-util-gfm-footnote@2.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ micromark-util-normalize-identifier: 2.0.1
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-table@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ markdown-table: 3.0.4
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm@3.1.0:
+ dependencies:
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-gfm-autolink-literal: 2.0.1
+ mdast-util-gfm-footnote: 2.1.0
+ mdast-util-gfm-strikethrough: 2.0.0
+ mdast-util-gfm-table: 2.0.0
+ mdast-util-gfm-task-list-item: 2.0.0
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-phrasing@4.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ unist-util-is: 6.0.1
+
+ mdast-util-to-markdown@2.1.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ longest-streak: 3.1.0
+ mdast-util-phrasing: 4.1.0
+ mdast-util-to-string: 4.0.0
+ micromark-util-classify-character: 2.0.1
+ micromark-util-decode-string: 2.0.1
+ unist-util-visit: 5.1.0
+ zwitch: 2.0.4
+
+ mdast-util-to-string@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+
+ media-typer@1.1.0: {}
+
+ merge-descriptors@2.0.0: {}
+
+ merge2@1.4.1: {}
+
+ micromark-core-commonmark@2.0.3:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-factory-destination: 2.0.1
+ micromark-factory-label: 2.0.1
+ micromark-factory-space: 2.0.1
+ micromark-factory-title: 2.0.1
+ micromark-factory-whitespace: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-html-tag-name: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-footnote@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-table@2.1.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm@3.0.0:
+ dependencies:
+ micromark-extension-gfm-autolink-literal: 2.1.0
+ micromark-extension-gfm-footnote: 2.1.0
+ micromark-extension-gfm-strikethrough: 2.1.0
+ micromark-extension-gfm-table: 2.1.1
+ micromark-extension-gfm-tagfilter: 2.0.0
+ micromark-extension-gfm-task-list-item: 2.1.0
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-destination@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-label@2.0.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-space@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-title@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-whitespace@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-chunked@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-classify-character@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-combine-extensions@2.0.1:
+ dependencies:
+ micromark-util-chunked: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-decode-string@2.0.1:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ micromark-util-character: 2.1.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-encode@2.0.1: {}
+
+ micromark-util-html-tag-name@2.0.1: {}
+
+ micromark-util-normalize-identifier@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-resolve-all@2.0.1:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-util-sanitize-uri@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-subtokenize@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.2: {}
+
+ micromark@4.0.2:
+ dependencies:
+ '@types/debug': 4.1.13
+ debug: 4.4.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-encode: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.2
+
+ mime-db@1.54.0: {}
+
+ mime-types@3.0.2:
+ dependencies:
+ mime-db: 1.54.0
+
+ mimic-response@3.1.0: {}
+
+ minimatch@10.2.5:
+ dependencies:
+ brace-expansion: 5.0.6
+
+ minimatch@3.1.5:
+ dependencies:
+ brace-expansion: 1.1.15
+
+ minimist@1.2.8: {}
+
+ mkdirp-classic@0.5.3: {}
+
+ ms@2.1.3: {}
+
+ nan@2.27.0:
+ optional: true
+
+ nanoid@3.3.13: {}
+
+ napi-build-utils@2.0.0: {}
+
+ napi-postinstall@0.3.4: {}
+
+ natural-compare@1.4.0: {}
+
+ negotiator@1.0.0: {}
+
+ next@16.2.9(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
+ dependencies:
+ '@next/env': 16.2.9
+ '@swc/helpers': 0.5.15
+ baseline-browser-mapping: 2.10.38
+ caniuse-lite: 1.0.30001799
+ postcss: 8.4.31
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+ styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.4)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 16.2.9
+ '@next/swc-darwin-x64': 16.2.9
+ '@next/swc-linux-arm64-gnu': 16.2.9
+ '@next/swc-linux-arm64-musl': 16.2.9
+ '@next/swc-linux-x64-gnu': 16.2.9
+ '@next/swc-linux-x64-musl': 16.2.9
+ '@next/swc-win32-arm64-msvc': 16.2.9
+ '@next/swc-win32-x64-msvc': 16.2.9
+ '@opentelemetry/api': 1.9.1
+ sharp: 0.34.5
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+
+ node-abi@3.92.0:
+ dependencies:
+ semver: 7.8.5
+
+ node-exports-info@1.6.0:
+ dependencies:
+ array.prototype.flatmap: 1.3.3
+ es-errors: 1.3.0
+ object.entries: 1.1.9
+ semver: 6.3.1
+
+ node-releases@2.0.48: {}
+
+ npm-run-path@6.0.0:
+ dependencies:
+ path-key: 4.0.0
+ unicorn-magic: 0.3.0
+
+ object-assign@4.1.1: {}
+
+ object-inspect@1.13.4: {}
+
+ object-keys@1.1.1: {}
+
+ object.assign@4.1.7:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-object-atoms: 1.1.2
+ has-symbols: 1.1.0
+ object-keys: 1.1.1
+
+ object.entries@1.1.9:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-object-atoms: 1.1.2
+
+ object.fromentries@2.0.8:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-object-atoms: 1.1.2
+
+ object.groupby@1.0.3:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+
+ object.values@1.2.1:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-object-atoms: 1.1.2
+
+ on-finished@2.4.1:
+ dependencies:
+ ee-first: 1.1.1
+
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ optionator@0.9.4:
+ dependencies:
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ word-wrap: 1.2.5
+
+ own-keys@1.0.1:
+ dependencies:
+ get-intrinsic: 1.3.0
+ object-keys: 1.1.1
+ safe-push-apply: 1.0.0
+
+ p-limit@3.1.0:
+ dependencies:
+ yocto-queue: 0.1.0
+
+ p-locate@5.0.0:
+ dependencies:
+ p-limit: 3.1.0
+
+ p-map@7.0.4: {}
+
+ p-retry@7.1.1:
+ dependencies:
+ is-network-error: 1.3.2
+
+ parent-module@1.0.1:
+ dependencies:
+ callsites: 3.1.0
+
+ parse-ms@4.0.0: {}
+
+ parseurl@1.3.3: {}
+
+ path-exists@4.0.0: {}
+
+ path-key@3.1.1: {}
+
+ path-key@4.0.0: {}
+
+ path-parse@1.0.7: {}
+
+ path-to-regexp@8.4.2: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.2: {}
+
+ picomatch@4.0.4: {}
+
+ pkce-challenge@5.0.1: {}
+
+ possible-typed-array-names@1.1.0: {}
+
+ postcss@8.4.31:
+ dependencies:
+ nanoid: 3.3.13
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ postcss@8.5.15:
+ dependencies:
+ nanoid: 3.3.13
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ posthog-node@5.38.2:
+ dependencies:
+ '@posthog/core': 1.35.3
+
+ prebuild-install@7.1.3:
+ dependencies:
+ detect-libc: 2.1.2
+ expand-template: 2.0.3
+ github-from-package: 0.0.0
+ minimist: 1.2.8
+ mkdirp-classic: 0.5.3
+ napi-build-utils: 2.0.0
+ node-abi: 3.92.0
+ pump: 3.0.4
+ rc: 1.2.8
+ simple-get: 4.0.1
+ tar-fs: 2.1.4
+ tunnel-agent: 0.6.0
+
+ prelude-ls@1.2.1: {}
+
+ pretty-ms@9.3.0:
+ dependencies:
+ parse-ms: 4.0.0
+
+ prop-types@15.8.1:
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ react-is: 16.13.1
+
+ proxy-addr@2.0.7:
+ dependencies:
+ forwarded: 0.2.0
+ ipaddr.js: 1.9.1
+
+ pump@3.0.4:
+ dependencies:
+ end-of-stream: 1.4.5
+ once: 1.4.0
+
+ punycode@2.3.1: {}
+
+ qs@6.15.2:
+ dependencies:
+ side-channel: 1.1.1
+
+ queue-microtask@1.2.3: {}
+
+ range-parser@1.2.1: {}
+
+ raw-body@3.0.2:
+ dependencies:
+ bytes: 3.1.2
+ http-errors: 2.0.1
+ iconv-lite: 0.7.2
+ unpipe: 1.0.0
+
+ rc@1.2.8:
+ dependencies:
+ deep-extend: 0.6.0
+ ini: 1.3.8
+ minimist: 1.2.8
+ strip-json-comments: 2.0.1
+
+ react-dom@19.2.4(react@19.2.4):
+ dependencies:
+ react: 19.2.4
+ scheduler: 0.27.0
+
+ react-is@16.13.1: {}
+
+ react@19.2.4: {}
+
+ readable-stream@3.6.2:
+ dependencies:
+ inherits: 2.0.4
+ string_decoder: 1.3.0
+ util-deprecate: 1.0.2
+
+ reflect.getprototypeof@1.0.10:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ get-intrinsic: 1.3.0
+ get-proto: 1.0.1
+ which-builtin-type: 1.2.1
+
+ regexp.prototype.flags@1.5.4:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-errors: 1.3.0
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ set-function-name: 2.0.2
+
+ remark-gfm@4.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-gfm: 3.1.0
+ micromark-extension-gfm: 3.0.0
+ remark-parse: 11.0.0
+ remark-stringify: 11.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-parse@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.3
+ micromark-util-types: 2.0.2
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-stringify@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-to-markdown: 2.1.2
+ unified: 11.0.5
+
+ remend@1.3.0: {}
+
+ require-from-string@2.0.2: {}
+
+ resolve-from@4.0.0: {}
+
+ resolve-pkg-maps@1.0.0: {}
+
+ resolve@2.0.0-next.7:
+ dependencies:
+ es-errors: 1.3.0
+ is-core-module: 2.16.2
+ node-exports-info: 1.6.0
+ object-keys: 1.1.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ reusify@1.1.0: {}
+
+ router@2.2.0:
+ dependencies:
+ debug: 4.4.3
+ depd: 2.0.0
+ is-promise: 4.0.0
+ parseurl: 1.3.3
+ path-to-regexp: 8.4.2
+ transitivePeerDependencies:
+ - supports-color
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ safe-array-concat@1.1.4:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ get-intrinsic: 1.3.0
+ has-symbols: 1.1.0
+ isarray: 2.0.5
+
+ safe-buffer@5.2.1: {}
+
+ safe-push-apply@1.0.0:
+ dependencies:
+ es-errors: 1.3.0
+ isarray: 2.0.5
+
+ safe-regex-test@1.1.0:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ is-regex: 1.2.1
+
+ safer-buffer@2.1.2: {}
+
+ scheduler@0.27.0: {}
+
+ section-matter@1.0.0:
+ dependencies:
+ extend-shallow: 2.0.1
+ kind-of: 6.0.3
+
+ semver@6.3.1: {}
+
+ semver@7.8.5: {}
+
+ 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
+ transitivePeerDependencies:
+ - supports-color
+
+ serve-static@2.2.1:
+ dependencies:
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ parseurl: 1.3.3
+ send: 1.2.1
+ transitivePeerDependencies:
+ - supports-color
+
+ 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.3.0
+ gopd: 1.2.0
+ has-property-descriptors: 1.0.2
+
+ set-function-name@2.0.2:
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ functions-have-names: 1.2.3
+ has-property-descriptors: 1.0.2
+
+ set-proto@1.0.0:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+
+ setprototypeof@1.2.0: {}
+
+ sharp@0.34.5:
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.8.5
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.34.5
+ '@img/sharp-darwin-x64': 0.34.5
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ '@img/sharp-linux-arm': 0.34.5
+ '@img/sharp-linux-arm64': 0.34.5
+ '@img/sharp-linux-ppc64': 0.34.5
+ '@img/sharp-linux-riscv64': 0.34.5
+ '@img/sharp-linux-s390x': 0.34.5
+ '@img/sharp-linux-x64': 0.34.5
+ '@img/sharp-linuxmusl-arm64': 0.34.5
+ '@img/sharp-linuxmusl-x64': 0.34.5
+ '@img/sharp-wasm32': 0.34.5
+ '@img/sharp-win32-arm64': 0.34.5
+ '@img/sharp-win32-ia32': 0.34.5
+ '@img/sharp-win32-x64': 0.34.5
+ optional: true
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ side-channel-list@1.0.1:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-map@1.0.1:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-weakmap@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-map: 1.0.1
+
+ side-channel@1.1.1:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-list: 1.0.1
+ side-channel-map: 1.0.1
+ side-channel-weakmap: 1.0.2
+
+ signal-exit@4.1.0: {}
+
+ simple-concat@1.0.1: {}
+
+ simple-get@4.0.1:
+ dependencies:
+ decompress-response: 6.0.0
+ once: 1.4.0
+ simple-concat: 1.0.1
+
+ source-map-js@1.2.1: {}
+
+ sprintf-js@1.0.3: {}
+
+ ssh2@1.17.0:
+ dependencies:
+ asn1: 0.2.6
+ bcrypt-pbkdf: 1.0.2
+ optionalDependencies:
+ cpu-features: 0.0.10
+ nan: 2.27.0
+
+ stable-hash@0.0.5: {}
+
+ statuses@2.0.2: {}
+
+ stop-iteration-iterator@1.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ internal-slot: 1.1.0
+
+ string.prototype.includes@2.0.1:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+
+ string.prototype.matchall@4.0.12:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ get-intrinsic: 1.3.0
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ internal-slot: 1.1.0
+ regexp.prototype.flags: 1.5.4
+ set-function-name: 2.0.2
+ side-channel: 1.1.1
+
+ string.prototype.repeat@1.0.0:
+ dependencies:
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+
+ string.prototype.trim@1.2.11:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-data-property: 1.1.4
+ define-properties: 1.2.1
+ es-abstract: 1.24.2
+ es-object-atoms: 1.1.2
+ has-property-descriptors: 1.0.2
+ safe-regex-test: 1.1.0
+
+ string.prototype.trimend@1.0.10:
+ dependencies:
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ define-properties: 1.2.1
+ es-object-atoms: 1.1.2
+
+ string.prototype.trimstart@1.0.8:
+ dependencies:
+ call-bind: 1.0.9
+ define-properties: 1.2.1
+ es-object-atoms: 1.1.2
+
+ string_decoder@1.3.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ strip-bom-string@1.0.0: {}
+
+ strip-bom@3.0.0: {}
+
+ strip-final-newline@4.0.0: {}
+
+ strip-json-comments@2.0.1: {}
+
+ strip-json-comments@3.1.1: {}
+
+ styled-jsx@5.1.6(@babel/core@7.29.7)(react@19.2.4):
+ dependencies:
+ client-only: 0.0.1
+ react: 19.2.4
+ optionalDependencies:
+ '@babel/core': 7.29.7
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-preserve-symlinks-flag@1.0.0: {}
+
+ tailwindcss@4.3.1: {}
+
+ tapable@2.3.3: {}
+
+ tar-fs@2.1.4:
+ dependencies:
+ chownr: 1.1.4
+ mkdirp-classic: 0.5.3
+ pump: 3.0.4
+ tar-stream: 2.2.0
+
+ tar-stream@2.2.0:
+ dependencies:
+ bl: 4.1.0
+ end-of-stream: 1.4.5
+ fs-constants: 1.0.0
+ inherits: 2.0.4
+ readable-stream: 3.6.2
+
+ tinyglobby@0.2.17:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.4)
+ picomatch: 4.0.4
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ toidentifier@1.0.1: {}
+
+ tokenx@1.3.0: {}
+
+ trough@2.2.0: {}
+
+ ts-api-utils@2.5.0(typescript@5.9.3):
+ dependencies:
+ typescript: 5.9.3
+
+ tsconfig-paths@3.15.0:
+ dependencies:
+ '@types/json5': 0.0.29
+ json5: 1.0.2
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+
+ tslib@2.8.1: {}
+
+ tunnel-agent@0.6.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ tweetnacl@0.14.5: {}
+
+ type-check@0.4.0:
+ dependencies:
+ prelude-ls: 1.2.1
+
+ type-is@2.1.0:
+ dependencies:
+ content-type: 2.0.0
+ media-typer: 1.1.0
+ mime-types: 3.0.2
+
+ typed-array-buffer@1.0.3:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ is-typed-array: 1.1.15
+
+ typed-array-byte-length@1.0.3:
+ dependencies:
+ call-bind: 1.0.9
+ for-each: 0.3.5
+ gopd: 1.2.0
+ has-proto: 1.2.0
+ is-typed-array: 1.1.15
+
+ typed-array-byte-offset@1.0.4:
+ dependencies:
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.9
+ for-each: 0.3.5
+ gopd: 1.2.0
+ has-proto: 1.2.0
+ is-typed-array: 1.1.15
+ reflect.getprototypeof: 1.0.10
+
+ typed-array-length@1.0.8:
+ dependencies:
+ call-bind: 1.0.9
+ for-each: 0.3.5
+ gopd: 1.2.0
+ is-typed-array: 1.1.15
+ possible-typed-array-names: 1.1.0
+ reflect.getprototypeof: 1.0.10
+
+ typescript-eslint@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3):
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 8.61.1(@typescript-eslint/parser@8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ '@typescript-eslint/parser': 8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ '@typescript-eslint/typescript-estree': 8.61.1(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.61.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ eslint: 9.39.4(jiti@2.7.0)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ typescript@5.9.3: {}
+
+ ulid@3.0.2: {}
+
+ unbox-primitive@1.1.0:
+ dependencies:
+ call-bound: 1.0.4
+ has-bigints: 1.1.0
+ has-symbols: 1.1.0
+ which-boxed-primitive: 1.1.1
+
+ undici-types@5.26.5: {}
+
+ undici-types@6.21.0: {}
+
+ unicorn-magic@0.3.0: {}
+
+ unified@11.0.5:
+ dependencies:
+ '@types/unist': 3.0.3
+ bail: 2.0.2
+ devlop: 1.1.0
+ extend: 3.0.2
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.3
+
+ unist-util-is@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-visit@5.1.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ unpipe@1.0.0: {}
+
+ unrs-resolver@1.12.2:
+ dependencies:
+ napi-postinstall: 0.3.4
+ optionalDependencies:
+ '@unrs/resolver-binding-android-arm-eabi': 1.12.2
+ '@unrs/resolver-binding-android-arm64': 1.12.2
+ '@unrs/resolver-binding-darwin-arm64': 1.12.2
+ '@unrs/resolver-binding-darwin-x64': 1.12.2
+ '@unrs/resolver-binding-freebsd-x64': 1.12.2
+ '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.2
+ '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.2
+ '@unrs/resolver-binding-linux-arm64-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-arm64-musl': 1.12.2
+ '@unrs/resolver-binding-linux-loong64-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-loong64-musl': 1.12.2
+ '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-riscv64-musl': 1.12.2
+ '@unrs/resolver-binding-linux-s390x-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-x64-gnu': 1.12.2
+ '@unrs/resolver-binding-linux-x64-musl': 1.12.2
+ '@unrs/resolver-binding-openharmony-arm64': 1.12.2
+ '@unrs/resolver-binding-wasm32-wasi': 1.12.2
+ '@unrs/resolver-binding-win32-arm64-msvc': 1.12.2
+ '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2
+ '@unrs/resolver-binding-win32-x64-msvc': 1.12.2
+
+ update-browserslist-db@1.2.3(browserslist@4.28.2):
+ dependencies:
+ browserslist: 4.28.2
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
+ uri-js@4.4.1:
+ dependencies:
+ punycode: 2.3.1
+
+ util-deprecate@1.0.2: {}
+
+ uuid@11.1.1: {}
+
+ vary@1.1.2: {}
+
+ vfile-message@4.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.3
+
+ which-boxed-primitive@1.1.1:
+ dependencies:
+ is-bigint: 1.1.0
+ is-boolean-object: 1.2.2
+ is-number-object: 1.1.1
+ is-string: 1.1.1
+ is-symbol: 1.1.1
+
+ which-builtin-type@1.2.1:
+ dependencies:
+ call-bound: 1.0.4
+ function.prototype.name: 1.2.0
+ has-tostringtag: 1.0.2
+ is-async-function: 2.1.1
+ is-date-object: 1.1.0
+ is-finalizationregistry: 1.1.1
+ is-generator-function: 1.1.2
+ is-regex: 1.2.1
+ is-weakref: 1.1.1
+ isarray: 2.0.5
+ which-boxed-primitive: 1.1.1
+ which-collection: 1.0.2
+ which-typed-array: 1.1.22
+
+ which-collection@1.0.2:
+ dependencies:
+ is-map: 2.0.3
+ is-set: 2.0.3
+ is-weakmap: 2.0.2
+ is-weakset: 2.0.4
+
+ which-typed-array@1.1.22:
+ dependencies:
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.9
+ call-bound: 1.0.4
+ for-each: 0.3.5
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-tostringtag: 1.0.2
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ word-wrap@1.2.5: {}
+
+ wrappy@1.0.2: {}
+
+ ws@8.21.0: {}
+
+ xxhash-wasm@1.1.0: {}
+
+ yallist@3.1.1: {}
+
+ yocto-queue@0.1.0: {}
+
+ yoctocolors@2.1.2: {}
+
+ zod-from-json-schema@0.0.5:
+ dependencies:
+ zod: 3.25.76
+
+ zod-from-json-schema@0.5.3:
+ dependencies:
+ zod: 4.4.3
+
+ zod-to-json-schema@3.25.2(zod@4.4.3):
+ dependencies:
+ zod: 4.4.3
+
+ zod-validation-error@4.0.2(zod@4.4.3):
+ dependencies:
+ zod: 4.4.3
+
+ zod@3.25.76: {}
+
+ zod@4.4.3: {}
+
+ zwitch@2.0.4: {}
pnpm-workspace.yaml +17 -0
@@ -0,0 +1,17 @@
+allowBuilds:
+ better-sqlite3: set this to true or false
+ cpu-features: set this to true or false
+ sharp: set this to true or false
+ ssh2: set this to true or false
+ unrs-resolver: set this to true or false
+ignoredBuiltDependencies:
+ - sharp
+ - unrs-resolver
+
+onlyBuiltDependencies:
+ - better-sqlite3
+ - ssh2
+ - cpu-features
+ - sharp
+ - unrs-resolver
+ - esbuild
postcss.config.mjs +7 -0
@@ -0,0 +1,7 @@
+const config = {
+ plugins: {
+ "@tailwindcss/postcss": {},
+ },
+};
+
+export default config;
public/file.svg +1 -0
@@ -0,0 +1 @@
+<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
public/globe.svg +1 -0
@@ -0,0 +1 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
public/next.svg +1 -0
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
public/vercel.svg +1 -0
@@ -0,0 +1 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
public/window.svg +1 -0
@@ -0,0 +1 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
tsconfig.json +34 -0
@@ -0,0 +1,34 @@
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": ["./*"]
+ }
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts",
+ "**/*.mts"
+ ],
+ "exclude": ["node_modules"]
+}