From 8b4696c087aed2256c74d106b58367406fb96a53 Mon Sep 17 00:00:00 2001 From: zerone0x Date: Sun, 25 Jan 2026 15:24:02 +0800 Subject: [PATCH 001/196] fix(voice-call): validate provider credentials from env vars The `validateProviderConfig()` function now checks both config values AND environment variables when validating provider credentials. This aligns the validation behavior with `resolveProvider()` which already falls back to env vars. Previously, users who set credentials via environment variables would get validation errors even though the credentials would be found at runtime. The error messages correctly suggested env vars as an alternative, but the validation didn't actually check them. Affects all three supported providers: Twilio, Telnyx, and Plivo. Fixes #1709 Co-Authored-By: Claude --- extensions/voice-call/src/config.test.ts | 196 +++++++++++++++++++++++ extensions/voice-call/src/config.ts | 12 +- 2 files changed, 202 insertions(+), 6 deletions(-) create mode 100644 extensions/voice-call/src/config.test.ts diff --git a/extensions/voice-call/src/config.test.ts b/extensions/voice-call/src/config.test.ts new file mode 100644 index 000000000..3a4311c8a --- /dev/null +++ b/extensions/voice-call/src/config.test.ts @@ -0,0 +1,196 @@ +import { afterEach, beforeEach, describe, expect, it } from "vitest"; + +import { validateProviderConfig, type VoiceCallConfig } from "./config.js"; + +function createBaseConfig( + provider: "telnyx" | "twilio" | "plivo" | "mock", +): VoiceCallConfig { + return { + enabled: true, + provider, + fromNumber: "+15550001234", + inboundPolicy: "disabled", + allowFrom: [], + outbound: { defaultMode: "notify", notifyHangupDelaySec: 3 }, + maxDurationSeconds: 300, + silenceTimeoutMs: 800, + transcriptTimeoutMs: 180000, + ringTimeoutMs: 30000, + maxConcurrentCalls: 1, + serve: { port: 3334, bind: "127.0.0.1", path: "/voice/webhook" }, + tailscale: { mode: "off", path: "/voice/webhook" }, + tunnel: { provider: "none", allowNgrokFreeTier: true }, + streaming: { + enabled: false, + sttProvider: "openai-realtime", + sttModel: "gpt-4o-transcribe", + silenceDurationMs: 800, + vadThreshold: 0.5, + streamPath: "/voice/stream", + }, + skipSignatureVerification: false, + stt: { provider: "openai", model: "whisper-1" }, + tts: { provider: "openai", model: "gpt-4o-mini-tts", voice: "coral" }, + responseModel: "openai/gpt-4o-mini", + responseTimeoutMs: 30000, + }; +} + +describe("validateProviderConfig", () => { + const originalEnv = { ...process.env }; + + beforeEach(() => { + // Clear all relevant env vars before each test + delete process.env.TWILIO_ACCOUNT_SID; + delete process.env.TWILIO_AUTH_TOKEN; + delete process.env.TELNYX_API_KEY; + delete process.env.TELNYX_CONNECTION_ID; + delete process.env.PLIVO_AUTH_ID; + delete process.env.PLIVO_AUTH_TOKEN; + }); + + afterEach(() => { + // Restore original env + process.env = { ...originalEnv }; + }); + + describe("twilio provider", () => { + it("passes validation when credentials are in config", () => { + const config = createBaseConfig("twilio"); + config.twilio = { accountSid: "AC123", authToken: "secret" }; + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(true); + expect(result.errors).toEqual([]); + }); + + it("passes validation when credentials are in environment variables", () => { + process.env.TWILIO_ACCOUNT_SID = "AC123"; + process.env.TWILIO_AUTH_TOKEN = "secret"; + const config = createBaseConfig("twilio"); + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(true); + expect(result.errors).toEqual([]); + }); + + it("passes validation with mixed config and env vars", () => { + process.env.TWILIO_AUTH_TOKEN = "secret"; + const config = createBaseConfig("twilio"); + config.twilio = { accountSid: "AC123" }; + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(true); + expect(result.errors).toEqual([]); + }); + + it("fails validation when accountSid is missing everywhere", () => { + process.env.TWILIO_AUTH_TOKEN = "secret"; + const config = createBaseConfig("twilio"); + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(false); + expect(result.errors).toContain( + "plugins.entries.voice-call.config.twilio.accountSid is required (or set TWILIO_ACCOUNT_SID env)", + ); + }); + + it("fails validation when authToken is missing everywhere", () => { + process.env.TWILIO_ACCOUNT_SID = "AC123"; + const config = createBaseConfig("twilio"); + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(false); + expect(result.errors).toContain( + "plugins.entries.voice-call.config.twilio.authToken is required (or set TWILIO_AUTH_TOKEN env)", + ); + }); + }); + + describe("telnyx provider", () => { + it("passes validation when credentials are in config", () => { + const config = createBaseConfig("telnyx"); + config.telnyx = { apiKey: "KEY123", connectionId: "CONN456" }; + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(true); + expect(result.errors).toEqual([]); + }); + + it("passes validation when credentials are in environment variables", () => { + process.env.TELNYX_API_KEY = "KEY123"; + process.env.TELNYX_CONNECTION_ID = "CONN456"; + const config = createBaseConfig("telnyx"); + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(true); + expect(result.errors).toEqual([]); + }); + + it("fails validation when apiKey is missing everywhere", () => { + process.env.TELNYX_CONNECTION_ID = "CONN456"; + const config = createBaseConfig("telnyx"); + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(false); + expect(result.errors).toContain( + "plugins.entries.voice-call.config.telnyx.apiKey is required (or set TELNYX_API_KEY env)", + ); + }); + }); + + describe("plivo provider", () => { + it("passes validation when credentials are in config", () => { + const config = createBaseConfig("plivo"); + config.plivo = { authId: "MA123", authToken: "secret" }; + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(true); + expect(result.errors).toEqual([]); + }); + + it("passes validation when credentials are in environment variables", () => { + process.env.PLIVO_AUTH_ID = "MA123"; + process.env.PLIVO_AUTH_TOKEN = "secret"; + const config = createBaseConfig("plivo"); + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(true); + expect(result.errors).toEqual([]); + }); + + it("fails validation when authId is missing everywhere", () => { + process.env.PLIVO_AUTH_TOKEN = "secret"; + const config = createBaseConfig("plivo"); + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(false); + expect(result.errors).toContain( + "plugins.entries.voice-call.config.plivo.authId is required (or set PLIVO_AUTH_ID env)", + ); + }); + }); + + describe("disabled config", () => { + it("skips validation when enabled is false", () => { + const config = createBaseConfig("twilio"); + config.enabled = false; + + const result = validateProviderConfig(config); + + expect(result.valid).toBe(true); + expect(result.errors).toEqual([]); + }); + }); +}); diff --git a/extensions/voice-call/src/config.ts b/extensions/voice-call/src/config.ts index 832e692ca..403a2eb89 100644 --- a/extensions/voice-call/src/config.ts +++ b/extensions/voice-call/src/config.ts @@ -352,12 +352,12 @@ export function validateProviderConfig(config: VoiceCallConfig): { } if (config.provider === "telnyx") { - if (!config.telnyx?.apiKey) { + if (!config.telnyx?.apiKey && !process.env.TELNYX_API_KEY) { errors.push( "plugins.entries.voice-call.config.telnyx.apiKey is required (or set TELNYX_API_KEY env)", ); } - if (!config.telnyx?.connectionId) { + if (!config.telnyx?.connectionId && !process.env.TELNYX_CONNECTION_ID) { errors.push( "plugins.entries.voice-call.config.telnyx.connectionId is required (or set TELNYX_CONNECTION_ID env)", ); @@ -365,12 +365,12 @@ export function validateProviderConfig(config: VoiceCallConfig): { } if (config.provider === "twilio") { - if (!config.twilio?.accountSid) { + if (!config.twilio?.accountSid && !process.env.TWILIO_ACCOUNT_SID) { errors.push( "plugins.entries.voice-call.config.twilio.accountSid is required (or set TWILIO_ACCOUNT_SID env)", ); } - if (!config.twilio?.authToken) { + if (!config.twilio?.authToken && !process.env.TWILIO_AUTH_TOKEN) { errors.push( "plugins.entries.voice-call.config.twilio.authToken is required (or set TWILIO_AUTH_TOKEN env)", ); @@ -378,12 +378,12 @@ export function validateProviderConfig(config: VoiceCallConfig): { } if (config.provider === "plivo") { - if (!config.plivo?.authId) { + if (!config.plivo?.authId && !process.env.PLIVO_AUTH_ID) { errors.push( "plugins.entries.voice-call.config.plivo.authId is required (or set PLIVO_AUTH_ID env)", ); } - if (!config.plivo?.authToken) { + if (!config.plivo?.authToken && !process.env.PLIVO_AUTH_TOKEN) { errors.push( "plugins.entries.voice-call.config.plivo.authToken is required (or set PLIVO_AUTH_TOKEN env)", ); From dd6bc5382da3747611e3308592b1fecfe1e8f4c3 Mon Sep 17 00:00:00 2001 From: Alg0rix Date: Sun, 25 Jan 2026 13:35:32 +0000 Subject: [PATCH 002/196] fix(msteams): correct typing indicator sendActivity call --- extensions/msteams/src/reply-dispatcher.ts | 66 +++++++++++----------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/extensions/msteams/src/reply-dispatcher.ts b/extensions/msteams/src/reply-dispatcher.ts index c83867a65..7b50b0629 100644 --- a/extensions/msteams/src/reply-dispatcher.ts +++ b/extensions/msteams/src/reply-dispatcher.ts @@ -42,7 +42,7 @@ export function createMSTeamsReplyDispatcher(params: { }) { const core = getMSTeamsRuntime(); const sendTypingIndicator = async () => { - await params.context.sendActivities([{ type: "typing" }]); + await params.context.sendActivity([{ type: "typing" }]); }; const typingCallbacks = createTypingCallbacks({ start: sendTypingIndicator, @@ -70,38 +70,38 @@ export function createMSTeamsReplyDispatcher(params: { const tableMode = core.channel.text.resolveMarkdownTableMode({ cfg: params.cfg, channel: "msteams", - }); - const messages = renderReplyPayloadsToMessages([payload], { - textChunkLimit: params.textLimit, - chunkText: true, - mediaMode: "split", - tableMode, - chunkMode, - }); - const mediaMaxBytes = resolveChannelMediaMaxBytes({ - cfg: params.cfg, - resolveChannelLimitMb: ({ cfg }) => cfg.channels?.msteams?.mediaMaxMb, - }); - const ids = await sendMSTeamsMessages({ - replyStyle: params.replyStyle, - adapter: params.adapter, - appId: params.appId, - conversationRef: params.conversationRef, - context: params.context, - messages, - // Enable default retry/backoff for throttling/transient failures. - retry: {}, - onRetry: (event) => { - params.log.debug("retrying send", { - replyStyle: params.replyStyle, - ...event, - }); - }, - tokenProvider: params.tokenProvider, - sharePointSiteId: params.sharePointSiteId, - mediaMaxBytes, - }); - if (ids.length > 0) params.onSentMessageIds?.(ids); + }); + const messages = renderReplyPayloadsToMessages([payload], { + textChunkLimit: params.textLimit, + chunkText: true, + mediaMode: "split", + tableMode, + chunkMode, + }); + const mediaMaxBytes = resolveChannelMediaMaxBytes({ + cfg: params.cfg, + resolveChannelLimitMb: ({ cfg }) => cfg.channels?.msteams?.mediaMaxMb, + }); + const ids = await sendMSTeamsMessages({ + replyStyle: params.replyStyle, + adapter: params.adapter, + appId: params.appId, + conversationRef: params.conversationRef, + context: params.context, + messages, + // Enable default retry/backoff for throttling/transient failures. + retry: {}, + onRetry: (event) => { + params.log.debug("retrying send", { + replyStyle: params.replyStyle, + ...event, + }); + }, + tokenProvider: params.tokenProvider, + sharePointSiteId: params.sharePointSiteId, + mediaMaxBytes, + }); + if (ids.length > 0) params.onSentMessageIds?.(ids); }, onError: (err, info) => { const errMsg = formatUnknownError(err); From e40257af33dc0941b83093d190dc3c6c37fd82fb Mon Sep 17 00:00:00 2001 From: 0xJonHoldsCrypto Date: Sun, 25 Jan 2026 17:12:17 +0000 Subject: [PATCH 003/196] docs: add Raspberry Pi installation guide --- docs/platforms/raspberry-pi.md | 354 +++++++++++++++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 docs/platforms/raspberry-pi.md diff --git a/docs/platforms/raspberry-pi.md b/docs/platforms/raspberry-pi.md new file mode 100644 index 000000000..1273d0112 --- /dev/null +++ b/docs/platforms/raspberry-pi.md @@ -0,0 +1,354 @@ +--- +summary: "Clawdbot on Raspberry Pi (budget self-hosted setup)" +read_when: + - Setting up Clawdbot on a Raspberry Pi + - Running Clawdbot on ARM devices + - Building a cheap always-on personal AI +--- + +# Clawdbot on Raspberry Pi + +## Goal + +Run a persistent, always-on Clawdbot Gateway on a Raspberry Pi for **~$35-80** one-time cost (no monthly fees). + +Perfect for: +- 24/7 personal AI assistant +- Home automation hub +- Low-power, always-available Telegram/WhatsApp bot + +## Hardware Requirements + +| Pi Model | RAM | Works? | Notes | +|----------|-----|--------|-------| +| **Pi 5** | 4GB/8GB | ✅ Best | Fastest, recommended | +| **Pi 4** | 4GB | ✅ Good | Sweet spot for most users | +| **Pi 4** | 2GB | ✅ OK | Works, add swap | +| **Pi 4** | 1GB | ⚠️ Tight | Possible with swap, minimal config | +| **Pi 3B+** | 1GB | ⚠️ Slow | Works but sluggish | +| **Pi Zero 2 W** | 512MB | ❌ | Not recommended | + +**Minimum specs:** 1GB RAM, 1 core, 500MB disk +**Recommended:** 2GB+ RAM, 64-bit OS, 16GB+ SD card (or USB SSD) + +## What You'll Need + +- Raspberry Pi 4 or 5 (2GB+ recommended) +- MicroSD card (16GB+) or USB SSD (better performance) +- Power supply (official Pi PSU recommended) +- Network connection (Ethernet or WiFi) +- ~30 minutes + +## 1) Flash the OS + +Use **Raspberry Pi OS Lite (64-bit)** — no desktop needed for a headless server. + +1. Download [Raspberry Pi Imager](https://www.raspberrypi.com/software/) +2. Choose OS: **Raspberry Pi OS Lite (64-bit)** +3. Click the gear icon (⚙️) to pre-configure: + - Set hostname: `clawdbot` + - Enable SSH + - Set username/password + - Configure WiFi (if not using Ethernet) +4. Flash to your SD card / USB drive +5. Insert and boot the Pi + +## 2) Connect via SSH + +```bash +ssh pi@clawdbot.local +# or use the IP address +ssh pi@192.168.x.x +``` + +## 3) System Setup + +```bash +# Update system +sudo apt update && sudo apt upgrade -y + +# Install essential packages +sudo apt install -y git curl build-essential + +# Set timezone (important for cron/reminders) +sudo timedatectl set-timezone America/Chicago # Change to your timezone +``` + +## 4) Install Node.js 22 (ARM64) + +```bash +# Install Node.js via NodeSource +curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - +sudo apt install -y nodejs + +# Verify +node --version # Should show v22.x.x +npm --version +``` + +## 5) Add Swap (Important for 2GB or less) + +Swap prevents out-of-memory crashes: + +```bash +# Create 2GB swap file +sudo fallocate -l 2G /swapfile +sudo chmod 600 /swapfile +sudo mkswap /swapfile +sudo swapon /swapfile + +# Make permanent +echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab + +# Optimize for low RAM (reduce swappiness) +echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf +sudo sysctl -p +``` + +## 6) Install Clawdbot + +### Option A: Standard Install (Recommended) + +```bash +curl -fsSL https://clawd.bot/install.sh | bash +``` + +### Option B: Hackable Install (For tinkering) + +```bash +git clone https://github.com/clawdbot/clawdbot.git +cd clawdbot +npm install +npm run build +npm link +``` + +The hackable install gives you direct access to logs and code — useful for debugging ARM-specific issues. + +## 7) Run Onboarding + +```bash +clawdbot onboard --install-daemon +``` + +Follow the wizard: +1. **Gateway mode:** Local +2. **Auth:** API keys recommended (OAuth can be finicky on headless Pi) +3. **Channels:** Telegram is easiest to start with +4. **Daemon:** Yes (systemd) + +## 8) Verify Installation + +```bash +# Check status +clawdbot status + +# Check service +sudo systemctl status clawdbot + +# View logs +journalctl -u clawdbot -f +``` + +## 9) Access the Dashboard + +Since the Pi is headless, use an SSH tunnel: + +```bash +# From your laptop/desktop +ssh -L 18789:localhost:18789 pi@clawdbot.local + +# Then open in browser +open http://localhost:18789 +``` + +Or use Tailscale for always-on access: + +```bash +# On the Pi +curl -fsSL https://tailscale.com/install.sh | sh +sudo tailscale up + +# Update config +clawdbot config set gateway.bind tailnet +sudo systemctl restart clawdbot +``` + +--- + +## Performance Optimizations + +### Use a USB SSD (Huge Improvement) + +SD cards are slow and wear out. A USB SSD dramatically improves performance: + +```bash +# Check if booting from USB +lsblk +``` + +See [Pi USB boot guide](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#usb-mass-storage-boot) for setup. + +### Reduce Memory Usage + +```bash +# Disable GPU memory allocation (headless) +echo 'gpu_mem=16' | sudo tee -a /boot/config.txt + +# Disable Bluetooth if not needed +sudo systemctl disable bluetooth +``` + +### Monitor Resources + +```bash +# Check memory +free -h + +# Check CPU temperature +vcgencmd measure_temp + +# Live monitoring +htop +``` + +--- + +## ARM-Specific Notes + +### Binary Compatibility + +Most Clawdbot features work on ARM64, but some external binaries may need ARM builds: + +| Tool | ARM64 Status | Notes | +|------|--------------|-------| +| Node.js | ✅ | Works great | +| WhatsApp (Baileys) | ✅ | Pure JS, no issues | +| Telegram | ✅ | Pure JS, no issues | +| gog (Gmail CLI) | ⚠️ | Check for ARM release | +| Chromium (browser) | ✅ | `sudo apt install chromium-browser` | + +If a skill fails, check if its binary has an ARM build. Many Go/Rust tools do; some don't. + +### 32-bit vs 64-bit + +**Always use 64-bit OS.** Node.js and many modern tools require it. Check with: + +```bash +uname -m +# Should show: aarch64 (64-bit) not armv7l (32-bit) +``` + +--- + +## Recommended Model Setup + +Since the Pi is just the Gateway (models run in the cloud), use API-based models: + +```json +{ + "agents": { + "defaults": { + "model": { + "primary": "anthropic/claude-sonnet-4-20250514", + "fallbacks": ["openai/gpt-4o-mini"] + } + } + } +} +``` + +**Don't try to run local LLMs on a Pi** — even small models are too slow. Let Claude/GPT do the heavy lifting. + +--- + +## Auto-Start on Boot + +The onboarding wizard sets this up, but to verify: + +```bash +# Check service is enabled +sudo systemctl is-enabled clawdbot + +# Enable if not +sudo systemctl enable clawdbot + +# Start on boot +sudo systemctl start clawdbot +``` + +--- + +## Troubleshooting + +### Out of Memory (OOM) + +```bash +# Check memory +free -h + +# Add more swap (see Step 5) +# Or reduce services running on the Pi +``` + +### Slow Performance + +- Use USB SSD instead of SD card +- Disable unused services: `sudo systemctl disable cups bluetooth avahi-daemon` +- Check CPU throttling: `vcgencmd get_throttled` (should return `0x0`) + +### Service Won't Start + +```bash +# Check logs +journalctl -u clawdbot --no-pager -n 100 + +# Common fix: rebuild +cd ~/clawdbot # if using hackable install +npm run build +sudo systemctl restart clawdbot +``` + +### ARM Binary Issues + +If a skill fails with "exec format error": +1. Check if the binary has an ARM64 build +2. Try building from source +3. Or use a Docker container with ARM support + +### WiFi Drops + +For headless Pis on WiFi: + +```bash +# Disable WiFi power management +sudo iwconfig wlan0 power off + +# Make permanent +echo 'wireless-power off' | sudo tee -a /etc/network/interfaces +``` + +--- + +## Cost Comparison + +| Setup | One-Time Cost | Monthly Cost | Notes | +|-------|---------------|--------------|-------| +| **Pi 4 (2GB)** | ~$45 | $0 | + power (~$5/yr) | +| **Pi 4 (4GB)** | ~$55 | $0 | Recommended | +| **Pi 5 (4GB)** | ~$60 | $0 | Best performance | +| **Pi 5 (8GB)** | ~$80 | $0 | Overkill but future-proof | +| DigitalOcean | $0 | $6/mo | $72/year | +| Hetzner | $0 | €3.79/mo | ~$50/year | + +**Break-even:** A Pi pays for itself in ~6-12 months vs cloud VPS. + +--- + +## See Also + +- [Linux guide](/platforms/linux) — general Linux setup +- [DigitalOcean guide](/platforms/digitalocean) — cloud alternative +- [Hetzner guide](/platforms/hetzner) — Docker setup +- [Tailscale](/gateway/tailscale) — remote access +- [Nodes](/nodes) — pair your laptop/phone with the Pi gateway From 68824c8903ea5cbe429ee36bf63df6aa63b7c6c0 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 25 Jan 2026 20:58:35 +0000 Subject: [PATCH 004/196] chore: start 2026.1.25 changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eda32488..1c05e8691 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ Docs: https://docs.clawd.bot +## 2026.1.25 + +### Changes +- TBD. + ## 2026.1.24-3 ### Fixes From ffaeee4c39cbb56be473e719ded16e6b6b8d8986 Mon Sep 17 00:00:00 2001 From: Ross Morsali Date: Sun, 25 Jan 2026 19:56:04 +0100 Subject: [PATCH 005/196] fix: preserve CLI session IDs for session resume - Add resumeArgs to DEFAULT_CLAUDE_BACKEND for proper --resume flag usage - Fix gateway not preserving cliSessionIds/claudeCliSessionId in nextEntry - Add test for CLI session ID preservation in gateway agent handler - Update docs with new resumeArgs default --- docs/gateway/cli-backends.md | 1 + src/agents/cli-backends.ts | 8 ++ src/gateway/server-methods/agent.test.ts | 163 +++++++++++++++++++++++ src/gateway/server-methods/agent.ts | 2 + 4 files changed, 174 insertions(+) create mode 100644 src/gateway/server-methods/agent.test.ts diff --git a/docs/gateway/cli-backends.md b/docs/gateway/cli-backends.md index 917145cc2..092533c2e 100644 --- a/docs/gateway/cli-backends.md +++ b/docs/gateway/cli-backends.md @@ -182,6 +182,7 @@ Clawdbot ships a default for `claude-cli`: - `command: "claude"` - `args: ["-p", "--output-format", "json", "--dangerously-skip-permissions"]` +- `resumeArgs: ["-p", "--output-format", "json", "--dangerously-skip-permissions", "--resume", "{sessionId}"]` - `modelArg: "--model"` - `systemPromptArg: "--append-system-prompt"` - `sessionArg: "--session-id"` diff --git a/src/agents/cli-backends.ts b/src/agents/cli-backends.ts index a2fcaa8a5..f21c04f52 100644 --- a/src/agents/cli-backends.ts +++ b/src/agents/cli-backends.ts @@ -28,6 +28,14 @@ const CLAUDE_MODEL_ALIASES: Record = { const DEFAULT_CLAUDE_BACKEND: CliBackendConfig = { command: "claude", args: ["-p", "--output-format", "json", "--dangerously-skip-permissions"], + resumeArgs: [ + "-p", + "--output-format", + "json", + "--dangerously-skip-permissions", + "--resume", + "{sessionId}", + ], output: "json", input: "arg", modelArg: "--model", diff --git a/src/gateway/server-methods/agent.test.ts b/src/gateway/server-methods/agent.test.ts new file mode 100644 index 000000000..149ab4a67 --- /dev/null +++ b/src/gateway/server-methods/agent.test.ts @@ -0,0 +1,163 @@ +import { describe, expect, it, vi } from "vitest"; + +import type { GatewayRequestContext } from "./types.js"; +import { agentHandlers } from "./agent.js"; + +const mocks = vi.hoisted(() => ({ + loadSessionEntry: vi.fn(), + updateSessionStore: vi.fn(), + agentCommand: vi.fn(), + registerAgentRunContext: vi.fn(), +})); + +vi.mock("../session-utils.js", () => ({ + loadSessionEntry: mocks.loadSessionEntry, +})); + +vi.mock("../../config/sessions.js", async () => { + const actual = await vi.importActual( + "../../config/sessions.js", + ); + return { + ...actual, + updateSessionStore: mocks.updateSessionStore, + resolveAgentIdFromSessionKey: () => "main", + resolveExplicitAgentSessionKey: () => undefined, + resolveAgentMainSessionKey: () => "agent:main:main", + }; +}); + +vi.mock("../../commands/agent.js", () => ({ + agentCommand: mocks.agentCommand, +})); + +vi.mock("../../config/config.js", () => ({ + loadConfig: () => ({}), +})); + +vi.mock("../../agents/agent-scope.js", () => ({ + listAgentIds: () => ["main"], +})); + +vi.mock("../../infra/agent-events.js", () => ({ + registerAgentRunContext: mocks.registerAgentRunContext, + onAgentEvent: vi.fn(), +})); + +vi.mock("../../sessions/send-policy.js", () => ({ + resolveSendPolicy: () => "allow", +})); + +vi.mock("../../utils/delivery-context.js", async () => { + const actual = await vi.importActual( + "../../utils/delivery-context.js", + ); + return { + ...actual, + normalizeSessionDeliveryFields: () => ({}), + }; +}); + +const makeContext = (): GatewayRequestContext => + ({ + dedupe: new Map(), + addChatRun: vi.fn(), + logGateway: { info: vi.fn(), error: vi.fn() }, + }) as unknown as GatewayRequestContext; + +describe("gateway agent handler", () => { + it("preserves cliSessionIds from existing session entry", async () => { + const existingCliSessionIds = { "claude-cli": "abc-123-def" }; + const existingClaudeCliSessionId = "abc-123-def"; + + mocks.loadSessionEntry.mockReturnValue({ + cfg: {}, + storePath: "/tmp/sessions.json", + entry: { + sessionId: "existing-session-id", + updatedAt: Date.now(), + cliSessionIds: existingCliSessionIds, + claudeCliSessionId: existingClaudeCliSessionId, + }, + canonicalKey: "agent:main:main", + }); + + let capturedEntry: Record | undefined; + mocks.updateSessionStore.mockImplementation(async (_path, updater) => { + const store: Record = {}; + await updater(store); + capturedEntry = store["agent:main:main"] as Record; + }); + + mocks.agentCommand.mockResolvedValue({ + payloads: [{ text: "ok" }], + meta: { durationMs: 100 }, + }); + + const respond = vi.fn(); + await agentHandlers.agent({ + params: { + message: "test", + agentId: "main", + sessionKey: "agent:main:main", + idempotencyKey: "test-idem", + }, + respond, + context: makeContext(), + req: { type: "req", id: "1", method: "agent" }, + client: null, + isWebchatConnect: () => false, + }); + + expect(mocks.updateSessionStore).toHaveBeenCalled(); + expect(capturedEntry).toBeDefined(); + expect(capturedEntry?.cliSessionIds).toEqual(existingCliSessionIds); + expect(capturedEntry?.claudeCliSessionId).toBe(existingClaudeCliSessionId); + }); + + it("handles missing cliSessionIds gracefully", async () => { + mocks.loadSessionEntry.mockReturnValue({ + cfg: {}, + storePath: "/tmp/sessions.json", + entry: { + sessionId: "existing-session-id", + updatedAt: Date.now(), + // No cliSessionIds or claudeCliSessionId + }, + canonicalKey: "agent:main:main", + }); + + let capturedEntry: Record | undefined; + mocks.updateSessionStore.mockImplementation(async (_path, updater) => { + const store: Record = {}; + await updater(store); + capturedEntry = store["agent:main:main"] as Record; + }); + + mocks.agentCommand.mockResolvedValue({ + payloads: [{ text: "ok" }], + meta: { durationMs: 100 }, + }); + + const respond = vi.fn(); + await agentHandlers.agent({ + params: { + message: "test", + agentId: "main", + sessionKey: "agent:main:main", + idempotencyKey: "test-idem-2", + }, + respond, + context: makeContext(), + req: { type: "req", id: "2", method: "agent" }, + client: null, + isWebchatConnect: () => false, + }); + + expect(mocks.updateSessionStore).toHaveBeenCalled(); + expect(capturedEntry).toBeDefined(); + // Should be undefined, not cause an error + expect(capturedEntry?.cliSessionIds).toBeUndefined(); + expect(capturedEntry?.claudeCliSessionId).toBeUndefined(); + }); +}); diff --git a/src/gateway/server-methods/agent.ts b/src/gateway/server-methods/agent.ts index 8c5782e00..d159d1f78 100644 --- a/src/gateway/server-methods/agent.ts +++ b/src/gateway/server-methods/agent.ts @@ -251,6 +251,8 @@ export const agentHandlers: GatewayRequestHandlers = { groupId: resolvedGroupId ?? entry?.groupId, groupChannel: resolvedGroupChannel ?? entry?.groupChannel, space: resolvedGroupSpace ?? entry?.space, + cliSessionIds: entry?.cliSessionIds, + claudeCliSessionId: entry?.claudeCliSessionId, }; sessionEntry = nextEntry; const sendPolicy = resolveSendPolicy({ From ae030c32dacdaafeb58147571a1c2e9dbc1d5c03 Mon Sep 17 00:00:00 2001 From: Ross Morsali Date: Sun, 25 Jan 2026 20:11:57 +0100 Subject: [PATCH 006/196] fix: emit assistant event for CLI backend responses in TUI CLI backends (claude-cli etc) don't emit streaming assistant events, causing TUI to show "(no output)" despite correct processing. Now emits assistant event with final text before lifecycle end so server-chat buffer gets populated for WebSocket clients. --- src/auto-reply/reply/agent-runner-execution.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/auto-reply/reply/agent-runner-execution.ts b/src/auto-reply/reply/agent-runner-execution.ts index a428aa6da..47c45b09d 100644 --- a/src/auto-reply/reply/agent-runner-execution.ts +++ b/src/auto-reply/reply/agent-runner-execution.ts @@ -179,6 +179,17 @@ export async function runAgentTurnWithFallback(params: { images: params.opts?.images, }) .then((result) => { + // CLI backends don't emit streaming assistant events, so we need to + // emit one with the final text so server-chat can populate its buffer + // and send the response to TUI/WebSocket clients. + const cliText = result.payloads?.[0]?.text?.trim(); + if (cliText) { + emitAgentEvent({ + runId, + stream: "assistant", + data: { text: cliText }, + }); + } emitAgentEvent({ runId, stream: "lifecycle", From 6ffc5d93e4d14a7b6dc7cc17187f332b9f143823 Mon Sep 17 00:00:00 2001 From: Ross Morsali Date: Sun, 25 Jan 2026 21:12:45 +0100 Subject: [PATCH 007/196] test: update CLI runner test to expect --resume for session resume --- src/agents/claude-cli-runner.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/agents/claude-cli-runner.test.ts b/src/agents/claude-cli-runner.test.ts index 6414aecb5..7825d00da 100644 --- a/src/agents/claude-cli-runner.test.ts +++ b/src/agents/claude-cli-runner.test.ts @@ -61,7 +61,7 @@ describe("runClaudeCliAgent", () => { expect(argv).toContain("hi"); }); - it("uses provided --session-id when a claude session id is provided", async () => { + it("uses --resume when a claude session id is provided", async () => { runCommandWithTimeoutMock.mockResolvedValueOnce({ stdout: JSON.stringify({ message: "ok", session_id: "sid-2" }), stderr: "", @@ -83,7 +83,7 @@ describe("runClaudeCliAgent", () => { expect(runCommandWithTimeoutMock).toHaveBeenCalledTimes(1); const argv = runCommandWithTimeoutMock.mock.calls[0]?.[0] as string[]; - expect(argv).toContain("--session-id"); + expect(argv).toContain("--resume"); expect(argv).toContain("c9d7b831-1c31-4d22-80b9-1e50ca207d4b"); expect(argv).toContain("hi"); }); From e0adf65dac311a6ab253de5f915ef77455b3026f Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 25 Jan 2026 21:08:23 +0000 Subject: [PATCH 008/196] test: cover CLI chat delta event (#1921) (thanks @rmorse) --- CHANGELOG.md | 1 + src/gateway/server-chat.agent-events.test.ts | 43 ++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/gateway/server-chat.agent-events.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c05e8691..ee138f13e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Docs: https://docs.clawd.bot ### Fixes - Gateway: harden reverse proxy handling for local-client detection and unauthenticated proxied connects. (#1795) Thanks @orlyjamie. - Security audit: flag loopback Control UI with auth disabled as critical. (#1795) Thanks @orlyjamie. +- CLI: resume claude-cli sessions and stream CLI replies to TUI clients. (#1921) Thanks @rmorse. ## 2026.1.24-2 diff --git a/src/gateway/server-chat.agent-events.test.ts b/src/gateway/server-chat.agent-events.test.ts new file mode 100644 index 000000000..14657464a --- /dev/null +++ b/src/gateway/server-chat.agent-events.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, it, vi } from "vitest"; + +import { createAgentEventHandler, createChatRunState } from "./server-chat.js"; + +describe("agent event handler", () => { + it("emits chat delta for assistant text-only events", () => { + const nowSpy = vi.spyOn(Date, "now").mockReturnValue(1_000); + const broadcast = vi.fn(); + const nodeSendToSession = vi.fn(); + const agentRunSeq = new Map(); + const chatRunState = createChatRunState(); + chatRunState.registry.add("run-1", { sessionKey: "session-1", clientRunId: "client-1" }); + + const handler = createAgentEventHandler({ + broadcast, + nodeSendToSession, + agentRunSeq, + chatRunState, + resolveSessionKeyForRun: () => undefined, + clearAgentRunContext: vi.fn(), + }); + + handler({ + runId: "run-1", + seq: 1, + stream: "assistant", + ts: Date.now(), + data: { text: "Hello world" }, + }); + + const chatCalls = broadcast.mock.calls.filter(([event]) => event === "chat"); + expect(chatCalls).toHaveLength(1); + const payload = chatCalls[0]?.[1] as { + state?: string; + message?: { content?: Array<{ text?: string }> }; + }; + expect(payload.state).toBe("delta"); + expect(payload.message?.content?.[0]?.text).toBe("Hello world"); + const sessionChatCalls = nodeSendToSession.mock.calls.filter(([, event]) => event === "chat"); + expect(sessionChatCalls).toHaveLength(1); + nowSpy.mockRestore(); + }); +}); From 50b4126c79536a9645cddcfe6801916b5f6d9343 Mon Sep 17 00:00:00 2001 From: Vignesh Date: Sun, 25 Jan 2026 13:42:56 -0800 Subject: [PATCH 009/196] Update deployment link for Railway template --- docs/railway.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/railway.mdx b/docs/railway.mdx index 808416f50..b8f994a7d 100644 --- a/docs/railway.mdx +++ b/docs/railway.mdx @@ -16,7 +16,7 @@ and you configure everything via the `/setup` web wizard. ## One-click deploy -Deploy on Railway +Deploy on Railway After deploy, find your public URL in **Railway → your service → Settings → Domains**. From 8f6542409a57c99952c4f03323f52498bc958399 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 25 Jan 2026 22:13:00 +0000 Subject: [PATCH 010/196] chore: bump versions for 2026.1.25 --- CHANGELOG.md | 1 + apps/android/app/build.gradle.kts | 4 ++-- apps/ios/Sources/Info.plist | 4 ++-- apps/ios/Tests/Info.plist | 4 ++-- apps/ios/project.yml | 8 ++++---- apps/macos/Sources/Clawdbot/Resources/Info.plist | 4 ++-- docs/platforms/fly.md | 2 +- docs/platforms/mac/release.md | 14 +++++++------- docs/reference/RELEASING.md | 2 +- extensions/bluebubbles/package.json | 2 +- extensions/copilot-proxy/package.json | 2 +- extensions/diagnostics-otel/package.json | 2 +- extensions/discord/package.json | 2 +- extensions/google-antigravity-auth/package.json | 2 +- extensions/google-gemini-cli-auth/package.json | 2 +- extensions/googlechat/package.json | 4 ++-- extensions/imessage/package.json | 2 +- extensions/line/package.json | 2 +- extensions/llm-task/package.json | 2 +- extensions/lobster/package.json | 2 +- extensions/matrix/package.json | 2 +- extensions/mattermost/package.json | 2 +- extensions/memory-core/package.json | 4 ++-- extensions/memory-lancedb/package.json | 2 +- extensions/msteams/package.json | 2 +- extensions/nextcloud-talk/package.json | 2 +- extensions/nostr/package.json | 2 +- extensions/open-prose/package.json | 2 +- extensions/signal/package.json | 2 +- extensions/slack/package.json | 2 +- extensions/telegram/package.json | 2 +- extensions/tlon/package.json | 2 +- extensions/voice-call/CHANGELOG.md | 2 +- extensions/voice-call/package.json | 2 +- extensions/whatsapp/package.json | 2 +- extensions/zalo/package.json | 2 +- extensions/zalouser/package.json | 2 +- package.json | 4 ++-- 38 files changed, 54 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee138f13e..afdbb8463 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Docs: https://docs.clawd.bot ## 2026.1.25 +Status: unreleased. ### Changes - TBD. diff --git a/apps/android/app/build.gradle.kts b/apps/android/app/build.gradle.kts index d8d77ebe1..a015c0e36 100644 --- a/apps/android/app/build.gradle.kts +++ b/apps/android/app/build.gradle.kts @@ -21,8 +21,8 @@ android { applicationId = "com.clawdbot.android" minSdk = 31 targetSdk = 36 - versionCode = 202601240 - versionName = "2026.1.24" + versionCode = 202601250 + versionName = "2026.1.25" } buildTypes { diff --git a/apps/ios/Sources/Info.plist b/apps/ios/Sources/Info.plist index 9dd7a0315..e1cf2b71d 100644 --- a/apps/ios/Sources/Info.plist +++ b/apps/ios/Sources/Info.plist @@ -19,9 +19,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2026.1.24 + 2026.1.25 CFBundleVersion - 20260124 + 20260125 NSAppTransportSecurity NSAllowsArbitraryLoadsInWebContent diff --git a/apps/ios/Tests/Info.plist b/apps/ios/Tests/Info.plist index 798a77421..6ff977b05 100644 --- a/apps/ios/Tests/Info.plist +++ b/apps/ios/Tests/Info.plist @@ -17,8 +17,8 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2026.1.24 + 2026.1.25 CFBundleVersion - 20260124 + 20260125 diff --git a/apps/ios/project.yml b/apps/ios/project.yml index 52faeb9d0..0073b4ef9 100644 --- a/apps/ios/project.yml +++ b/apps/ios/project.yml @@ -81,8 +81,8 @@ targets: properties: CFBundleDisplayName: Clawdbot CFBundleIconName: AppIcon - CFBundleShortVersionString: "2026.1.24" - CFBundleVersion: "20260124" + CFBundleShortVersionString: "2026.1.25" + CFBundleVersion: "20260125" UILaunchScreen: {} UIApplicationSceneManifest: UIApplicationSupportsMultipleScenes: false @@ -130,5 +130,5 @@ targets: path: Tests/Info.plist properties: CFBundleDisplayName: ClawdbotTests - CFBundleShortVersionString: "2026.1.24" - CFBundleVersion: "20260124" + CFBundleShortVersionString: "2026.1.25" + CFBundleVersion: "20260125" diff --git a/apps/macos/Sources/Clawdbot/Resources/Info.plist b/apps/macos/Sources/Clawdbot/Resources/Info.plist index 1c7d9619f..ee9e3113d 100644 --- a/apps/macos/Sources/Clawdbot/Resources/Info.plist +++ b/apps/macos/Sources/Clawdbot/Resources/Info.plist @@ -15,9 +15,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2026.1.24 + 2026.1.25 CFBundleVersion - 202601240 + 202601250 CFBundleIconFile Clawdbot CFBundleURLTypes diff --git a/docs/platforms/fly.md b/docs/platforms/fly.md index d43b83ed7..0fdf176ae 100644 --- a/docs/platforms/fly.md +++ b/docs/platforms/fly.md @@ -182,7 +182,7 @@ cat > /data/clawdbot.json << 'EOF' "bind": "auto" }, "meta": { - "lastTouchedVersion": "2026.1.24" + "lastTouchedVersion": "2026.1.25" } } EOF diff --git a/docs/platforms/mac/release.md b/docs/platforms/mac/release.md index d2d267661..d3bfd02c3 100644 --- a/docs/platforms/mac/release.md +++ b/docs/platforms/mac/release.md @@ -30,17 +30,17 @@ Notes: # From repo root; set release IDs so Sparkle feed is enabled. # APP_BUILD must be numeric + monotonic for Sparkle compare. BUNDLE_ID=com.clawdbot.mac \ -APP_VERSION=2026.1.24-3 \ +APP_VERSION=2026.1.25 \ APP_BUILD="$(git rev-list --count HEAD)" \ BUILD_CONFIG=release \ SIGN_IDENTITY="Developer ID Application: ()" \ scripts/package-mac-app.sh # Zip for distribution (includes resource forks for Sparkle delta support) -ditto -c -k --sequesterRsrc --keepParent dist/Clawdbot.app dist/Clawdbot-2026.1.24-3.zip +ditto -c -k --sequesterRsrc --keepParent dist/Clawdbot.app dist/Clawdbot-2026.1.25.zip # Optional: also build a styled DMG for humans (drag to /Applications) -scripts/create-dmg.sh dist/Clawdbot.app dist/Clawdbot-2026.1.24-3.dmg +scripts/create-dmg.sh dist/Clawdbot.app dist/Clawdbot-2026.1.25.dmg # Recommended: build + notarize/staple zip + DMG # First, create a keychain profile once: @@ -48,26 +48,26 @@ scripts/create-dmg.sh dist/Clawdbot.app dist/Clawdbot-2026.1.24-3.dmg # --apple-id "" --team-id "" --password "" NOTARIZE=1 NOTARYTOOL_PROFILE=clawdbot-notary \ BUNDLE_ID=com.clawdbot.mac \ -APP_VERSION=2026.1.24-3 \ +APP_VERSION=2026.1.25 \ APP_BUILD="$(git rev-list --count HEAD)" \ BUILD_CONFIG=release \ SIGN_IDENTITY="Developer ID Application: ()" \ scripts/package-mac-dist.sh # Optional: ship dSYM alongside the release -ditto -c -k --keepParent apps/macos/.build/release/Clawdbot.app.dSYM dist/Clawdbot-2026.1.24-3.dSYM.zip +ditto -c -k --keepParent apps/macos/.build/release/Clawdbot.app.dSYM dist/Clawdbot-2026.1.25.dSYM.zip ``` ## Appcast entry Use the release note generator so Sparkle renders formatted HTML notes: ```bash -SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/Clawdbot-2026.1.24-3.zip https://raw.githubusercontent.com/clawdbot/clawdbot/main/appcast.xml +SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/Clawdbot-2026.1.25.zip https://raw.githubusercontent.com/clawdbot/clawdbot/main/appcast.xml ``` Generates HTML release notes from `CHANGELOG.md` (via [`scripts/changelog-to-html.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/changelog-to-html.sh)) and embeds them in the appcast entry. Commit the updated `appcast.xml` alongside the release assets (zip + dSYM) when publishing. ## Publish & verify -- Upload `Clawdbot-2026.1.24-3.zip` (and `Clawdbot-2026.1.24-3.dSYM.zip`) to the GitHub release for tag `v2026.1.24-3`. +- Upload `Clawdbot-2026.1.25.zip` (and `Clawdbot-2026.1.25.dSYM.zip`) to the GitHub release for tag `v2026.1.25`. - Ensure the raw appcast URL matches the baked feed: `https://raw.githubusercontent.com/clawdbot/clawdbot/main/appcast.xml`. - Sanity checks: - `curl -I https://raw.githubusercontent.com/clawdbot/clawdbot/main/appcast.xml` returns 200. diff --git a/docs/reference/RELEASING.md b/docs/reference/RELEASING.md index 6492bd469..244757a48 100644 --- a/docs/reference/RELEASING.md +++ b/docs/reference/RELEASING.md @@ -17,7 +17,7 @@ When the operator says “release”, immediately do this preflight (no extra qu - Use Sparkle keys from `~/Library/CloudStorage/Dropbox/Backup/Sparkle` if needed. 1) **Version & metadata** -- [ ] Bump `package.json` version (e.g., `2026.1.24`). +- [ ] Bump `package.json` version (e.g., `2026.1.25`). - [ ] Run `pnpm plugins:sync` to align extension package versions + changelogs. - [ ] Update CLI/version strings: [`src/cli/program.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/cli/program.ts) and the Baileys user agent in [`src/provider-web.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/provider-web.ts). - [ ] Confirm package metadata (name, description, repository, keywords, license) and `bin` map points to [`dist/entry.js`](https://github.com/clawdbot/clawdbot/blob/main/dist/entry.js) for `clawdbot`. diff --git a/extensions/bluebubbles/package.json b/extensions/bluebubbles/package.json index 925b05bc1..7d82036a0 100644 --- a/extensions/bluebubbles/package.json +++ b/extensions/bluebubbles/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/bluebubbles", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot BlueBubbles channel plugin", "clawdbot": { diff --git a/extensions/copilot-proxy/package.json b/extensions/copilot-proxy/package.json index 792a94225..2a9a63c71 100644 --- a/extensions/copilot-proxy/package.json +++ b/extensions/copilot-proxy/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/copilot-proxy", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Copilot Proxy provider plugin", "clawdbot": { diff --git a/extensions/diagnostics-otel/package.json b/extensions/diagnostics-otel/package.json index 2afc99e2e..65a6bf0cd 100644 --- a/extensions/diagnostics-otel/package.json +++ b/extensions/diagnostics-otel/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/diagnostics-otel", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot diagnostics OpenTelemetry exporter", "clawdbot": { diff --git a/extensions/discord/package.json b/extensions/discord/package.json index dae5fe1f1..90a99d4d3 100644 --- a/extensions/discord/package.json +++ b/extensions/discord/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/discord", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Discord channel plugin", "clawdbot": { diff --git a/extensions/google-antigravity-auth/package.json b/extensions/google-antigravity-auth/package.json index 96bffde7c..f1d8f86bd 100644 --- a/extensions/google-antigravity-auth/package.json +++ b/extensions/google-antigravity-auth/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/google-antigravity-auth", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Google Antigravity OAuth provider plugin", "clawdbot": { diff --git a/extensions/google-gemini-cli-auth/package.json b/extensions/google-gemini-cli-auth/package.json index dc8a894d7..7e3fef15b 100644 --- a/extensions/google-gemini-cli-auth/package.json +++ b/extensions/google-gemini-cli-auth/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/google-gemini-cli-auth", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Gemini CLI OAuth provider plugin", "clawdbot": { diff --git a/extensions/googlechat/package.json b/extensions/googlechat/package.json index 056bdedb6..af1ccf8e1 100644 --- a/extensions/googlechat/package.json +++ b/extensions/googlechat/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/googlechat", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Google Chat channel plugin", "clawdbot": { @@ -34,6 +34,6 @@ "clawdbot": "workspace:*" }, "peerDependencies": { - "clawdbot": ">=2026.1.24" + "clawdbot": ">=2026.1.25" } } diff --git a/extensions/imessage/package.json b/extensions/imessage/package.json index 79aa7890d..944ad06bf 100644 --- a/extensions/imessage/package.json +++ b/extensions/imessage/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/imessage", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot iMessage channel plugin", "clawdbot": { diff --git a/extensions/line/package.json b/extensions/line/package.json index b518f5ca5..346d66415 100644 --- a/extensions/line/package.json +++ b/extensions/line/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/line", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot LINE channel plugin", "clawdbot": { diff --git a/extensions/llm-task/package.json b/extensions/llm-task/package.json index a03344d1a..d6bfbb31d 100644 --- a/extensions/llm-task/package.json +++ b/extensions/llm-task/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/llm-task", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot JSON-only LLM task plugin", "clawdbot": { diff --git a/extensions/lobster/package.json b/extensions/lobster/package.json index 3926b553b..b73dbac69 100644 --- a/extensions/lobster/package.json +++ b/extensions/lobster/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/lobster", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Lobster workflow tool plugin (typed pipelines + resumable approvals)", "clawdbot": { diff --git a/extensions/matrix/package.json b/extensions/matrix/package.json index 24529ee97..7fa12bc74 100644 --- a/extensions/matrix/package.json +++ b/extensions/matrix/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/matrix", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Matrix channel plugin", "clawdbot": { diff --git a/extensions/mattermost/package.json b/extensions/mattermost/package.json index 77d799c34..60c02d50f 100644 --- a/extensions/mattermost/package.json +++ b/extensions/mattermost/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/mattermost", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Mattermost channel plugin", "clawdbot": { diff --git a/extensions/memory-core/package.json b/extensions/memory-core/package.json index c70c2a63f..c70da1395 100644 --- a/extensions/memory-core/package.json +++ b/extensions/memory-core/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/memory-core", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot core memory search plugin", "clawdbot": { @@ -9,6 +9,6 @@ ] }, "peerDependencies": { - "clawdbot": ">=2026.1.24" + "clawdbot": ">=2026.1.25" } } diff --git a/extensions/memory-lancedb/package.json b/extensions/memory-lancedb/package.json index 80018044f..e003f5890 100644 --- a/extensions/memory-lancedb/package.json +++ b/extensions/memory-lancedb/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/memory-lancedb", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot LanceDB-backed long-term memory plugin with auto-recall/capture", "dependencies": { diff --git a/extensions/msteams/package.json b/extensions/msteams/package.json index b336b80e6..b94f8e76a 100644 --- a/extensions/msteams/package.json +++ b/extensions/msteams/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/msteams", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Microsoft Teams channel plugin", "clawdbot": { diff --git a/extensions/nextcloud-talk/package.json b/extensions/nextcloud-talk/package.json index bf5e443e5..2da3f3b2a 100644 --- a/extensions/nextcloud-talk/package.json +++ b/extensions/nextcloud-talk/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/nextcloud-talk", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Nextcloud Talk channel plugin", "clawdbot": { diff --git a/extensions/nostr/package.json b/extensions/nostr/package.json index 3a3e5ac56..b2fb4b799 100644 --- a/extensions/nostr/package.json +++ b/extensions/nostr/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/nostr", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Nostr channel plugin for NIP-04 encrypted DMs", "clawdbot": { diff --git a/extensions/open-prose/package.json b/extensions/open-prose/package.json index 873f3458a..052201205 100644 --- a/extensions/open-prose/package.json +++ b/extensions/open-prose/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/open-prose", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "OpenProse VM skill pack plugin (slash command + telemetry).", "clawdbot": { diff --git a/extensions/signal/package.json b/extensions/signal/package.json index 034c65dea..65948eb7b 100644 --- a/extensions/signal/package.json +++ b/extensions/signal/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/signal", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Signal channel plugin", "clawdbot": { diff --git a/extensions/slack/package.json b/extensions/slack/package.json index 73f2f6ecd..5bd452d2e 100644 --- a/extensions/slack/package.json +++ b/extensions/slack/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/slack", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Slack channel plugin", "clawdbot": { diff --git a/extensions/telegram/package.json b/extensions/telegram/package.json index 81b378df2..64d3d7dea 100644 --- a/extensions/telegram/package.json +++ b/extensions/telegram/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/telegram", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Telegram channel plugin", "clawdbot": { diff --git a/extensions/tlon/package.json b/extensions/tlon/package.json index dca4f914d..06750126d 100644 --- a/extensions/tlon/package.json +++ b/extensions/tlon/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/tlon", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Tlon/Urbit channel plugin", "clawdbot": { diff --git a/extensions/voice-call/CHANGELOG.md b/extensions/voice-call/CHANGELOG.md index 6123a7315..a8721d47d 100644 --- a/extensions/voice-call/CHANGELOG.md +++ b/extensions/voice-call/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 2026.1.24 +## 2026.1.25 ### Changes - Breaking: voice-call TTS now uses core `messages.tts` (plugin TTS config deep‑merges with core). diff --git a/extensions/voice-call/package.json b/extensions/voice-call/package.json index 840776c19..31b171f76 100644 --- a/extensions/voice-call/package.json +++ b/extensions/voice-call/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/voice-call", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot voice-call plugin", "dependencies": { diff --git a/extensions/whatsapp/package.json b/extensions/whatsapp/package.json index 8e18af842..b7b57eb51 100644 --- a/extensions/whatsapp/package.json +++ b/extensions/whatsapp/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/whatsapp", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot WhatsApp channel plugin", "clawdbot": { diff --git a/extensions/zalo/package.json b/extensions/zalo/package.json index a3a87a878..8f077a6b3 100644 --- a/extensions/zalo/package.json +++ b/extensions/zalo/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/zalo", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Zalo channel plugin", "clawdbot": { diff --git a/extensions/zalouser/package.json b/extensions/zalouser/package.json index 513295b46..0ab93d1ce 100644 --- a/extensions/zalouser/package.json +++ b/extensions/zalouser/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/zalouser", - "version": "2026.1.24", + "version": "2026.1.25", "type": "module", "description": "Clawdbot Zalo Personal Account plugin via zca-cli", "dependencies": { diff --git a/package.json b/package.json index 5d77e25d0..2a841139f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clawdbot", - "version": "2026.1.24-3", + "version": "2026.1.25", "description": "WhatsApp gateway CLI (Baileys web) with Pi RPC agent", "type": "module", "main": "dist/index.js", @@ -220,7 +220,7 @@ "@types/proper-lockfile": "^4.1.4", "@types/qrcode-terminal": "^0.12.2", "@types/ws": "^8.18.1", - "@typescript/native-preview": "7.0.0-dev.20260124.1", + "@typescript/native-preview": "7.0.0-dev.20260125.1", "@vitest/coverage-v8": "^4.0.18", "docx-preview": "^0.3.7", "lit": "^3.3.2", From 5c231fc21f7d458edf2d766da336c817fb9796de Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:01:38 -0600 Subject: [PATCH 011/196] Doctor: warn on gateway exposure (#2016) Co-authored-by: Alex Alaniz --- CHANGELOG.md | 2 +- src/commands/doctor-security.ts | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afdbb8463..cacc265a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ Docs: https://docs.clawd.bot Status: unreleased. ### Changes -- TBD. +- Doctor: warn on gateway exposure without auth. (#2016) Thanks @Alex-Alaniz. ## 2026.1.24-3 diff --git a/src/commands/doctor-security.ts b/src/commands/doctor-security.ts index b3d82247f..483917faa 100644 --- a/src/commands/doctor-security.ts +++ b/src/commands/doctor-security.ts @@ -10,6 +10,61 @@ export async function noteSecurityWarnings(cfg: ClawdbotConfig) { const warnings: string[] = []; const auditHint = `- Run: ${formatCliCommand("clawdbot security audit --deep")}`; + // =========================================== + // GATEWAY NETWORK EXPOSURE CHECK + // =========================================== + // Check for dangerous gateway binding configurations + // that expose the gateway to network without proper auth + + const gatewayBind = cfg.gateway?.bind ?? "loopback"; + const customBindHost = cfg.gateway?.customBindHost?.trim(); + const authMode = cfg.gateway?.auth?.mode ?? "off"; + const authToken = cfg.gateway?.auth?.token; + const authPassword = cfg.gateway?.auth?.password; + + const isLoopbackBindHost = (host: string) => { + const normalized = host.trim().toLowerCase(); + return ( + normalized === "localhost" || + normalized === "::1" || + normalized === "[::1]" || + normalized.startsWith("127.") + ); + }; + + // Bindings that expose gateway beyond localhost + const exposedBindings = ["all", "lan", "0.0.0.0"]; + const isExposed = + exposedBindings.includes(gatewayBind) || + (gatewayBind === "custom" && (!customBindHost || !isLoopbackBindHost(customBindHost))); + + if (isExposed) { + if (authMode === "off") { + warnings.push( + `- CRITICAL: Gateway bound to "${gatewayBind}" with NO authentication.`, + ` Anyone on your network (or internet if port-forwarded) can fully control your agent.`, + ` Fix: ${formatCliCommand("clawdbot config set gateway.bind loopback")}`, + ` Or enable auth: ${formatCliCommand("clawdbot config set gateway.auth.mode token")}`, + ); + } else if (authMode === "token" && !authToken) { + warnings.push( + `- CRITICAL: Gateway bound to "${gatewayBind}" with empty auth token.`, + ` Fix: ${formatCliCommand("clawdbot doctor --fix")} to generate a token`, + ); + } else if (authMode === "password" && !authPassword) { + warnings.push( + `- CRITICAL: Gateway bound to "${gatewayBind}" with empty password.`, + ` Fix: ${formatCliCommand("clawdbot configure")} to set a password`, + ); + } else { + // Auth is configured, but still warn about network exposure + warnings.push( + `- WARNING: Gateway bound to "${gatewayBind}" (network-accessible).`, + ` Ensure your auth credentials are strong and not exposed.`, + ); + } + } + const warnDmPolicy = async (params: { label: string; provider: ChannelId; From 44bf454508322964c66f7c35f72fb935d8608617 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:02:28 -0600 Subject: [PATCH 012/196] Docs: update clawtributors --- README.md | 55 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index ebbdc43d5..47f3a9090 100644 --- a/README.md +++ b/README.md @@ -479,31 +479,32 @@ Thanks to all clawtributors:

steipete plum-dawg bohdanpodvirnyi iHildy joaohlisboa mneves75 MatthieuBizien MaudeBot Glucksberg rahthakor vrknetha radek-paclt Tobias Bischoff joshp123 czekaj mukhtharcm sebslight maxsumrall xadenryan rodrigouroz - juanpablodlc hsrvc magimetal meaningfool tyler6204 patelhiren NicholasSpisak jonisjongithub abhisekbasu1 zerone0x - jamesgroat claude JustYannicc SocialNerd42069 Hyaxia dantelex daveonkels google-labs-jules[bot] lc0rp mousberg - vignesh07 mteam88 Eng. Juan Combetto Mariano Belinky dbhurley TSavo julianengel bradleypriest benithors rohannagpal - timolins benostein f-trycua nachx639 pvoo sreekaransrinath gupsammy cristip73 stefangalescu nachoiacovino - Vasanth Rao Naik Sabavat petter-b cpojer scald gumadeiras andranik-sahakyan davidguttman sleontenko denysvitali sircrumpet - peschee rafaelreis-r thewilloftheshadow ratulsarna lutr0 danielz1z emanuelst KristijanJovanovski CashWilliams rdev - osolmaz joshrad-dev kiranjd adityashaw2 sheeek artuskg Takhoffman onutc pauloportella neooriginal - manuelhettich minghinmatthewlam myfunc travisirby buddyh connorshea kyleok mcinteerj dependabot[bot] John-Rood - timkrase uos-status gerardward2007 obviyus roshanasingh4 tosh-hamburg azade-c bjesuiter cheeeee Josh Phillips - robbyczgw-cla dlauer pookNast Whoaa512 YuriNachos chriseidhof ngutman ysqander aj47 superman32432432 - Yurii Chukhlib grp06 antons austinm911 blacksmith-sh[bot] damoahdominic dan-dr HeimdallStrategy imfing jalehman - jarvis-medmatic kkarimi mahmoudashraf93 pkrmf RandyVentures Ryan Lisse dougvk erikpr1994 Ghost jonasjancarik - Keith the Silly Goose L36 Server Marc mitschabaude-bot mkbehr neist sibbl chrisrodz Friederike Seiler gabriel-trigo - iamadig Jonathan D. Rhyne (DJ-D) Kit koala73 manmal ogulcancelik pasogott petradonka rubyrunsstuff siddhantjain - suminhthanh svkozak VACInc wes-davis zats 24601 adam91holt ameno- Chris Taylor Django Navarro - evalexpr henrino3 humanwritten larlyssa odysseus0 oswalpalash pcty-nextgen-service-account Syhids Aaron Konyer aaronveklabs - andreabadesso Andrii cash-echo-bot Clawd ClawdFx dguido EnzeD erik-agens Evizero fcatuhe - itsjaydesu ivancasco ivanrvpereira jayhickey jeffersonwarrior jeffersonwarrior jverdi longmaba mickahouan mjrussell - odnxe p6l-richard philipp-spiess robaxelsen Sash Catanzarite T5-AndyML travisp VAC william arzt zknicker - abhaymundhara alejandro maza andrewting19 anpoirier arthyn Asleep123 bolismauro conhecendoia dasilva333 Developer - Dimitrios Ploutarchos Drake Thomsen fal3 Felix Krause ganghyun kim grrowl gtsifrikas HazAT hrdwdmrbl hugobarauna - Jamie Openshaw Jarvis Jefferson Nunn Kevin Lin levifig Lloyd loukotal louzhixian martinpucik Matt mini - Miles mrdbstn MSch Mustafa Tag Eldeen ndraiman nexty5870 prathamdby ptn1411 reeltimeapps RLTCmpe - Rolf Fredheim Rony Kelner Samrat Jha senoldogann Seredeep sergical shiv19 siraht snopoke testingabc321 - The Admiral thesash Ubuntu voidserf Vultr-Clawd Admin Wimmie wstock yazinsai ymat19 Zach Knickerbocker - aaronn Alphonse-arianee Azade carlulsoe ddyo Erik latitudeki5223 Manuel Maly Mourad Boustani odrobnik - pcty-nextgen-ios-builder Quentin Randy Torres rhjoh ronak-guliani William Stock + juanpablodlc hsrvc magimetal meaningfool tyler6204 patelhiren NicholasSpisak jonisjongithub zerone0x abhisekbasu1 + jamesgroat claude JustYannicc Hyaxia dantelex SocialNerd42069 daveonkels google-labs-jules[bot] lc0rp mousberg + vignesh07 mteam88 dbhurley Mariano Belinky Eng. Juan Combetto TSavo julianengel bradleypriest benithors rohannagpal + timolins f-trycua benostein nachx639 pvoo sreekaransrinath gupsammy cristip73 stefangalescu nachoiacovino + Vasanth Rao Naik Sabavat petter-b cpojer scald gumadeiras andranik-sahakyan davidguttman sleontenko denysvitali orlyjamie + sircrumpet peschee rafaelreis-r thewilloftheshadow ratulsarna lutr0 danielz1z emanuelst KristijanJovanovski rdev + joshrad-dev kiranjd osolmaz adityashaw2 CashWilliams sheeek artuskg Takhoffman onutc pauloportella + neooriginal manuelhettich minghinmatthewlam myfunc travisirby buddyh connorshea kyleok mcinteerj dependabot[bot] + John-Rood timkrase uos-status gerardward2007 obviyus roshanasingh4 tosh-hamburg azade-c JonUleis bjesuiter + cheeeee Josh Phillips robbyczgw-cla dlauer pookNast Whoaa512 YuriNachos chriseidhof ngutman ysqander + aj47 superman32432432 Yurii Chukhlib grp06 antons austinm911 blacksmith-sh[bot] damoahdominic dan-dr HeimdallStrategy + imfing jalehman jarvis-medmatic kkarimi mahmoudashraf93 pkrmf RandyVentures Ryan Lisse dougvk erikpr1994 + Ghost jonasjancarik Keith the Silly Goose L36 Server Marc mitschabaude-bot mkbehr neist sibbl chrisrodz + Friederike Seiler gabriel-trigo iamadig Jonathan D. Rhyne (DJ-D) Kit koala73 manmal ogulcancelik pasogott petradonka + rubyrunsstuff siddhantjain suminhthanh svkozak VACInc wes-davis zats 24601 adam91holt ameno- + Chris Taylor Django Navarro evalexpr henrino3 humanwritten larlyssa odysseus0 oswalpalash pcty-nextgen-service-account rmorse + Syhids Aaron Konyer aaronveklabs andreabadesso Andrii cash-echo-bot Clawd ClawdFx dguido EnzeD + erik-agens Evizero fcatuhe itsjaydesu ivancasco ivanrvpereira jayhickey jeffersonwarrior jeffersonwarrior jverdi + longmaba mickahouan mjrussell odnxe p6l-richard philipp-spiess robaxelsen Sash Catanzarite T5-AndyML travisp + VAC william arzt zknicker abhaymundhara alejandro maza andrewting19 anpoirier arthyn Asleep123 bolismauro + conhecendoia dasilva333 Developer Dimitrios Ploutarchos Drake Thomsen fal3 Felix Krause foeken ganghyun kim grrowl + gtsifrikas HazAT hrdwdmrbl hugobarauna Jamie Openshaw Jarvis Jefferson Nunn Kevin Lin kitze levifig + Lloyd loukotal louzhixian martinpucik Matt mini Miles mrdbstn MSch Mustafa Tag Eldeen ndraiman + nexty5870 Noctivoro prathamdby ptn1411 reeltimeapps RLTCmpe Rolf Fredheim Rony Kelner Samrat Jha senoldogann + Seredeep sergical shiv19 shiyuanhai siraht snopoke testingabc321 The Admiral thesash Ubuntu + voidserf Vultr-Clawd Admin Wimmie wstock yazinsai ymat19 Zach Knickerbocker aaronn Alphonse-arianee Azade + carlulsoe ddyo Erik latitudeki5223 Manuel Maly Mourad Boustani odrobnik pcty-nextgen-ios-builder Quentin Randy Torres + rhjoh ronak-guliani William Stock

From 7ea4b06a046ad1bdf979941c605e0fbea81a664d Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:05:00 -0600 Subject: [PATCH 013/196] Deps: revert native-preview to published version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2a841139f..0c63d5d69 100644 --- a/package.json +++ b/package.json @@ -220,7 +220,7 @@ "@types/proper-lockfile": "^4.1.4", "@types/qrcode-terminal": "^0.12.2", "@types/ws": "^8.18.1", - "@typescript/native-preview": "7.0.0-dev.20260125.1", + "@typescript/native-preview": "7.0.0-dev.20260124.1", "@vitest/coverage-v8": "^4.0.18", "docx-preview": "^0.3.7", "lit": "^3.3.2", From 138916a0d1a20e613dd2db98239877244c5ad1e9 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:11:21 -0600 Subject: [PATCH 014/196] Deps: sync memory-core lockfile spec --- pnpm-lock.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 781a461a9..14bef9f5c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -357,7 +357,7 @@ importers: extensions/memory-core: dependencies: clawdbot: - specifier: '>=2026.1.24' + specifier: '>=2026.1.25' version: link:../.. extensions/memory-lancedb: From 9c26cded75615cdd2683981a21633b4b6fb799fa Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:22:10 -0600 Subject: [PATCH 015/196] Docs: add Vercel AI Gateway sidebar entry (#1901) Co-authored-by: Jerilyn Zheng --- CHANGELOG.md | 1 + docs/docs.json | 1 + docs/providers/vercel-ai-gateway.md | 1 + 3 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cacc265a3..5e4a7005d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Status: unreleased. ### Changes - Doctor: warn on gateway exposure without auth. (#2016) Thanks @Alex-Alaniz. +- Docs: add Vercel AI Gateway to providers sidebar. (#1901) Thanks @jerilynzheng. ## 2026.1.24-3 diff --git a/docs/docs.json b/docs/docs.json index 09b248990..4af7943e0 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -983,6 +983,7 @@ "bedrock", "providers/moonshot", "providers/minimax", + "providers/vercel-ai-gateway", "providers/openrouter", "providers/synthetic", "providers/opencode", diff --git a/docs/providers/vercel-ai-gateway.md b/docs/providers/vercel-ai-gateway.md index bd31f0a87..36cf51cda 100644 --- a/docs/providers/vercel-ai-gateway.md +++ b/docs/providers/vercel-ai-gateway.md @@ -1,4 +1,5 @@ --- +title: "Vercel AI Gateway" summary: "Vercel AI Gateway setup (auth + model selection)" read_when: - You want to use Vercel AI Gateway with Clawdbot From c7fabb43f98e27c95fffc656dded87e7a9371355 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:23:40 -0600 Subject: [PATCH 016/196] Agents: expand cron tool description (#1988) Co-authored-by: Tomas Cupr --- CHANGELOG.md | 1 + src/agents/tools/cron-tool.ts | 46 +++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e4a7005d..44a2e6021 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Status: unreleased. ### Changes - Doctor: warn on gateway exposure without auth. (#2016) Thanks @Alex-Alaniz. - Docs: add Vercel AI Gateway to providers sidebar. (#1901) Thanks @jerilynzheng. +- Agents: expand cron tool description with full schema docs. (#1988) Thanks @tomascupr. ## 2026.1.24-3 diff --git a/src/agents/tools/cron-tool.ts b/src/agents/tools/cron-tool.ts index a1d218dd7..739b3ada3 100644 --- a/src/agents/tools/cron-tool.ts +++ b/src/agents/tools/cron-tool.ts @@ -133,8 +133,50 @@ export function createCronTool(opts?: CronToolOptions): AnyAgentTool { return { label: "Cron", name: "cron", - description: - "Manage Gateway cron jobs (status/list/add/update/remove/run/runs) and send wake events. Use `jobId` as the canonical identifier; `id` is accepted for compatibility. Use `contextMessages` (0-10) to add previous messages as context to the job text.", + description: `Manage Gateway cron jobs (status/list/add/update/remove/run/runs) and send wake events. + +ACTIONS: +- status: Check cron scheduler status +- list: List jobs (use includeDisabled:true to include disabled) +- add: Create job (requires job object, see schema below) +- update: Modify job (requires jobId + patch object) +- remove: Delete job (requires jobId) +- run: Trigger job immediately (requires jobId) +- runs: Get job run history (requires jobId) +- wake: Send wake event (requires text, optional mode) + +JOB SCHEMA (for add action): +{ + "name": "string (optional)", + "schedule": { ... }, // Required: when to run + "payload": { ... }, // Required: what to execute + "sessionTarget": "main" | "isolated", // Required + "enabled": true | false // Optional, default true +} + +SCHEDULE TYPES (schedule.kind): +- "at": One-shot at absolute time + { "kind": "at", "atMs": } +- "every": Recurring interval + { "kind": "every", "everyMs": , "anchorMs": } +- "cron": Cron expression + { "kind": "cron", "expr": "", "tz": "" } + +PAYLOAD TYPES (payload.kind): +- "systemEvent": Injects text as system event into session + { "kind": "systemEvent", "text": "" } +- "agentTurn": Runs agent with message (isolated sessions only) + { "kind": "agentTurn", "message": "", "model": "", "thinking": "", "timeoutSeconds": , "deliver": , "channel": "", "to": "", "bestEffortDeliver": } + +CRITICAL CONSTRAINTS: +- sessionTarget="main" REQUIRES payload.kind="systemEvent" +- sessionTarget="isolated" REQUIRES payload.kind="agentTurn" + +WAKE MODES (for wake action): +- "next-heartbeat" (default): Wake on next heartbeat +- "now": Wake immediately + +Use jobId as the canonical identifier; id is accepted for compatibility. Use contextMessages (0-10) to add previous messages as context to the job text.`, parameters: CronToolSchema, execute: async (_toolCallId, args) => { const params = args as Record; From a21671ed5b3f034aa89940a53e375d19b199b1de Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:25:08 -0600 Subject: [PATCH 017/196] Skills: add missing dependency metadata (#1995) Co-authored-by: jackheuberger --- CHANGELOG.md | 1 + skills/discord/SKILL.md | 1 + skills/github/SKILL.md | 1 + skills/notion/SKILL.md | 2 +- skills/slack/SKILL.md | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44a2e6021..425b21b1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Status: unreleased. - Doctor: warn on gateway exposure without auth. (#2016) Thanks @Alex-Alaniz. - Docs: add Vercel AI Gateway to providers sidebar. (#1901) Thanks @jerilynzheng. - Agents: expand cron tool description with full schema docs. (#1988) Thanks @tomascupr. +- Skills: add missing dependency metadata for GitHub, Notion, Slack, Discord. (#1995) Thanks @jackheuberger. ## 2026.1.24-3 diff --git a/skills/discord/SKILL.md b/skills/discord/SKILL.md index 0b64f14e1..5525a3bf5 100644 --- a/skills/discord/SKILL.md +++ b/skills/discord/SKILL.md @@ -1,6 +1,7 @@ --- name: discord description: Use when you need to control Discord from Clawdbot via the discord tool: send messages, react, post or upload stickers, upload emojis, run polls, manage threads/pins/search, create/edit/delete channels and categories, fetch permissions or member/role/channel info, or handle moderation actions in Discord DMs or channels. +metadata: {"clawdbot":{"emoji":"🎮","requires":{"config":["channels.discord"]}}} --- # Discord Actions diff --git a/skills/github/SKILL.md b/skills/github/SKILL.md index 03b2a0033..e7c89f7ba 100644 --- a/skills/github/SKILL.md +++ b/skills/github/SKILL.md @@ -1,6 +1,7 @@ --- name: github description: "Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries." +metadata: {"clawdbot":{"emoji":"🐙","requires":{"bins":["gh"]},"install":[{"id":"brew","kind":"brew","formula":"gh","bins":["gh"],"label":"Install GitHub CLI (brew)"},{"id":"apt","kind":"apt","package":"gh","bins":["gh"],"label":"Install GitHub CLI (apt)"}]}} --- # GitHub Skill diff --git a/skills/notion/SKILL.md b/skills/notion/SKILL.md index 869871b3c..04921e250 100644 --- a/skills/notion/SKILL.md +++ b/skills/notion/SKILL.md @@ -2,7 +2,7 @@ name: notion description: Notion API for creating and managing pages, databases, and blocks. homepage: https://developers.notion.com -metadata: {"clawdbot":{"emoji":"📝"}} +metadata: {"clawdbot":{"emoji":"📝","requires":{"env":["NOTION_API_KEY"]},"primaryEnv":"NOTION_API_KEY"}} --- # notion diff --git a/skills/slack/SKILL.md b/skills/slack/SKILL.md index df04f858f..b72bab1f3 100644 --- a/skills/slack/SKILL.md +++ b/skills/slack/SKILL.md @@ -1,6 +1,7 @@ --- name: slack description: Use when you need to control Slack from Clawdbot via the slack tool, including reacting to messages or pinning/unpinning items in Slack channels or DMs. +metadata: {"clawdbot":{"emoji":"💬","requires":{"config":["channels.slack"]}}} --- # Slack Actions From 136f0d4d1d5028516f4824314a6db5ebd06871af Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:28:53 -0600 Subject: [PATCH 018/196] Docs: add Render deployment guide (#1975) Co-authored-by: Anurag Goel --- CHANGELOG.md | 1 + docs/docs.json | 1 + docs/render.mdx | 158 ++++++++++++++++++++++++++++++++++++++++++++++++ render.yaml | 21 +++++++ 4 files changed, 181 insertions(+) create mode 100644 docs/render.mdx create mode 100644 render.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 425b21b1e..6abd9fc53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Status: unreleased. - Docs: add Vercel AI Gateway to providers sidebar. (#1901) Thanks @jerilynzheng. - Agents: expand cron tool description with full schema docs. (#1988) Thanks @tomascupr. - Skills: add missing dependency metadata for GitHub, Notion, Slack, Discord. (#1995) Thanks @jackheuberger. +- Docs: add Render deployment guide. (#1975) Thanks @anurag. ## 2026.1.24-3 diff --git a/docs/docs.json b/docs/docs.json index 4af7943e0..983585bff 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -827,6 +827,7 @@ "install/nix", "install/docker", "railway", + "render", "install/bun" ] }, diff --git a/docs/render.mdx b/docs/render.mdx new file mode 100644 index 000000000..3fcdae07a --- /dev/null +++ b/docs/render.mdx @@ -0,0 +1,158 @@ +--- +title: Deploy on Render +--- + +Deploy Clawdbot on Render using Infrastructure as Code. The included `render.yaml` Blueprint defines your entire stack declaratively, service, disk, environment variables, so you can deploy with a single click and version your infrastructure alongside your code. + +## Prerequisites + +- A [Render account](https://render.com) (free tier available) +- An API key from your preferred [model provider](/providers) + +## Deploy with a Render Blueprint + +Deploy to Render + +Clicking this link will: + +1. Create a new Render service from the `render.yaml` Blueprint at the root of this repo. +2. Prompt you to set `SETUP_PASSWORD` +3. Build the Docker image and deploy + +Once deployed, your service URL follows the pattern `https://.onrender.com`. + +## Understanding the Blueprint + +Render Blueprints are YAML files that define your infrastructure. The `render.yaml` in this +repository configures everything needed to run Clawdbot: + +```yaml +services: + - type: web + name: clawdbot + runtime: docker + plan: starter + healthCheckPath: /health + envVars: + - key: PORT + value: "8080" + - key: SETUP_PASSWORD + sync: false # prompts during deploy + - key: CLAWDBOT_STATE_DIR + value: /data/.clawdbot + - key: CLAWDBOT_WORKSPACE_DIR + value: /data/workspace + - key: CLAWDBOT_GATEWAY_TOKEN + generateValue: true # auto-generates a secure token + disk: + name: clawdbot-data + mountPath: /data + sizeGB: 1 +``` + +Key Blueprint features used: + +| Feature | Purpose | +|---------|---------| +| `runtime: docker` | Builds from the repo's Dockerfile | +| `healthCheckPath` | Render monitors `/health` and restarts unhealthy instances | +| `sync: false` | Prompts for value during deploy (secrets) | +| `generateValue: true` | Auto-generates a cryptographically secure value | +| `disk` | Persistent storage that survives redeploys | + +## Choosing a plan + +| Plan | Spin-down | Disk | Best for | +|------|-----------|------|----------| +| Free | After 15 min idle | Not available | Testing, demos | +| Starter | Never | 1GB+ | Personal use, small teams | +| Standard+ | Never | 1GB+ | Production, multiple channels | + +The Blueprint defaults to `starter`. To use free tier, change `plan: free` in your fork's +`render.yaml` (but note: no persistent disk means config resets on each deploy). + +## After deployment + +### Complete the setup wizard + +1. Navigate to `https://.onrender.com/setup` +2. Enter your `SETUP_PASSWORD` +3. Select a model provider and paste your API key +4. Optionally configure messaging channels (Telegram, Discord, Slack) +5. Click **Run setup** + +### Access the Control UI + +The web dashboard is available at `https://.onrender.com/clawdbot`. + +## Render Dashboard features + +### Logs + +View real-time logs in **Dashboard → your service → Logs**. Filter by: +- Build logs (Docker image creation) +- Deploy logs (service startup) +- Runtime logs (application output) + +### Shell access + +For debugging, open a shell session via **Dashboard → your service → Shell**. The persistent disk is mounted at `/data`. + +### Environment variables + +Modify variables in **Dashboard → your service → Environment**. Changes trigger an automatic redeploy. + +### Auto-deploy + +If you use the original Clawdbot repository, Render will not auto-deploy your Clawdbot. To update it, run a manual Blueprint sync from the dashboard. + +## Custom domain + +1. Go to **Dashboard → your service → Settings → Custom Domains** +2. Add your domain +3. Configure DNS as instructed (CNAME to `*.onrender.com`) +4. Render provisions a TLS certificate automatically + +## Scaling + +Render supports horizontal and vertical scaling: + +- **Vertical**: Change the plan to get more CPU/RAM +- **Horizontal**: Increase instance count (Standard plan and above) + +For Clawdbot, vertical scaling is usually sufficient. Horizontal scaling requires sticky sessions or external state management. + +## Backups and migration + +Export your configuration and workspace at any time: + +``` +https://.onrender.com/setup/export +``` + +This downloads a portable backup you can restore on any Clawdbot host. + +## Troubleshooting + +### Service won't start + +Check the deploy logs in the Render Dashboard. Common issues: + +- Missing `SETUP_PASSWORD` — the Blueprint prompts for this, but verify it's set +- Port mismatch — ensure `PORT=8080` matches the Dockerfile's exposed port + +### Slow cold starts (free tier) + +Free tier services spin down after 15 minutes of inactivity. The first request after spin-down takes a few seconds while the container starts. Upgrade to Starter plan for always-on. + +### Data loss after redeploy + +This happens on free tier (no persistent disk). Upgrade to a paid plan, or +regularly export your config via `/setup/export`. + +### Health check failures + +Render expects a 200 response from `/health` within 30 seconds. If builds succeed but deploys fail, the service may be taking too long to start. Check: + +- Build logs for errors +- Whether the container runs locally with `docker build && docker run` diff --git a/render.yaml b/render.yaml new file mode 100644 index 000000000..01923a8f6 --- /dev/null +++ b/render.yaml @@ -0,0 +1,21 @@ +services: + - type: web + name: clawdbot + runtime: docker + plan: starter + healthCheckPath: /health + envVars: + - key: PORT + value: "8080" + - key: SETUP_PASSWORD + sync: false + - key: CLAWDBOT_STATE_DIR + value: /data/.clawdbot + - key: CLAWDBOT_WORKSPACE_DIR + value: /data/workspace + - key: CLAWDBOT_GATEWAY_TOKEN + generateValue: true + disk: + name: clawdbot-data + mountPath: /data + sizeGB: 1 From 6b6284c69cda6193bc0de5d178ed0e8e0ea251e2 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:37:20 -0600 Subject: [PATCH 019/196] CI: add PR labeler + label sync --- .github/labeler.yml | 150 ++++++++++++++++++++++++++++ .github/workflows/auto-response.yml | 59 +++++++++++ .github/workflows/labeler.yml | 17 ++++ scripts/sync-labels.ts | 91 +++++++++++++++++ 4 files changed, 317 insertions(+) create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/auto-response.yml create mode 100644 .github/workflows/labeler.yml create mode 100644 scripts/sync-labels.ts diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000..0f3344acc --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,150 @@ +"channel: bluebubbles": + - "extensions/bluebubbles/**" + - "docs/channels/bluebubbles.md" +"channel: discord": + - "src/discord/**" + - "extensions/discord/**" + - "docs/channels/discord.md" +"channel: googlechat": + - "extensions/googlechat/**" + - "docs/channels/googlechat.md" +"channel: imessage": + - "src/imessage/**" + - "extensions/imessage/**" + - "docs/channels/imessage.md" +"channel: line": + - "extensions/line/**" +"channel: matrix": + - "extensions/matrix/**" + - "docs/channels/matrix.md" +"channel: mattermost": + - "extensions/mattermost/**" + - "docs/channels/mattermost.md" +"channel: msteams": + - "extensions/msteams/**" + - "docs/channels/msteams.md" +"channel: nextcloud-talk": + - "extensions/nextcloud-talk/**" + - "docs/channels/nextcloud-talk.md" +"channel: nostr": + - "extensions/nostr/**" + - "docs/channels/nostr.md" +"channel: signal": + - "src/signal/**" + - "extensions/signal/**" + - "docs/channels/signal.md" +"channel: slack": + - "src/slack/**" + - "extensions/slack/**" + - "docs/channels/slack.md" +"channel: telegram": + - "src/telegram/**" + - "extensions/telegram/**" + - "docs/channels/telegram.md" +"channel: tlon": + - "extensions/tlon/**" + - "docs/channels/tlon.md" +"channel: voice-call": + - "extensions/voice-call/**" +"channel: whatsapp-web": + - "src/web/**" + - "extensions/whatsapp/**" + - "docs/channels/whatsapp.md" +"channel: zalo": + - "extensions/zalo/**" + - "docs/channels/zalo.md" +"channel: zalouser": + - "extensions/zalouser/**" + - "docs/channels/zalouser.md" + +"app: android": + - "apps/android/**" + - "docs/platforms/android.md" +"app: ios": + - "apps/ios/**" + - "docs/platforms/ios.md" +"app: macos": + - "apps/macos/**" + - "docs/platforms/macos.md" + - "docs/platforms/mac/**" +"app: web-ui": + - "ui/**" + - "src/gateway/control-ui.ts" + - "src/gateway/control-ui-shared.ts" + - "src/infra/control-ui-assets.ts" + +"cli": + - "src/cli/**" + - "src/commands/**" + - "src/tui/**" + +"gateway": + - "src/gateway/**" + - "src/daemon/**" + - "docs/gateway/**" + +"docs": + - "docs/**" + - "docs.acp.md" + - "README.md" + - "README-header.png" + - "CHANGELOG.md" + - "CONTRIBUTING.md" + - "SECURITY.md" + +"extensions: bluebubbles": + - "extensions/bluebubbles/**" +"extensions: copilot-proxy": + - "extensions/copilot-proxy/**" +"extensions: diagnostics-otel": + - "extensions/diagnostics-otel/**" +"extensions: discord": + - "extensions/discord/**" +"extensions: google-antigravity-auth": + - "extensions/google-antigravity-auth/**" +"extensions: google-gemini-cli-auth": + - "extensions/google-gemini-cli-auth/**" +"extensions: googlechat": + - "extensions/googlechat/**" +"extensions: imessage": + - "extensions/imessage/**" +"extensions: line": + - "extensions/line/**" +"extensions: llm-task": + - "extensions/llm-task/**" +"extensions: lobster": + - "extensions/lobster/**" +"extensions: matrix": + - "extensions/matrix/**" +"extensions: mattermost": + - "extensions/mattermost/**" +"extensions: memory-core": + - "extensions/memory-core/**" +"extensions: memory-lancedb": + - "extensions/memory-lancedb/**" +"extensions: msteams": + - "extensions/msteams/**" +"extensions: nextcloud-talk": + - "extensions/nextcloud-talk/**" +"extensions: nostr": + - "extensions/nostr/**" +"extensions: open-prose": + - "extensions/open-prose/**" +"extensions: qwen-portal-auth": + - "extensions/qwen-portal-auth/**" +"extensions: signal": + - "extensions/signal/**" +"extensions: slack": + - "extensions/slack/**" +"extensions: telegram": + - "extensions/telegram/**" +"extensions: tlon": + - "extensions/tlon/**" +"extensions: voice-call": + - "extensions/voice-call/**" +"extensions: whatsapp": + - "extensions/whatsapp/**" +"extensions: zalo": + - "extensions/zalo/**" +"extensions: zalouser": + - "extensions/zalouser/**" diff --git a/.github/workflows/auto-response.yml b/.github/workflows/auto-response.yml new file mode 100644 index 000000000..7f242a094 --- /dev/null +++ b/.github/workflows/auto-response.yml @@ -0,0 +1,59 @@ +name: Auto response + +on: + issues: + types: [labeled] + pull_request: + types: [labeled] + +permissions: + issues: write + pull-requests: write + +jobs: + auto-response: + runs-on: ubuntu-latest + steps: + - name: Handle labeled items + uses: actions/github-script@v7 + with: + script: | + const rules = [ + { + label: "skill-clawdhub", + close: true, + message: + "Thanks for the contribution! New skills should be published to Clawdhub for everyone to use. We’re keeping the core lean on skills, so I’m closing this out.", + }, + ]; + + const labelName = context.payload.label?.name; + if (!labelName) { + return; + } + + const rule = rules.find((item) => item.label === labelName); + if (!rule) { + return; + } + + const issueNumber = context.payload.issue?.number ?? context.payload.pull_request?.number; + if (!issueNumber) { + return; + } + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + body: rule.message, + }); + + if (rule.close) { + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + state: "closed", + }); + } diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 000000000..6ec73a1a3 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,17 @@ +name: Labeler + +on: + pull_request_target: + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: write + +jobs: + label: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v5 + with: + configuration-path: .github/labeler.yml diff --git a/scripts/sync-labels.ts b/scripts/sync-labels.ts new file mode 100644 index 000000000..0220e911a --- /dev/null +++ b/scripts/sync-labels.ts @@ -0,0 +1,91 @@ +import { execFileSync } from "node:child_process"; +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; +import yaml from "yaml"; + +type LabelConfig = Record; + +type RepoLabel = { + name: string; + color?: string; +}; + +const COLOR_BY_PREFIX = new Map([ + ["channel", "1d76db"], + ["app", "6f42c1"], + ["extensions", "0e8a16"], + ["docs", "0075ca"], + ["cli", "f9d0c4"], + ["gateway", "d4c5f9"], +]); + +const configPath = resolve(".github/labeler.yml"); +const config = yaml.parse(readFileSync(configPath, "utf8")) as LabelConfig; + +if (!config || typeof config !== "object") { + throw new Error("labeler.yml must be a mapping of label names to globs."); +} + +const labelNames = Object.keys(config).filter(Boolean); +const repo = resolveRepo(); +const existing = fetchExistingLabels(repo); + +const missing = labelNames.filter((label) => !existing.has(label)); +if (!missing.length) { + console.log("All labeler labels already exist."); + process.exit(0); +} + +for (const label of missing) { + const color = pickColor(label); + execFileSync( + "gh", + [ + "api", + "-X", + "POST", + `repos/${repo}/labels`, + "-f", + `name=${label}`, + "-f", + `color=${color}`, + ], + { stdio: "inherit" }, + ); + console.log(`Created label: ${label}`); +} + +function pickColor(label: string): string { + const prefix = label.includes(":") ? label.split(":", 1)[0].trim() : label.trim(); + return COLOR_BY_PREFIX.get(prefix) ?? "ededed"; +} + +function resolveRepo(): string { + const remote = execFileSync("git", ["config", "--get", "remote.origin.url"], { + encoding: "utf8", + }).trim(); + + if (!remote) { + throw new Error("Unable to determine repository from git remote."); + } + + if (remote.startsWith("git@github.com:")) { + return remote.replace("git@github.com:", "").replace(/\.git$/, ""); + } + + if (remote.startsWith("https://github.com/")) { + return remote.replace("https://github.com/", "").replace(/\.git$/, ""); + } + + throw new Error(`Unsupported GitHub remote: ${remote}`); +} + +function fetchExistingLabels(repo: string): Map { + const raw = execFileSync( + "gh", + ["api", `repos/${repo}/labels?per_page=100`, "--paginate"], + { encoding: "utf8" }, + ); + const labels = JSON.parse(raw) as RepoLabel[]; + return new Map(labels.map((label) => [label.name, label])); +} From b25fcaef0f14293886f020231e169be51bb3da45 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:38:44 -0600 Subject: [PATCH 020/196] CI: parse labeler without deps --- scripts/sync-labels.ts | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/scripts/sync-labels.ts b/scripts/sync-labels.ts index 0220e911a..297644c1e 100644 --- a/scripts/sync-labels.ts +++ b/scripts/sync-labels.ts @@ -1,9 +1,6 @@ import { execFileSync } from "node:child_process"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; -import yaml from "yaml"; - -type LabelConfig = Record; type RepoLabel = { name: string; @@ -20,13 +17,12 @@ const COLOR_BY_PREFIX = new Map([ ]); const configPath = resolve(".github/labeler.yml"); -const config = yaml.parse(readFileSync(configPath, "utf8")) as LabelConfig; +const labelNames = extractLabelNames(readFileSync(configPath, "utf8")); -if (!config || typeof config !== "object") { - throw new Error("labeler.yml must be a mapping of label names to globs."); +if (!labelNames.length) { + throw new Error("labeler.yml must declare at least one label."); } -const labelNames = Object.keys(config).filter(Boolean); const repo = resolveRepo(); const existing = fetchExistingLabels(repo); @@ -55,6 +51,26 @@ for (const label of missing) { console.log(`Created label: ${label}`); } +function extractLabelNames(contents: string): string[] { + const labels: string[] = []; + for (const line of contents.split("\n")) { + if (!line.trim() || line.trimStart().startsWith("#")) { + continue; + } + if (/^\s/.test(line)) { + continue; + } + const match = line.match(/^(["'])(.+)\1\s*:/) ?? line.match(/^([^:]+):/); + if (match) { + const name = (match[2] ?? match[1] ?? "").trim(); + if (name) { + labels.push(name); + } + } + } + return labels; +} + function pickColor(label: string): string { const prefix = label.includes(":") ? label.split(":", 1)[0].trim() : label.trim(); return COLOR_BY_PREFIX.get(prefix) ?? "ededed"; From 28fe95ac5ef56c50bb5c7a8c47307fb83060ba71 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:39:44 -0600 Subject: [PATCH 021/196] Docs: note labeler updates --- .github/labeler.yml | 41 ----------------------------------------- AGENTS.md | 1 + 2 files changed, 1 insertion(+), 41 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 0f3344acc..0c3d863cf 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -86,65 +86,24 @@ "docs": - "docs/**" - "docs.acp.md" - - "README.md" - - "README-header.png" - - "CHANGELOG.md" - - "CONTRIBUTING.md" - - "SECURITY.md" -"extensions: bluebubbles": - - "extensions/bluebubbles/**" "extensions: copilot-proxy": - "extensions/copilot-proxy/**" "extensions: diagnostics-otel": - "extensions/diagnostics-otel/**" -"extensions: discord": - - "extensions/discord/**" "extensions: google-antigravity-auth": - "extensions/google-antigravity-auth/**" "extensions: google-gemini-cli-auth": - "extensions/google-gemini-cli-auth/**" -"extensions: googlechat": - - "extensions/googlechat/**" -"extensions: imessage": - - "extensions/imessage/**" -"extensions: line": - - "extensions/line/**" "extensions: llm-task": - "extensions/llm-task/**" "extensions: lobster": - "extensions/lobster/**" -"extensions: matrix": - - "extensions/matrix/**" -"extensions: mattermost": - - "extensions/mattermost/**" "extensions: memory-core": - "extensions/memory-core/**" "extensions: memory-lancedb": - "extensions/memory-lancedb/**" -"extensions: msteams": - - "extensions/msteams/**" -"extensions: nextcloud-talk": - - "extensions/nextcloud-talk/**" -"extensions: nostr": - - "extensions/nostr/**" "extensions: open-prose": - "extensions/open-prose/**" "extensions: qwen-portal-auth": - "extensions/qwen-portal-auth/**" -"extensions: signal": - - "extensions/signal/**" -"extensions: slack": - - "extensions/slack/**" -"extensions: telegram": - - "extensions/telegram/**" -"extensions: tlon": - - "extensions/tlon/**" -"extensions: voice-call": - - "extensions/voice-call/**" -"extensions: whatsapp": - - "extensions/whatsapp/**" -"extensions: zalo": - - "extensions/zalo/**" -"extensions: zalouser": - - "extensions/zalouser/**" diff --git a/AGENTS.md b/AGENTS.md index deed6d9bd..ac85a00d8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,6 +13,7 @@ - Core channel docs: `docs/channels/` - Core channel code: `src/telegram`, `src/discord`, `src/slack`, `src/signal`, `src/imessage`, `src/web` (WhatsApp web), `src/channels`, `src/routing` - Extensions (channel plugins): `extensions/*` (e.g. `extensions/msteams`, `extensions/matrix`, `extensions/zalo`, `extensions/zalouser`, `extensions/voice-call`) +- When adding channels/extensions/apps/docs, review `.github/labeler.yml` for label coverage. ## Docs Linking (Mintlify) - Docs are hosted on Mintlify (docs.clawd.bot). From 9c8e8c5c2d531e58cfe7fe0714a4530fa10c8016 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:45:42 -0600 Subject: [PATCH 022/196] CI: increase Node heap size for macOS checks (#1890) Co-authored-by: Zach Knickerbocker --- .github/workflows/ci.yml | 2 ++ CHANGELOG.md | 1 + 2 files changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fcd8e457c..8cc86bd63 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -342,6 +342,8 @@ jobs: pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true || pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true - name: Run ${{ matrix.task }} + env: + NODE_OPTIONS: --max-old-space-size=4096 run: ${{ matrix.command }} macos-app: diff --git a/CHANGELOG.md b/CHANGELOG.md index 6abd9fc53..93b171b38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Status: unreleased. - Agents: expand cron tool description with full schema docs. (#1988) Thanks @tomascupr. - Skills: add missing dependency metadata for GitHub, Notion, Slack, Discord. (#1995) Thanks @jackheuberger. - Docs: add Render deployment guide. (#1975) Thanks @anurag. +- CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. ## 2026.1.24-3 From 159f6bfddd6c9e596856fdac65b775c67ed5c364 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:02:18 -0600 Subject: [PATCH 023/196] macOS: bump Textual to 0.3.1 (#2033) Co-authored-by: Garric G. Nahapetian --- CHANGELOG.md | 1 + apps/macos/Package.resolved | 4 ++-- apps/shared/ClawdbotKit/Package.swift | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93b171b38..19cea8844 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Status: unreleased. - Skills: add missing dependency metadata for GitHub, Notion, Slack, Discord. (#1995) Thanks @jackheuberger. - Docs: add Render deployment guide. (#1975) Thanks @anurag. - CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. +- macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. ## 2026.1.24-3 diff --git a/apps/macos/Package.resolved b/apps/macos/Package.resolved index ffc524d1c..ef9609649 100644 --- a/apps/macos/Package.resolved +++ b/apps/macos/Package.resolved @@ -123,8 +123,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/gonzalezreal/textual", "state" : { - "revision" : "a03c1e103d88de4ea0dd8320ea1611ec0d4b29b3", - "version" : "0.2.0" + "revision" : "5b06b811c0f5313b6b84bbef98c635a630638c38", + "version" : "0.3.1" } } ], diff --git a/apps/shared/ClawdbotKit/Package.swift b/apps/shared/ClawdbotKit/Package.swift index 076842fce..88dc28b5c 100644 --- a/apps/shared/ClawdbotKit/Package.swift +++ b/apps/shared/ClawdbotKit/Package.swift @@ -15,7 +15,7 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/steipete/ElevenLabsKit", exact: "0.1.0"), - .package(url: "https://github.com/gonzalezreal/textual", exact: "0.2.0"), + .package(url: "https://github.com/gonzalezreal/textual", exact: "0.3.1"), ], targets: [ .target( From 5d2ef89e0367b2301e2a5125e7e644277a803fa7 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:04:41 -0600 Subject: [PATCH 024/196] Browser: add URL fallback for relay tab matching (#1999) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: João Paulo Furtado --- CHANGELOG.md | 1 + src/browser/pw-session.ts | 52 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19cea8844..23d5d51b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Status: unreleased. - Docs: add Render deployment guide. (#1975) Thanks @anurag. - CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. - macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. +- Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. ## 2026.1.24-3 diff --git a/src/browser/pw-session.ts b/src/browser/pw-session.ts index 0c7fa9f48..e1dbcf7a1 100644 --- a/src/browser/pw-session.ts +++ b/src/browser/pw-session.ts @@ -337,12 +337,56 @@ async function pageTargetId(page: Page): Promise { } } -async function findPageByTargetId(browser: Browser, targetId: string): Promise { +async function findPageByTargetId( + browser: Browser, + targetId: string, + cdpUrl?: string, +): Promise { const pages = await getAllPages(browser); + // First, try the standard CDP session approach for (const page of pages) { const tid = await pageTargetId(page).catch(() => null); if (tid && tid === targetId) return page; } + // If CDP sessions fail (e.g., extension relay blocks Target.attachToBrowserTarget), + // fall back to URL-based matching using the /json/list endpoint + if (cdpUrl) { + try { + const baseUrl = cdpUrl + .replace(/\/+$/, "") + .replace(/^ws:/, "http:") + .replace(/\/cdp$/, ""); + const response = await fetch(`${baseUrl}/json/list`); + if (response.ok) { + const targets = (await response.json()) as Array<{ + id: string; + url: string; + title?: string; + }>; + const target = targets.find((t) => t.id === targetId); + if (target) { + // Try to find a page with matching URL + const urlMatch = pages.filter((p) => p.url() === target.url); + if (urlMatch.length === 1) { + return urlMatch[0]; + } + // If multiple URL matches, use index-based matching as fallback + // This works when Playwright and the relay enumerate tabs in the same order + if (urlMatch.length > 1) { + const sameUrlTargets = targets.filter((t) => t.url === target.url); + if (sameUrlTargets.length === urlMatch.length) { + const idx = sameUrlTargets.findIndex((t) => t.id === targetId); + if (idx >= 0 && idx < urlMatch.length) { + return urlMatch[idx]; + } + } + } + } + } + } catch { + // Ignore fetch errors and fall through to return null + } + } return null; } @@ -355,7 +399,7 @@ export async function getPageForTargetId(opts: { if (!pages.length) throw new Error("No pages available in the connected browser."); const first = pages[0]; if (!opts.targetId) return first; - const found = await findPageByTargetId(browser, opts.targetId); + const found = await findPageByTargetId(browser, opts.targetId, opts.cdpUrl); if (!found) { // Extension relays can block CDP attachment APIs (e.g. Target.attachToBrowserTarget), // which prevents us from resolving a page's targetId via newCDPSession(). If Playwright @@ -496,7 +540,7 @@ export async function closePageByTargetIdViaPlaywright(opts: { targetId: string; }): Promise { const { browser } = await connectBrowser(opts.cdpUrl); - const page = await findPageByTargetId(browser, opts.targetId); + const page = await findPageByTargetId(browser, opts.targetId, opts.cdpUrl); if (!page) { throw new Error("tab not found"); } @@ -512,7 +556,7 @@ export async function focusPageByTargetIdViaPlaywright(opts: { targetId: string; }): Promise { const { browser } = await connectBrowser(opts.cdpUrl); - const page = await findPageByTargetId(browser, opts.targetId); + const page = await findPageByTargetId(browser, opts.targetId, opts.cdpUrl); if (!page) { throw new Error("tab not found"); } From 6d60c325700e26ad0876be74ceb29d1b0e3a4648 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:07:51 -0600 Subject: [PATCH 025/196] Update: ignore dist/control-ui in dirty check (#1976) Co-authored-by: Glucksberg --- CHANGELOG.md | 1 + src/infra/update-check.ts | 7 ++++--- src/infra/update-runner.test.ts | 7 ++++--- src/infra/update-runner.ts | 19 +++++++++++++++++-- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23d5d51b3..a1e2a9d08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Status: unreleased. - CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. - macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. - Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. +- Update: ignore dist/control-ui for dirty checks and restore after ui builds. (#1976) Thanks @Glucksberg. ## 2026.1.24-3 diff --git a/src/infra/update-check.ts b/src/infra/update-check.ts index 2e020ff8d..518da3c28 100644 --- a/src/infra/update-check.ts +++ b/src/infra/update-check.ts @@ -129,9 +129,10 @@ export async function checkGitUpdateStatus(params: { ).catch(() => null); const upstream = upstreamRes && upstreamRes.code === 0 ? upstreamRes.stdout.trim() : null; - const dirtyRes = await runCommandWithTimeout(["git", "-C", root, "status", "--porcelain"], { - timeoutMs, - }).catch(() => null); + const dirtyRes = await runCommandWithTimeout( + ["git", "-C", root, "status", "--porcelain", "--", ":!dist/control-ui/"], + { timeoutMs }, + ).catch(() => null); const dirty = dirtyRes && dirtyRes.code === 0 ? dirtyRes.stdout.trim().length > 0 : null; const fetchOk = params.fetch diff --git a/src/infra/update-runner.test.ts b/src/infra/update-runner.test.ts index e33159326..6bf450d83 100644 --- a/src/infra/update-runner.test.ts +++ b/src/infra/update-runner.test.ts @@ -44,7 +44,7 @@ describe("runGatewayUpdate", () => { [`git -C ${tempDir} rev-parse --show-toplevel`]: { stdout: tempDir }, [`git -C ${tempDir} rev-parse HEAD`]: { stdout: "abc123" }, [`git -C ${tempDir} rev-parse --abbrev-ref HEAD`]: { stdout: "main" }, - [`git -C ${tempDir} status --porcelain`]: { stdout: " M README.md" }, + [`git -C ${tempDir} status --porcelain -- :!dist/control-ui/`]: { stdout: " M README.md" }, }); const result = await runGatewayUpdate({ @@ -69,7 +69,7 @@ describe("runGatewayUpdate", () => { [`git -C ${tempDir} rev-parse --show-toplevel`]: { stdout: tempDir }, [`git -C ${tempDir} rev-parse HEAD`]: { stdout: "abc123" }, [`git -C ${tempDir} rev-parse --abbrev-ref HEAD`]: { stdout: "main" }, - [`git -C ${tempDir} status --porcelain`]: { stdout: "" }, + [`git -C ${tempDir} status --porcelain -- :!dist/control-ui/`]: { stdout: "" }, [`git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`]: { stdout: "origin/main", }, @@ -103,7 +103,7 @@ describe("runGatewayUpdate", () => { const { runner, calls } = createRunner({ [`git -C ${tempDir} rev-parse --show-toplevel`]: { stdout: tempDir }, [`git -C ${tempDir} rev-parse HEAD`]: { stdout: "abc123" }, - [`git -C ${tempDir} status --porcelain`]: { stdout: "" }, + [`git -C ${tempDir} status --porcelain -- :!dist/control-ui/`]: { stdout: "" }, [`git -C ${tempDir} fetch --all --prune --tags`]: { stdout: "" }, [`git -C ${tempDir} tag --list v* --sort=-v:refname`]: { stdout: `${stableTag}\n${betaTag}\n`, @@ -112,6 +112,7 @@ describe("runGatewayUpdate", () => { "pnpm install": { stdout: "" }, "pnpm build": { stdout: "" }, "pnpm ui:build": { stdout: "" }, + [`git -C ${tempDir} checkout -- dist/control-ui/`]: { stdout: "" }, "pnpm clawdbot doctor --non-interactive": { stdout: "" }, }); diff --git a/src/infra/update-runner.ts b/src/infra/update-runner.ts index 0a5196fd7..c73c3a7e7 100644 --- a/src/infra/update-runner.ts +++ b/src/infra/update-runner.ts @@ -346,10 +346,14 @@ export async function runGatewayUpdate(opts: UpdateRunnerOptions = {}): Promise< const channel: UpdateChannel = opts.channel ?? "dev"; const branch = channel === "dev" ? await readBranchName(runCommand, gitRoot, timeoutMs) : null; const needsCheckoutMain = channel === "dev" && branch !== DEV_BRANCH; - gitTotalSteps = channel === "dev" ? (needsCheckoutMain ? 10 : 9) : 8; + gitTotalSteps = channel === "dev" ? (needsCheckoutMain ? 11 : 10) : 9; const statusCheck = await runStep( - step("clean check", ["git", "-C", gitRoot, "status", "--porcelain"], gitRoot), + step( + "clean check", + ["git", "-C", gitRoot, "status", "--porcelain", "--", ":!dist/control-ui/"], + gitRoot, + ), ); steps.push(statusCheck); const hasUncommittedChanges = @@ -654,6 +658,17 @@ export async function runGatewayUpdate(opts: UpdateRunnerOptions = {}): Promise< ); steps.push(uiBuildStep); + // Restore dist/control-ui/ to committed state to prevent dirty repo after update + // (ui:build regenerates assets with new hashes, which would block future updates) + const restoreUiStep = await runStep( + step( + "restore control-ui", + ["git", "-C", gitRoot, "checkout", "--", "dist/control-ui/"], + gitRoot, + ), + ); + steps.push(restoreUiStep); + const doctorStep = await runStep( step( "clawdbot doctor", From a989fe8af92e5630f6b0f51e4156a0a21a47c346 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:08:12 -0600 Subject: [PATCH 026/196] CI: update labeler v5 config --- .github/labeler.yml | 205 +++++++++++++++++++++++++++++--------------- 1 file changed, 134 insertions(+), 71 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 0c3d863cf..5b34c41e0 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,109 +1,172 @@ "channel: bluebubbles": - - "extensions/bluebubbles/**" - - "docs/channels/bluebubbles.md" + - changed-files: + - any-glob-to-any-file: + - "extensions/bluebubbles/**" + - "docs/channels/bluebubbles.md" "channel: discord": - - "src/discord/**" - - "extensions/discord/**" - - "docs/channels/discord.md" + - changed-files: + - any-glob-to-any-file: + - "src/discord/**" + - "extensions/discord/**" + - "docs/channels/discord.md" "channel: googlechat": - - "extensions/googlechat/**" - - "docs/channels/googlechat.md" + - changed-files: + - any-glob-to-any-file: + - "extensions/googlechat/**" + - "docs/channels/googlechat.md" "channel: imessage": - - "src/imessage/**" - - "extensions/imessage/**" - - "docs/channels/imessage.md" + - changed-files: + - any-glob-to-any-file: + - "src/imessage/**" + - "extensions/imessage/**" + - "docs/channels/imessage.md" "channel: line": - - "extensions/line/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/line/**" "channel: matrix": - - "extensions/matrix/**" - - "docs/channels/matrix.md" + - changed-files: + - any-glob-to-any-file: + - "extensions/matrix/**" + - "docs/channels/matrix.md" "channel: mattermost": - - "extensions/mattermost/**" - - "docs/channels/mattermost.md" + - changed-files: + - any-glob-to-any-file: + - "extensions/mattermost/**" + - "docs/channels/mattermost.md" "channel: msteams": - - "extensions/msteams/**" - - "docs/channels/msteams.md" + - changed-files: + - any-glob-to-any-file: + - "extensions/msteams/**" + - "docs/channels/msteams.md" "channel: nextcloud-talk": - - "extensions/nextcloud-talk/**" - - "docs/channels/nextcloud-talk.md" + - changed-files: + - any-glob-to-any-file: + - "extensions/nextcloud-talk/**" + - "docs/channels/nextcloud-talk.md" "channel: nostr": - - "extensions/nostr/**" - - "docs/channels/nostr.md" + - changed-files: + - any-glob-to-any-file: + - "extensions/nostr/**" + - "docs/channels/nostr.md" "channel: signal": - - "src/signal/**" - - "extensions/signal/**" - - "docs/channels/signal.md" + - changed-files: + - any-glob-to-any-file: + - "src/signal/**" + - "extensions/signal/**" + - "docs/channels/signal.md" "channel: slack": - - "src/slack/**" - - "extensions/slack/**" - - "docs/channels/slack.md" + - changed-files: + - any-glob-to-any-file: + - "src/slack/**" + - "extensions/slack/**" + - "docs/channels/slack.md" "channel: telegram": - - "src/telegram/**" - - "extensions/telegram/**" - - "docs/channels/telegram.md" + - changed-files: + - any-glob-to-any-file: + - "src/telegram/**" + - "extensions/telegram/**" + - "docs/channels/telegram.md" "channel: tlon": - - "extensions/tlon/**" - - "docs/channels/tlon.md" + - changed-files: + - any-glob-to-any-file: + - "extensions/tlon/**" + - "docs/channels/tlon.md" "channel: voice-call": - - "extensions/voice-call/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/voice-call/**" "channel: whatsapp-web": - - "src/web/**" - - "extensions/whatsapp/**" - - "docs/channels/whatsapp.md" + - changed-files: + - any-glob-to-any-file: + - "src/web/**" + - "extensions/whatsapp/**" + - "docs/channels/whatsapp.md" "channel: zalo": - - "extensions/zalo/**" - - "docs/channels/zalo.md" + - changed-files: + - any-glob-to-any-file: + - "extensions/zalo/**" + - "docs/channels/zalo.md" "channel: zalouser": - - "extensions/zalouser/**" - - "docs/channels/zalouser.md" + - changed-files: + - any-glob-to-any-file: + - "extensions/zalouser/**" + - "docs/channels/zalouser.md" "app: android": - - "apps/android/**" - - "docs/platforms/android.md" + - changed-files: + - any-glob-to-any-file: + - "apps/android/**" + - "docs/platforms/android.md" "app: ios": - - "apps/ios/**" - - "docs/platforms/ios.md" + - changed-files: + - any-glob-to-any-file: + - "apps/ios/**" + - "docs/platforms/ios.md" "app: macos": - - "apps/macos/**" - - "docs/platforms/macos.md" - - "docs/platforms/mac/**" + - changed-files: + - any-glob-to-any-file: + - "apps/macos/**" + - "docs/platforms/macos.md" + - "docs/platforms/mac/**" "app: web-ui": - - "ui/**" - - "src/gateway/control-ui.ts" - - "src/gateway/control-ui-shared.ts" - - "src/infra/control-ui-assets.ts" - -"cli": - - "src/cli/**" - - "src/commands/**" - - "src/tui/**" + - changed-files: + - any-glob-to-any-file: + - "ui/**" + - "src/gateway/control-ui.ts" + - "src/gateway/control-ui-shared.ts" + - "src/infra/control-ui-assets.ts" "gateway": - - "src/gateway/**" - - "src/daemon/**" - - "docs/gateway/**" + - changed-files: + - any-glob-to-any-file: + - "src/gateway/**" + - "src/daemon/**" + - "docs/gateway/**" "docs": - - "docs/**" - - "docs.acp.md" + - changed-files: + - any-glob-to-any-file: + - "docs/**" + - "docs.acp.md" "extensions: copilot-proxy": - - "extensions/copilot-proxy/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/copilot-proxy/**" "extensions: diagnostics-otel": - - "extensions/diagnostics-otel/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/diagnostics-otel/**" "extensions: google-antigravity-auth": - - "extensions/google-antigravity-auth/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/google-antigravity-auth/**" "extensions: google-gemini-cli-auth": - - "extensions/google-gemini-cli-auth/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/google-gemini-cli-auth/**" "extensions: llm-task": - - "extensions/llm-task/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/llm-task/**" "extensions: lobster": - - "extensions/lobster/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/lobster/**" "extensions: memory-core": - - "extensions/memory-core/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/memory-core/**" "extensions: memory-lancedb": - - "extensions/memory-lancedb/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/memory-lancedb/**" "extensions: open-prose": - - "extensions/open-prose/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/open-prose/**" "extensions: qwen-portal-auth": - - "extensions/qwen-portal-auth/**" + - changed-files: + - any-glob-to-any-file: + - "extensions/qwen-portal-auth/**" From 47101da4643ab499831a8b0377422d13f46093da Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:09:31 -0600 Subject: [PATCH 027/196] Telegram: honor caption param for media sends (#1888) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marc Güell Segarra --- CHANGELOG.md | 1 + src/channels/plugins/actions/telegram.ts | 8 +++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1e2a9d08..7bb0a459d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Status: unreleased. - macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. - Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. - Update: ignore dist/control-ui for dirty checks and restore after ui builds. (#1976) Thanks @Glucksberg. +- Telegram: allow caption param for media sends. (#1888) Thanks @mguellsegarra. ## 2026.1.24-3 diff --git a/src/channels/plugins/actions/telegram.ts b/src/channels/plugins/actions/telegram.ts index 18a11c797..fe4e41307 100644 --- a/src/channels/plugins/actions/telegram.ts +++ b/src/channels/plugins/actions/telegram.ts @@ -13,11 +13,9 @@ const providerId = "telegram"; function readTelegramSendParams(params: Record) { const to = readStringParam(params, "to", { required: true }); const mediaUrl = readStringParam(params, "media", { trim: false }); - const content = - readStringParam(params, "message", { - required: !mediaUrl, - allowEmpty: true, - }) ?? ""; + const message = readStringParam(params, "message", { required: !mediaUrl, allowEmpty: true }); + const caption = readStringParam(params, "caption", { allowEmpty: true }); + const content = message || caption || ""; const replyTo = readStringParam(params, "replyTo"); const threadId = readStringParam(params, "threadId"); const buttons = params.buttons; From 84f8f8b10e540d2c89c1c475bdec3c3c94c6d592 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:11:50 -0600 Subject: [PATCH 028/196] Telegram: skip block replies when streaming off (#1885) Co-authored-by: Ivan Casco --- CHANGELOG.md | 1 + src/auto-reply/reply/agent-runner-execution.ts | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bb0a459d..af7ae9ddc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Status: unreleased. - Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. - Update: ignore dist/control-ui for dirty checks and restore after ui builds. (#1976) Thanks @Glucksberg. - Telegram: allow caption param for media sends. (#1888) Thanks @mguellsegarra. +- Telegram: avoid block replies when streaming is disabled. (#1885) Thanks @ivancasco. ## 2026.1.24-3 diff --git a/src/auto-reply/reply/agent-runner-execution.ts b/src/auto-reply/reply/agent-runner-execution.ts index 47c45b09d..939fa92f0 100644 --- a/src/auto-reply/reply/agent-runner-execution.ts +++ b/src/auto-reply/reply/agent-runner-execution.ts @@ -369,12 +369,13 @@ export async function runAgentTurnWithFallback(params: { // Use pipeline if available (block streaming enabled), otherwise send directly if (params.blockStreamingEnabled && params.blockReplyPipeline) { params.blockReplyPipeline.enqueue(blockPayload); - } else { - // Send directly when flushing before tool execution (no streaming). + } else if (params.blockStreamingEnabled) { + // Send directly when flushing before tool execution (no pipeline but streaming enabled). // Track sent key to avoid duplicate in final payloads. directlySentBlockKeys.add(createBlockReplyPayloadKey(blockPayload)); await params.opts?.onBlockReply?.(blockPayload); } + // When streaming is disabled entirely, blocks are accumulated in final text instead. } : undefined, onBlockReplyFlush: From 9ecbb0ae81db993dc05962abef9118b53eb3d599 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:13:36 -0600 Subject: [PATCH 029/196] Auth: print copyable Google auth URL (#1787) Co-authored-by: Robby --- CHANGELOG.md | 1 + extensions/google-antigravity-auth/index.ts | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af7ae9ddc..8d5412dcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Status: unreleased. - Update: ignore dist/control-ui for dirty checks and restore after ui builds. (#1976) Thanks @Glucksberg. - Telegram: allow caption param for media sends. (#1888) Thanks @mguellsegarra. - Telegram: avoid block replies when streaming is disabled. (#1885) Thanks @ivancasco. +- Auth: show copyable Google auth URL after ASCII prompt. (#1787) Thanks @robbyczgw-cla. ## 2026.1.24-3 diff --git a/extensions/google-antigravity-auth/index.ts b/extensions/google-antigravity-auth/index.ts index d6902bffe..f349ada6a 100644 --- a/extensions/google-antigravity-auth/index.ts +++ b/extensions/google-antigravity-auth/index.ts @@ -281,6 +281,7 @@ async function loginAntigravity(params: { openUrl: (url: string) => Promise; prompt: (message: string) => Promise; note: (message: string, title?: string) => Promise; + log: (message: string) => void; progress: { update: (msg: string) => void; stop: (msg?: string) => void }; }): Promise<{ access: string; @@ -314,6 +315,11 @@ async function loginAntigravity(params: { ].join("\n"), "Google Antigravity OAuth", ); + // Output raw URL below the box for easy copying (fixes #1772) + params.log(""); + params.log("Copy this URL:"); + params.log(authUrl); + params.log(""); } if (!needsManual) { @@ -382,6 +388,7 @@ const antigravityPlugin = { openUrl: ctx.openUrl, prompt: async (message) => String(await ctx.prompter.text({ message })), note: ctx.prompter.note, + log: (message) => ctx.runtime.log(message), progress: spin, }); From 73507e8654abf751cce99696e6d91c4ac31ec917 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:15:20 -0600 Subject: [PATCH 030/196] Routing: precompile session key regexes (#1697) Co-authored-by: Ray Tien --- CHANGELOG.md | 1 + src/routing/session-key.ts | 30 ++++++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d5412dcd..e39c291d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Status: unreleased. - Telegram: allow caption param for media sends. (#1888) Thanks @mguellsegarra. - Telegram: avoid block replies when streaming is disabled. (#1885) Thanks @ivancasco. - Auth: show copyable Google auth URL after ASCII prompt. (#1787) Thanks @robbyczgw-cla. +- Routing: precompile session key regexes. (#1697) Thanks @Ray0907. ## 2026.1.24-3 diff --git a/src/routing/session-key.ts b/src/routing/session-key.ts index 028e657cb..7f9f209ed 100644 --- a/src/routing/session-key.ts +++ b/src/routing/session-key.ts @@ -11,6 +11,12 @@ export const DEFAULT_AGENT_ID = "main"; export const DEFAULT_MAIN_KEY = "main"; export const DEFAULT_ACCOUNT_ID = "default"; +// Pre-compiled regex +const VALID_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i; +const INVALID_CHARS_RE = /[^a-z0-9_-]+/g; +const LEADING_DASH_RE = /^-+/; +const TRAILING_DASH_RE = /-+$/; + function normalizeToken(value: string | undefined | null): string { return (value ?? "").trim().toLowerCase(); } @@ -52,14 +58,14 @@ export function normalizeAgentId(value: string | undefined | null): string { const trimmed = (value ?? "").trim(); if (!trimmed) return DEFAULT_AGENT_ID; // Keep it path-safe + shell-friendly. - if (/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(trimmed)) return trimmed.toLowerCase(); + if (VALID_ID_RE.test(trimmed)) return trimmed.toLowerCase(); // Best-effort fallback: collapse invalid characters to "-" return ( trimmed .toLowerCase() - .replace(/[^a-z0-9_-]+/g, "-") - .replace(/^-+/, "") - .replace(/-+$/, "") + .replace(INVALID_CHARS_RE, "-") + .replace(LEADING_DASH_RE, "") + .replace(TRAILING_DASH_RE, "") .slice(0, 64) || DEFAULT_AGENT_ID ); } @@ -67,13 +73,13 @@ export function normalizeAgentId(value: string | undefined | null): string { export function sanitizeAgentId(value: string | undefined | null): string { const trimmed = (value ?? "").trim(); if (!trimmed) return DEFAULT_AGENT_ID; - if (/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(trimmed)) return trimmed.toLowerCase(); + if (VALID_ID_RE.test(trimmed)) return trimmed.toLowerCase(); return ( trimmed .toLowerCase() - .replace(/[^a-z0-9_-]+/gi, "-") - .replace(/^-+/, "") - .replace(/-+$/, "") + .replace(INVALID_CHARS_RE, "-") + .replace(LEADING_DASH_RE, "") + .replace(TRAILING_DASH_RE, "") .slice(0, 64) || DEFAULT_AGENT_ID ); } @@ -81,13 +87,13 @@ export function sanitizeAgentId(value: string | undefined | null): string { export function normalizeAccountId(value: string | undefined | null): string { const trimmed = (value ?? "").trim(); if (!trimmed) return DEFAULT_ACCOUNT_ID; - if (/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(trimmed)) return trimmed.toLowerCase(); + if (VALID_ID_RE.test(trimmed)) return trimmed.toLowerCase(); return ( trimmed .toLowerCase() - .replace(/[^a-z0-9_-]+/g, "-") - .replace(/^-+/, "") - .replace(/-+$/, "") + .replace(INVALID_CHARS_RE, "-") + .replace(LEADING_DASH_RE, "") + .replace(TRAILING_DASH_RE, "") .slice(0, 64) || DEFAULT_ACCOUNT_ID ); } From 1f06f8031e7e16d93d6faee65e999a56179ce19b Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:15:34 -0600 Subject: [PATCH 031/196] CI: use app token for labeler --- .github/workflows/labeler.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 6ec73a1a3..8d078774b 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -12,6 +12,12 @@ jobs: label: runs-on: ubuntu-latest steps: + - uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: "2729701" + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - uses: actions/labeler@v5 with: configuration-path: .github/labeler.yml + repo-token: ${{ steps.app-token.outputs.token }} From 7187c3d06765c9d3a7b1de40430fe1567b174131 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:17:42 -0600 Subject: [PATCH 032/196] TUI: guard against overflow width crashes (#1686) Co-authored-by: Mohammad Jafari --- CHANGELOG.md | 1 + src/tui/components/filterable-select-list.ts | 2 +- src/tui/components/searchable-select-list.ts | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e39c291d2..480767383 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Status: unreleased. - Telegram: avoid block replies when streaming is disabled. (#1885) Thanks @ivancasco. - Auth: show copyable Google auth URL after ASCII prompt. (#1787) Thanks @robbyczgw-cla. - Routing: precompile session key regexes. (#1697) Thanks @Ray0907. +- TUI: avoid width overflow when rendering selection lists. (#1686) Thanks @mossein. ## 2026.1.24-3 diff --git a/src/tui/components/filterable-select-list.ts b/src/tui/components/filterable-select-list.ts index 67361bcf1..a7b197bf5 100644 --- a/src/tui/components/filterable-select-list.ts +++ b/src/tui/components/filterable-select-list.ts @@ -69,7 +69,7 @@ export class FilterableSelectList implements Component { lines.push(filterLabel + inputText); // Separator - lines.push(chalk.dim("─".repeat(width))); + lines.push(chalk.dim("─".repeat(Math.max(0, width)))); // Select list const listLines = this.selectList.render(width); diff --git a/src/tui/components/searchable-select-list.ts b/src/tui/components/searchable-select-list.ts index f8e07e790..54fc34918 100644 --- a/src/tui/components/searchable-select-list.ts +++ b/src/tui/components/searchable-select-list.ts @@ -214,7 +214,8 @@ export class SearchableSelectList implements Component { const maxValueWidth = Math.min(30, width - prefixWidth - 4); const truncatedValue = truncateToWidth(displayValue, maxValueWidth, ""); const valueText = this.highlightMatch(truncatedValue, query); - const spacing = " ".repeat(Math.max(1, 32 - visibleWidth(valueText))); + const spacingWidth = Math.max(1, 32 - visibleWidth(valueText)); + const spacing = " ".repeat(spacingWidth); const descriptionStart = prefixWidth + visibleWidth(valueText) + spacing.length; const remainingWidth = width - descriptionStart - 2; if (remainingWidth > 10) { From 7f6422c8977ce782f15809fda26ae67a1d4c7aa9 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:20:39 -0600 Subject: [PATCH 033/196] Telegram: preserve topic IDs in restart notifications (#1807) Co-authored-by: hsrvc --- CHANGELOG.md | 1 + src/agents/tools/sessions-send-helpers.ts | 24 +++++++++++++++++++++-- src/gateway/server-restart-sentinel.ts | 16 ++++++++++----- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 480767383..dc46291fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Status: unreleased. - Auth: show copyable Google auth URL after ASCII prompt. (#1787) Thanks @robbyczgw-cla. - Routing: precompile session key regexes. (#1697) Thanks @Ray0907. - TUI: avoid width overflow when rendering selection lists. (#1686) Thanks @mossein. +- Telegram: keep topic IDs in restart sentinel notifications. (#1807) Thanks @hsrvc. ## 2026.1.24-3 diff --git a/src/agents/tools/sessions-send-helpers.ts b/src/agents/tools/sessions-send-helpers.ts index 5e758d426..c9940de0f 100644 --- a/src/agents/tools/sessions-send-helpers.ts +++ b/src/agents/tools/sessions-send-helpers.ts @@ -14,6 +14,7 @@ export type AnnounceTarget = { channel: string; to: string; accountId?: string; + threadId?: string; // Forum topic/thread ID }; export function resolveAnnounceTargetFromKey(sessionKey: string): AnnounceTarget | null { @@ -22,7 +23,22 @@ export function resolveAnnounceTargetFromKey(sessionKey: string): AnnounceTarget if (parts.length < 3) return null; const [channelRaw, kind, ...rest] = parts; if (kind !== "group" && kind !== "channel") return null; - const id = rest.join(":").trim(); + + // Extract topic/thread ID from rest (supports both :topic: and :thread:) + // Telegram uses :topic:, other platforms use :thread: + let threadId: string | undefined; + const restJoined = rest.join(":"); + const topicMatch = restJoined.match(/:topic:(\d+)$/); + const threadMatch = restJoined.match(/:thread:(\d+)$/); + const match = topicMatch || threadMatch; + + if (match) { + threadId = match[1]; // Keep as string to match AgentCommandOpts.threadId + } + + // Remove :topic:N or :thread:N suffix from ID for target + const id = match ? restJoined.replace(/:(topic|thread):\d+$/, "") : restJoined.trim(); + if (!id) return null; if (!channelRaw) return null; const normalizedChannel = normalizeAnyChannelId(channelRaw) ?? normalizeChatChannelId(channelRaw); @@ -37,7 +53,11 @@ export function resolveAnnounceTargetFromKey(sessionKey: string): AnnounceTarget const normalized = normalizedChannel ? getChannelPlugin(normalizedChannel)?.messaging?.normalizeTarget?.(kindTarget) : undefined; - return { channel, to: normalized ?? kindTarget }; + return { + channel, + to: normalized ?? kindTarget, + threadId, + }; } export function buildAgentToAgentMessageContext(params: { diff --git a/src/gateway/server-restart-sentinel.ts b/src/gateway/server-restart-sentinel.ts index fa33b7c21..28719290e 100644 --- a/src/gateway/server-restart-sentinel.ts +++ b/src/gateway/server-restart-sentinel.ts @@ -28,11 +28,16 @@ export async function scheduleRestartSentinelWake(params: { deps: CliDeps }) { return; } - const threadMarker = ":thread:"; - const threadIndex = sessionKey.lastIndexOf(threadMarker); - const baseSessionKey = threadIndex === -1 ? sessionKey : sessionKey.slice(0, threadIndex); + // Extract topic/thread ID from sessionKey (supports both :topic: and :thread:) + // Telegram uses :topic:, other platforms use :thread: + const topicIndex = sessionKey.lastIndexOf(":topic:"); + const threadIndex = sessionKey.lastIndexOf(":thread:"); + const markerIndex = Math.max(topicIndex, threadIndex); + const marker = topicIndex > threadIndex ? ":topic:" : ":thread:"; + + const baseSessionKey = markerIndex === -1 ? sessionKey : sessionKey.slice(0, markerIndex); const threadIdRaw = - threadIndex === -1 ? undefined : sessionKey.slice(threadIndex + threadMarker.length); + markerIndex === -1 ? undefined : sessionKey.slice(markerIndex + marker.length); const sessionThreadId = threadIdRaw?.trim() || undefined; const { cfg, entry } = loadSessionEntry(sessionKey); @@ -42,7 +47,7 @@ export async function scheduleRestartSentinelWake(params: { deps: CliDeps }) { // Handles race condition where store wasn't flushed before restart const sentinelContext = payload.deliveryContext; let sessionDeliveryContext = deliveryContextFromSession(entry); - if (!sessionDeliveryContext && threadIndex !== -1 && baseSessionKey) { + if (!sessionDeliveryContext && markerIndex !== -1 && baseSessionKey) { const { entry: baseEntry } = loadSessionEntry(baseSessionKey); sessionDeliveryContext = deliveryContextFromSession(baseEntry); } @@ -74,6 +79,7 @@ export async function scheduleRestartSentinelWake(params: { deps: CliDeps }) { const threadId = payload.threadId ?? + parsedTarget?.threadId ?? // From resolveAnnounceTargetFromKey (extracts :topic:N) sessionThreadId ?? (origin?.threadId != null ? String(origin.threadId) : undefined); From 1b598ad70923e6f6c3f6f7bc12ffc75f06e07004 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:22:25 -0600 Subject: [PATCH 034/196] Config: apply config.env before substitution (#1813) Co-authored-by: SPANISH FLU --- CHANGELOG.md | 1 + src/config/io.ts | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc46291fb..6aacd64aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Status: unreleased. - Routing: precompile session key regexes. (#1697) Thanks @Ray0907. - TUI: avoid width overflow when rendering selection lists. (#1686) Thanks @mossein. - Telegram: keep topic IDs in restart sentinel notifications. (#1807) Thanks @hsrvc. +- Config: apply config.env before ${VAR} substitution. (#1813) Thanks @spanishflu-est1918. ## 2026.1.24-3 diff --git a/src/config/io.ts b/src/config/io.ts index da3a7fb23..9078ef2a2 100644 --- a/src/config/io.ts +++ b/src/config/io.ts @@ -211,6 +211,11 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) { parseJson: (raw) => deps.json5.parse(raw), }); + // Apply config.env to process.env BEFORE substitution so ${VAR} can reference config-defined vars + if (resolved && typeof resolved === "object" && "env" in resolved) { + applyConfigEnv(resolved as ClawdbotConfig, deps.env); + } + // Substitute ${VAR} env var references const substituted = resolveConfigEnvVars(resolved, deps.env); @@ -365,6 +370,11 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) { }; } + // Apply config.env to process.env BEFORE substitution so ${VAR} can reference config-defined vars + if (resolved && typeof resolved === "object" && "env" in resolved) { + applyConfigEnv(resolved as ClawdbotConfig, deps.env); + } + // Substitute ${VAR} env var references let substituted: unknown; try { From 678ad9e3aed137e7ab65736185aacdc468f8e707 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:23:18 -0600 Subject: [PATCH 035/196] CI: expand web-ui label globs --- .github/labeler.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/labeler.yml b/.github/labeler.yml index 5b34c41e0..5d2837a6c 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -115,6 +115,8 @@ - "ui/**" - "src/gateway/control-ui.ts" - "src/gateway/control-ui-shared.ts" + - "src/gateway/protocol/**" + - "src/gateway/server-methods/chat.ts" - "src/infra/control-ui-assets.ts" "gateway": From 7e4e24445e21d0727895a2667ef6eac515e6904c Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:28:46 -0600 Subject: [PATCH 036/196] Slack: clear ack reaction after streaming replies (#2044) Co-authored-by: Shaurya Pratap Singh --- CHANGELOG.md | 1 + src/slack/monitor/message-handler/dispatch.ts | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6aacd64aa..2cd23f0f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ Status: unreleased. - TUI: avoid width overflow when rendering selection lists. (#1686) Thanks @mossein. - Telegram: keep topic IDs in restart sentinel notifications. (#1807) Thanks @hsrvc. - Config: apply config.env before ${VAR} substitution. (#1813) Thanks @spanishflu-est1918. +- Slack: clear ack reaction after streamed replies. (#2044) Thanks @fancyboi999. ## 2026.1.24-3 diff --git a/src/slack/monitor/message-handler/dispatch.ts b/src/slack/monitor/message-handler/dispatch.ts index d31885cfa..38b69f049 100644 --- a/src/slack/monitor/message-handler/dispatch.ts +++ b/src/slack/monitor/message-handler/dispatch.ts @@ -141,7 +141,9 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag }); markDispatchIdle(); - if (!queuedFinal) { + const anyReplyDelivered = queuedFinal || (counts.block ?? 0) > 0 || (counts.final ?? 0) > 0; + + if (!anyReplyDelivered) { if (prepared.isRoomish) { clearHistoryEntriesIfEnabled({ historyMap: ctx.channelHistories, From 8b91ceb7c96f5eb15e3cda39d6fa6a769dddcfad Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 21:46:15 -0600 Subject: [PATCH 037/196] macOS: preserve custom SSH usernames (#2046) Co-authored-by: Alexis Gallagher --- CHANGELOG.md | 1 + apps/macos/Sources/Clawdbot/AppState.swift | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cd23f0f1..5e3ab78da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Status: unreleased. - Telegram: keep topic IDs in restart sentinel notifications. (#1807) Thanks @hsrvc. - Config: apply config.env before ${VAR} substitution. (#1813) Thanks @spanishflu-est1918. - Slack: clear ack reaction after streamed replies. (#2044) Thanks @fancyboi999. +- macOS: keep custom SSH usernames in remote target. (#2046) Thanks @algal. ## 2026.1.24-3 diff --git a/apps/macos/Sources/Clawdbot/AppState.swift b/apps/macos/Sources/Clawdbot/AppState.swift index eeaf034d0..6ccb83369 100644 --- a/apps/macos/Sources/Clawdbot/AppState.swift +++ b/apps/macos/Sources/Clawdbot/AppState.swift @@ -413,10 +413,17 @@ final class AppState { } private func updateRemoteTarget(host: String) { - let parsed = CommandResolver.parseSSHTarget(self.remoteTarget) - let user = parsed?.user ?? NSUserName() - let port = parsed?.port ?? 22 - let assembled = port == 22 ? "\(user)@\(host)" : "\(user)@\(host):\(port)" + let trimmed = self.remoteTarget.trimmingCharacters(in: .whitespacesAndNewlines) + guard let parsed = CommandResolver.parseSSHTarget(trimmed) else { return } + let trimmedUser = parsed.user?.trimmingCharacters(in: .whitespacesAndNewlines) + let user = (trimmedUser?.isEmpty ?? true) ? nil : trimmedUser + let port = parsed.port + let assembled: String + if let user { + assembled = port == 22 ? "\(user)@\(host)" : "\(user)@\(host):\(port)" + } else { + assembled = port == 22 ? host : "\(host):\(port)" + } if assembled != self.remoteTarget { self.remoteTarget = assembled } From 15f7648e1e8a82dce8053d0b3e559eab26078de1 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:18:47 -0600 Subject: [PATCH 038/196] Docs: credit Control UI refresh contributors (#1852) --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e3ab78da..921ecaca7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Status: unreleased. - Agents: expand cron tool description with full schema docs. (#1988) Thanks @tomascupr. - Skills: add missing dependency metadata for GitHub, Notion, Slack, Discord. (#1995) Thanks @jackheuberger. - Docs: add Render deployment guide. (#1975) Thanks @anurag. +- Docs: credit both contributors for Control UI refresh. (#1852) Thanks @EnzeD. - CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. - macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. - Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. @@ -58,7 +59,7 @@ Status: unreleased. - Telegram: treat DM topics as separate sessions and keep DM history limits stable with thread suffixes. (#1597) Thanks @rohannagpal. - Telegram: add `channels.telegram.linkPreview` to toggle outbound link previews. (#1700) Thanks @zerone0x. https://docs.clawd.bot/channels/telegram - Web search: add Brave freshness filter parameter for time-scoped results. (#1688) Thanks @JonUleis. https://docs.clawd.bot/tools/web -- UI: refresh Control UI dashboard design system (typography, colors, spacing). (#1786) Thanks @mousberg. +- UI: refresh Control UI dashboard design system (colors, icons, typography). (#1745, #1786) Thanks @EnzeD, @mousberg. - Exec approvals: forward approval prompts to chat with `/approve` for all channels (including plugins). (#1621) Thanks @czekaj. https://docs.clawd.bot/tools/exec-approvals https://docs.clawd.bot/tools/slash-commands - Gateway: expose config.patch in the gateway tool with safe partial updates + restart sentinel. (#1653) Thanks @Glucksberg. - Diagnostics: add diagnostic flags for targeted debug logs (config + env override). https://docs.clawd.bot/diagnostics/flags From 0648d660a8673d03507c1babef4ae43595f429cd Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:22:52 -0600 Subject: [PATCH 039/196] Docs: use generic Pi hostnames --- docs/platforms/raspberry-pi.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/platforms/raspberry-pi.md b/docs/platforms/raspberry-pi.md index 1273d0112..b34e3fcfe 100644 --- a/docs/platforms/raspberry-pi.md +++ b/docs/platforms/raspberry-pi.md @@ -46,7 +46,7 @@ Use **Raspberry Pi OS Lite (64-bit)** — no desktop needed for a headless serve 1. Download [Raspberry Pi Imager](https://www.raspberrypi.com/software/) 2. Choose OS: **Raspberry Pi OS Lite (64-bit)** 3. Click the gear icon (⚙️) to pre-configure: - - Set hostname: `clawdbot` + - Set hostname: `gateway-host` - Enable SSH - Set username/password - Configure WiFi (if not using Ethernet) @@ -56,9 +56,9 @@ Use **Raspberry Pi OS Lite (64-bit)** — no desktop needed for a headless serve ## 2) Connect via SSH ```bash -ssh pi@clawdbot.local +ssh user@gateway-host # or use the IP address -ssh pi@192.168.x.x +ssh user@192.168.x.x ``` ## 3) System Setup @@ -156,7 +156,7 @@ Since the Pi is headless, use an SSH tunnel: ```bash # From your laptop/desktop -ssh -L 18789:localhost:18789 pi@clawdbot.local +ssh -L 18789:localhost:18789 user@gateway-host # Then open in browser open http://localhost:18789 From 5d6a9da370b89fee5f57098bef68cd6ba6f6bf3a Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:26:00 -0600 Subject: [PATCH 040/196] Onboarding: add Venice API key flags (#1893) --- CHANGELOG.md | 1 + src/cli/program/register.onboard.ts | 4 +++- .../local/auth-choice.ts | 21 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 921ecaca7..e5813b5d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Status: unreleased. - Skills: add missing dependency metadata for GitHub, Notion, Slack, Discord. (#1995) Thanks @jackheuberger. - Docs: add Render deployment guide. (#1975) Thanks @anurag. - Docs: credit both contributors for Control UI refresh. (#1852) Thanks @EnzeD. +- Onboarding: add Venice API key to non-interactive flow. (#1893) Thanks @jonisjongithub. - CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. - macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. - Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. diff --git a/src/cli/program/register.onboard.ts b/src/cli/program/register.onboard.ts index 281464b6f..ee9d5ccd2 100644 --- a/src/cli/program/register.onboard.ts +++ b/src/cli/program/register.onboard.ts @@ -52,7 +52,7 @@ export function registerOnboardCommand(program: Command) { .option("--mode ", "Wizard mode: local|remote") .option( "--auth-choice ", - "Auth: setup-token|claude-cli|token|chutes|openai-codex|openai-api-key|openrouter-api-key|ai-gateway-api-key|moonshot-api-key|kimi-code-api-key|synthetic-api-key|codex-cli|gemini-api-key|zai-api-key|apiKey|minimax-api|minimax-api-lightning|opencode-zen|skip", + "Auth: setup-token|claude-cli|token|chutes|openai-codex|openai-api-key|openrouter-api-key|ai-gateway-api-key|moonshot-api-key|kimi-code-api-key|synthetic-api-key|venice-api-key|codex-cli|gemini-api-key|zai-api-key|apiKey|minimax-api|minimax-api-lightning|opencode-zen|skip", ) .option( "--token-provider ", @@ -74,6 +74,7 @@ export function registerOnboardCommand(program: Command) { .option("--zai-api-key ", "Z.AI API key") .option("--minimax-api-key ", "MiniMax API key") .option("--synthetic-api-key ", "Synthetic API key") + .option("--venice-api-key ", "Venice API key") .option("--opencode-zen-api-key ", "OpenCode Zen API key") .option("--gateway-port ", "Gateway port") .option("--gateway-bind ", "Gateway bind: loopback|tailnet|lan|auto|custom") @@ -123,6 +124,7 @@ export function registerOnboardCommand(program: Command) { zaiApiKey: opts.zaiApiKey as string | undefined, minimaxApiKey: opts.minimaxApiKey as string | undefined, syntheticApiKey: opts.syntheticApiKey as string | undefined, + veniceApiKey: opts.veniceApiKey as string | undefined, opencodeZenApiKey: opts.opencodeZenApiKey as string | undefined, gatewayPort: typeof gatewayPort === "number" && Number.isFinite(gatewayPort) diff --git a/src/commands/onboard-non-interactive/local/auth-choice.ts b/src/commands/onboard-non-interactive/local/auth-choice.ts index 6762fb7d2..02e0a75b9 100644 --- a/src/commands/onboard-non-interactive/local/auth-choice.ts +++ b/src/commands/onboard-non-interactive/local/auth-choice.ts @@ -20,6 +20,7 @@ import { applyOpencodeZenConfig, applyOpenrouterConfig, applySyntheticConfig, + applyVeniceConfig, applyVercelAiGatewayConfig, applyZaiConfig, setAnthropicApiKey, @@ -30,6 +31,7 @@ import { setOpencodeZenApiKey, setOpenrouterApiKey, setSyntheticApiKey, + setVeniceApiKey, setVercelAiGatewayApiKey, setZaiApiKey, } from "../../onboard-auth.js"; @@ -272,6 +274,25 @@ export async function applyNonInteractiveAuthChoice(params: { return applySyntheticConfig(nextConfig); } + if (authChoice === "venice-api-key") { + const resolved = await resolveNonInteractiveApiKey({ + provider: "venice", + cfg: baseConfig, + flagValue: opts.veniceApiKey, + flagName: "--venice-api-key", + envVar: "VENICE_API_KEY", + runtime, + }); + if (!resolved) return null; + if (resolved.source !== "profile") await setVeniceApiKey(resolved.key); + nextConfig = applyAuthProfileConfig(nextConfig, { + profileId: "venice:default", + provider: "venice", + mode: "api_key", + }); + return applyVeniceConfig(nextConfig); + } + if ( authChoice === "minimax-cloud" || authChoice === "minimax-api" || From 51720980736b170569665e4863c4b7937a525e16 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:30:18 -0600 Subject: [PATCH 041/196] Tlon: format reply IDs as @ud (#1837) --- CHANGELOG.md | 1 + extensions/tlon/src/urbit/send.ts | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5813b5d1..2b1dfa6fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Status: unreleased. - Docs: add Render deployment guide. (#1975) Thanks @anurag. - Docs: credit both contributors for Control UI refresh. (#1852) Thanks @EnzeD. - Onboarding: add Venice API key to non-interactive flow. (#1893) Thanks @jonisjongithub. +- Tlon: format thread reply IDs as @ud. (#1837) Thanks @wca4a. - CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. - macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. - Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. diff --git a/extensions/tlon/src/urbit/send.ts b/extensions/tlon/src/urbit/send.ts index 35f7f2d74..621bbd69a 100644 --- a/extensions/tlon/src/urbit/send.ts +++ b/extensions/tlon/src/urbit/send.ts @@ -63,16 +63,28 @@ export async function sendGroupMessage({ const story = [{ inline: [text] }]; const sentAt = Date.now(); + // Format reply ID as @ud (with dots) - required for Tlon to recognize thread replies + let formattedReplyId = replyToId; + if (replyToId && /^\d+$/.test(replyToId)) { + try { + formattedReplyId = formatUd(BigInt(replyToId)); + } catch { + // Fall back to raw ID if formatting fails + } + } + const action = { channel: { nest: `chat/${hostShip}/${channelName}`, - action: replyToId + action: formattedReplyId ? { - reply: { - id: replyToId, - delta: { - add: { - memo: { + // Thread reply - needs post wrapper around reply action + // ReplyActionAdd takes Memo: {content, author, sent} - no kind/blob/meta + post: { + reply: { + id: formattedReplyId, + action: { + add: { content: story, author: fromShip, sent: sentAt, @@ -82,6 +94,7 @@ export async function sendGroupMessage({ }, } : { + // Regular post post: { add: { content: story, From d696ee3dfd64286c35313f69e658a0748640dc83 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:32:38 -0600 Subject: [PATCH 042/196] Docs: add Claude Max API Proxy guide (#1875) Co-authored-by: atalovesyou --- CHANGELOG.md | 1 + docs/providers/claude-max-api-proxy.md | 145 +++++++++++++++++++++++++ docs/providers/index.md | 4 + 3 files changed, 150 insertions(+) create mode 100644 docs/providers/claude-max-api-proxy.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b1dfa6fe..a1d4cd7d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Status: unreleased. - Agents: expand cron tool description with full schema docs. (#1988) Thanks @tomascupr. - Skills: add missing dependency metadata for GitHub, Notion, Slack, Discord. (#1995) Thanks @jackheuberger. - Docs: add Render deployment guide. (#1975) Thanks @anurag. +- Docs: add Claude Max API Proxy guide. (#1875) Thanks @atalovesyou. - Docs: credit both contributors for Control UI refresh. (#1852) Thanks @EnzeD. - Onboarding: add Venice API key to non-interactive flow. (#1893) Thanks @jonisjongithub. - Tlon: format thread reply IDs as @ud. (#1837) Thanks @wca4a. diff --git a/docs/providers/claude-max-api-proxy.md b/docs/providers/claude-max-api-proxy.md new file mode 100644 index 000000000..255be62fc --- /dev/null +++ b/docs/providers/claude-max-api-proxy.md @@ -0,0 +1,145 @@ +--- +summary: "Use Claude Max/Pro subscription as an OpenAI-compatible API endpoint" +read_when: + - You want to use Claude Max subscription with OpenAI-compatible tools + - You want a local API server that wraps Claude Code CLI + - You want to save money by using subscription instead of API keys +--- +# Claude Max API Proxy + +**claude-max-api-proxy** is a community tool that exposes your Claude Max/Pro subscription as an OpenAI-compatible API endpoint. This allows you to use your subscription with any tool that supports the OpenAI API format. + +## Why Use This? + +| Approach | Cost | Best For | +|----------|------|----------| +| Anthropic API | Pay per token (~$15/M input, $75/M output for Opus) | Production apps, high volume | +| Claude Max subscription | $200/month flat | Personal use, development, unlimited usage | + +If you have a Claude Max subscription and want to use it with OpenAI-compatible tools, this proxy can save you significant money. + +## How It Works + +``` +Your App → claude-max-api-proxy → Claude Code CLI → Anthropic (via subscription) + (OpenAI format) (converts format) (uses your login) +``` + +The proxy: +1. Accepts OpenAI-format requests at `http://localhost:3456/v1/chat/completions` +2. Converts them to Claude Code CLI commands +3. Returns responses in OpenAI format (streaming supported) + +## Installation + +```bash +# Requires Node.js 20+ and Claude Code CLI +npm install -g claude-max-api-proxy + +# Verify Claude CLI is authenticated +claude --version +``` + +## Usage + +### Start the server + +```bash +claude-max-api +# Server runs at http://localhost:3456 +``` + +### Test it + +```bash +# Health check +curl http://localhost:3456/health + +# List models +curl http://localhost:3456/v1/models + +# Chat completion +curl http://localhost:3456/v1/chat/completions \ + -H "Content-Type: application/json" \ + -d '{ + "model": "claude-opus-4", + "messages": [{"role": "user", "content": "Hello!"}] + }' +``` + +### With Clawdbot + +You can point Clawdbot at the proxy as a custom OpenAI-compatible endpoint: + +```json5 +{ + env: { + OPENAI_API_KEY: "not-needed", + OPENAI_BASE_URL: "http://localhost:3456/v1" + }, + agents: { + defaults: { + model: { primary: "openai/claude-opus-4" } + } + } +} +``` + +## Available Models + +| Model ID | Maps To | +|----------|---------| +| `claude-opus-4` | Claude Opus 4 | +| `claude-sonnet-4` | Claude Sonnet 4 | +| `claude-haiku-4` | Claude Haiku 4 | + +## Auto-Start on macOS + +Create a LaunchAgent to run the proxy automatically: + +```bash +cat > ~/Library/LaunchAgents/com.claude-max-api.plist << 'EOF' + + + + + Label + com.claude-max-api + RunAtLoad + + KeepAlive + + ProgramArguments + + /usr/local/bin/node + /usr/local/lib/node_modules/claude-max-api-proxy/dist/server/standalone.js + + EnvironmentVariables + + PATH + /usr/local/bin:/opt/homebrew/bin:~/.local/bin:/usr/bin:/bin + + + +EOF + +launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.claude-max-api.plist +``` + +## Links + +- **npm:** https://www.npmjs.com/package/claude-max-api-proxy +- **GitHub:** https://github.com/atalovesyou/claude-max-api-proxy +- **Issues:** https://github.com/atalovesyou/claude-max-api-proxy/issues + +## Notes + +- This is a **community tool**, not officially supported by Anthropic or Clawdbot +- Requires an active Claude Max/Pro subscription with Claude Code CLI authenticated +- The proxy runs locally and does not send data to any third-party servers +- Streaming responses are fully supported + +## See Also + +- [Anthropic provider](/providers/anthropic) - Native Clawdbot integration with Claude Code CLI OAuth +- [OpenAI provider](/providers/openai) - For OpenAI/Codex subscriptions diff --git a/docs/providers/index.md b/docs/providers/index.md index c4f020192..b4779d201 100644 --- a/docs/providers/index.md +++ b/docs/providers/index.md @@ -51,5 +51,9 @@ See [Venice AI](/providers/venice). - [Deepgram (audio transcription)](/providers/deepgram) +## Community tools + +- [Claude Max API Proxy](/providers/claude-max-api-proxy) - Use Claude Max/Pro subscription as an OpenAI-compatible API endpoint + For the full provider catalog (xAI, Groq, Mistral, etc.) and advanced configuration, see [Model providers](/concepts/model-providers). From 10914d62496d8786ffcffd7cb2ca7d5d85b9f3f6 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:33:03 -0600 Subject: [PATCH 043/196] Docs: add DigitalOcean deployment guide (#1870) Co-authored-by: 0xJonHoldsCrypto <0xJonHoldsCrypto@users.noreply.github.com> --- CHANGELOG.md | 1 + docs/platforms/digitalocean.md | 239 +++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 docs/platforms/digitalocean.md diff --git a/CHANGELOG.md b/CHANGELOG.md index a1d4cd7d7..cd5436c1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Status: unreleased. - Skills: add missing dependency metadata for GitHub, Notion, Slack, Discord. (#1995) Thanks @jackheuberger. - Docs: add Render deployment guide. (#1975) Thanks @anurag. - Docs: add Claude Max API Proxy guide. (#1875) Thanks @atalovesyou. +- Docs: add DigitalOcean deployment guide. (#1870) Thanks @0xJonHoldsCrypto. - Docs: credit both contributors for Control UI refresh. (#1852) Thanks @EnzeD. - Onboarding: add Venice API key to non-interactive flow. (#1893) Thanks @jonisjongithub. - Tlon: format thread reply IDs as @ud. (#1837) Thanks @wca4a. diff --git a/docs/platforms/digitalocean.md b/docs/platforms/digitalocean.md new file mode 100644 index 000000000..1b8e1d90d --- /dev/null +++ b/docs/platforms/digitalocean.md @@ -0,0 +1,239 @@ +--- +summary: "Clawdbot on DigitalOcean (cheapest paid VPS option)" +read_when: + - Setting up Clawdbot on DigitalOcean + - Looking for cheap VPS hosting for Clawdbot +--- + +# Clawdbot on DigitalOcean + +## Goal + +Run a persistent Clawdbot Gateway on DigitalOcean for **$6/month** (or $4/mo with reserved pricing). + +If you want something even cheaper, see [Oracle Cloud (Free Tier)](#oracle-cloud-free-alternative) at the bottom — it's **actually free forever**. + +## Cost Comparison (2026) + +| Provider | Plan | Specs | Price/mo | Notes | +|----------|------|-------|----------|-------| +| **Oracle Cloud** | Always Free ARM | 4 OCPU, 24GB RAM | **$0** | Best value, requires ARM-compatible setup | +| **Hetzner** | CX22 | 2 vCPU, 4GB RAM | €3.79 (~$4) | Cheapest paid, EU datacenters | +| **DigitalOcean** | Basic | 1 vCPU, 1GB RAM | $6 | Easy UI, good docs | +| **Vultr** | Cloud Compute | 1 vCPU, 1GB RAM | $6 | Many locations | +| **Linode** | Nanode | 1 vCPU, 1GB RAM | $5 | Now part of Akamai | + +**Recommendation:** +- **Free:** Oracle Cloud ARM (if you can handle the signup process) +- **Paid:** Hetzner CX22 (best specs per dollar) — see [Hetzner guide](/platforms/hetzner) +- **Easy:** DigitalOcean (this guide) — beginner-friendly UI + +--- + +## Prerequisites + +- DigitalOcean account ([signup with $200 free credit](https://m.do.co/c/signup)) +- SSH key pair (or willingness to use password auth) +- ~20 minutes + +## 1) Create a Droplet + +1. Log into [DigitalOcean](https://cloud.digitalocean.com/) +2. Click **Create → Droplets** +3. Choose: + - **Region:** Closest to you (or your users) + - **Image:** Ubuntu 24.04 LTS + - **Size:** Basic → Regular → **$6/mo** (1 vCPU, 1GB RAM, 25GB SSD) + - **Authentication:** SSH key (recommended) or password +4. Click **Create Droplet** +5. Note the IP address + +## 2) Connect via SSH + +```bash +ssh root@YOUR_DROPLET_IP +``` + +## 3) Install Clawdbot + +```bash +# Update system +apt update && apt upgrade -y + +# Install Node.js 22 +curl -fsSL https://deb.nodesource.com/setup_22.x | bash - +apt install -y nodejs + +# Install Clawdbot +curl -fsSL https://clawd.bot/install.sh | bash + +# Verify +clawdbot --version +``` + +## 4) Run Onboarding + +```bash +clawdbot onboard --install-daemon +``` + +The wizard will walk you through: +- Model auth (API keys or OAuth) +- Channel setup (Telegram, WhatsApp, Discord, etc.) +- Gateway token (auto-generated) +- Daemon installation (systemd) + +## 5) Verify the Gateway + +```bash +# Check status +clawdbot status + +# Check service +systemctl status clawdbot + +# View logs +journalctl -u clawdbot -f +``` + +## 6) Access the Dashboard + +The gateway binds to loopback by default. To access the Control UI: + +**Option A: SSH Tunnel (recommended)** +```bash +# From your local machine +ssh -L 18789:localhost:18789 root@YOUR_DROPLET_IP + +# Then open: http://localhost:18789 +``` + +**Option B: Tailscale (easier long-term)** +```bash +# On the droplet +curl -fsSL https://tailscale.com/install.sh | sh +tailscale up + +# Configure gateway to bind to Tailscale +clawdbot config set gateway.bind tailnet +clawdbot gateway restart +``` + +Then access via your Tailscale IP: `http://100.x.x.x:18789` + +## 7) Connect Your Channels + +### Telegram +```bash +clawdbot pairing list telegram +clawdbot pairing approve telegram +``` + +### WhatsApp +```bash +clawdbot channels login whatsapp +# Scan QR code +``` + +See [Channels](/channels) for other providers. + +--- + +## Optimizations for 1GB RAM + +The $6 droplet only has 1GB RAM. To keep things running smoothly: + +### Add swap (recommended) +```bash +fallocate -l 2G /swapfile +chmod 600 /swapfile +mkswap /swapfile +swapon /swapfile +echo '/swapfile none swap sw 0 0' >> /etc/fstab +``` + +### Use a lighter model +If you're hitting OOMs, consider: +- Using API-based models (Claude, GPT) instead of local models +- Setting `agents.defaults.model.primary` to a smaller model + +### Monitor memory +```bash +free -h +htop +``` + +--- + +## Persistence + +All state lives in: +- `~/.clawdbot/` — config, credentials, session data +- `~/clawd/` — workspace (SOUL.md, memory, etc.) + +These survive reboots. Back them up periodically: +```bash +tar -czvf clawdbot-backup.tar.gz ~/.clawdbot ~/clawd +``` + +--- + +## Oracle Cloud Free Alternative + +Oracle Cloud offers **Always Free** ARM instances that are significantly more powerful: + +| What you get | Specs | +|--------------|-------| +| **4 OCPUs** | ARM Ampere A1 | +| **24GB RAM** | More than enough | +| **200GB storage** | Block volume | +| **Forever free** | No credit card charges | + +### Quick setup: +1. Sign up at [oracle.com/cloud/free](https://www.oracle.com/cloud/free/) +2. Create a VM.Standard.A1.Flex instance (ARM) +3. Choose Oracle Linux or Ubuntu +4. Allocate up to 4 OCPU / 24GB RAM within free tier +5. Follow the same Clawdbot install steps above + +**Caveats:** +- Signup can be finicky (retry if it fails) +- ARM architecture — most things work, but some binaries need ARM builds +- Oracle may reclaim idle instances (keep them active) + +For the full Oracle guide, see the [community docs](https://gist.github.com/rssnyder/51e3cfedd730e7dd5f4a816143b25dbd). + +--- + +## Troubleshooting + +### Gateway won't start +```bash +clawdbot gateway status +clawdbot doctor --non-interactive +journalctl -u clawdbot --no-pager -n 50 +``` + +### Port already in use +```bash +lsof -i :18789 +kill +``` + +### Out of memory +```bash +# Check memory +free -h + +# Add more swap +# Or upgrade to $12/mo droplet (2GB RAM) +``` + +--- + +## See Also + +- [Hetzner guide](/platforms/hetzner) — cheaper, more powerful +- [Docker install](/install/docker) — containerized setup +- [Tailscale](/gateway/tailscale) — secure remote access +- [Configuration](/gateway/configuration) — full config reference From a2d9127ff64b9417e3a953404d5a7b1a544e497e Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:33:35 -0600 Subject: [PATCH 044/196] Docs: add Raspberry Pi install guide (#1871) Co-authored-by: 0xJonHoldsCrypto <0xJonHoldsCrypto@users.noreply.github.com> --- CHANGELOG.md | 1 + docs/platforms/raspberry-pi.md | 354 +++++++++++++++++++++++++++++++++ 2 files changed, 355 insertions(+) create mode 100644 docs/platforms/raspberry-pi.md diff --git a/CHANGELOG.md b/CHANGELOG.md index cd5436c1d..27fa13f18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Status: unreleased. - Docs: add Render deployment guide. (#1975) Thanks @anurag. - Docs: add Claude Max API Proxy guide. (#1875) Thanks @atalovesyou. - Docs: add DigitalOcean deployment guide. (#1870) Thanks @0xJonHoldsCrypto. +- Docs: add Raspberry Pi install guide. (#1871) Thanks @0xJonHoldsCrypto. - Docs: credit both contributors for Control UI refresh. (#1852) Thanks @EnzeD. - Onboarding: add Venice API key to non-interactive flow. (#1893) Thanks @jonisjongithub. - Tlon: format thread reply IDs as @ud. (#1837) Thanks @wca4a. diff --git a/docs/platforms/raspberry-pi.md b/docs/platforms/raspberry-pi.md new file mode 100644 index 000000000..b34e3fcfe --- /dev/null +++ b/docs/platforms/raspberry-pi.md @@ -0,0 +1,354 @@ +--- +summary: "Clawdbot on Raspberry Pi (budget self-hosted setup)" +read_when: + - Setting up Clawdbot on a Raspberry Pi + - Running Clawdbot on ARM devices + - Building a cheap always-on personal AI +--- + +# Clawdbot on Raspberry Pi + +## Goal + +Run a persistent, always-on Clawdbot Gateway on a Raspberry Pi for **~$35-80** one-time cost (no monthly fees). + +Perfect for: +- 24/7 personal AI assistant +- Home automation hub +- Low-power, always-available Telegram/WhatsApp bot + +## Hardware Requirements + +| Pi Model | RAM | Works? | Notes | +|----------|-----|--------|-------| +| **Pi 5** | 4GB/8GB | ✅ Best | Fastest, recommended | +| **Pi 4** | 4GB | ✅ Good | Sweet spot for most users | +| **Pi 4** | 2GB | ✅ OK | Works, add swap | +| **Pi 4** | 1GB | ⚠️ Tight | Possible with swap, minimal config | +| **Pi 3B+** | 1GB | ⚠️ Slow | Works but sluggish | +| **Pi Zero 2 W** | 512MB | ❌ | Not recommended | + +**Minimum specs:** 1GB RAM, 1 core, 500MB disk +**Recommended:** 2GB+ RAM, 64-bit OS, 16GB+ SD card (or USB SSD) + +## What You'll Need + +- Raspberry Pi 4 or 5 (2GB+ recommended) +- MicroSD card (16GB+) or USB SSD (better performance) +- Power supply (official Pi PSU recommended) +- Network connection (Ethernet or WiFi) +- ~30 minutes + +## 1) Flash the OS + +Use **Raspberry Pi OS Lite (64-bit)** — no desktop needed for a headless server. + +1. Download [Raspberry Pi Imager](https://www.raspberrypi.com/software/) +2. Choose OS: **Raspberry Pi OS Lite (64-bit)** +3. Click the gear icon (⚙️) to pre-configure: + - Set hostname: `gateway-host` + - Enable SSH + - Set username/password + - Configure WiFi (if not using Ethernet) +4. Flash to your SD card / USB drive +5. Insert and boot the Pi + +## 2) Connect via SSH + +```bash +ssh user@gateway-host +# or use the IP address +ssh user@192.168.x.x +``` + +## 3) System Setup + +```bash +# Update system +sudo apt update && sudo apt upgrade -y + +# Install essential packages +sudo apt install -y git curl build-essential + +# Set timezone (important for cron/reminders) +sudo timedatectl set-timezone America/Chicago # Change to your timezone +``` + +## 4) Install Node.js 22 (ARM64) + +```bash +# Install Node.js via NodeSource +curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - +sudo apt install -y nodejs + +# Verify +node --version # Should show v22.x.x +npm --version +``` + +## 5) Add Swap (Important for 2GB or less) + +Swap prevents out-of-memory crashes: + +```bash +# Create 2GB swap file +sudo fallocate -l 2G /swapfile +sudo chmod 600 /swapfile +sudo mkswap /swapfile +sudo swapon /swapfile + +# Make permanent +echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab + +# Optimize for low RAM (reduce swappiness) +echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf +sudo sysctl -p +``` + +## 6) Install Clawdbot + +### Option A: Standard Install (Recommended) + +```bash +curl -fsSL https://clawd.bot/install.sh | bash +``` + +### Option B: Hackable Install (For tinkering) + +```bash +git clone https://github.com/clawdbot/clawdbot.git +cd clawdbot +npm install +npm run build +npm link +``` + +The hackable install gives you direct access to logs and code — useful for debugging ARM-specific issues. + +## 7) Run Onboarding + +```bash +clawdbot onboard --install-daemon +``` + +Follow the wizard: +1. **Gateway mode:** Local +2. **Auth:** API keys recommended (OAuth can be finicky on headless Pi) +3. **Channels:** Telegram is easiest to start with +4. **Daemon:** Yes (systemd) + +## 8) Verify Installation + +```bash +# Check status +clawdbot status + +# Check service +sudo systemctl status clawdbot + +# View logs +journalctl -u clawdbot -f +``` + +## 9) Access the Dashboard + +Since the Pi is headless, use an SSH tunnel: + +```bash +# From your laptop/desktop +ssh -L 18789:localhost:18789 user@gateway-host + +# Then open in browser +open http://localhost:18789 +``` + +Or use Tailscale for always-on access: + +```bash +# On the Pi +curl -fsSL https://tailscale.com/install.sh | sh +sudo tailscale up + +# Update config +clawdbot config set gateway.bind tailnet +sudo systemctl restart clawdbot +``` + +--- + +## Performance Optimizations + +### Use a USB SSD (Huge Improvement) + +SD cards are slow and wear out. A USB SSD dramatically improves performance: + +```bash +# Check if booting from USB +lsblk +``` + +See [Pi USB boot guide](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#usb-mass-storage-boot) for setup. + +### Reduce Memory Usage + +```bash +# Disable GPU memory allocation (headless) +echo 'gpu_mem=16' | sudo tee -a /boot/config.txt + +# Disable Bluetooth if not needed +sudo systemctl disable bluetooth +``` + +### Monitor Resources + +```bash +# Check memory +free -h + +# Check CPU temperature +vcgencmd measure_temp + +# Live monitoring +htop +``` + +--- + +## ARM-Specific Notes + +### Binary Compatibility + +Most Clawdbot features work on ARM64, but some external binaries may need ARM builds: + +| Tool | ARM64 Status | Notes | +|------|--------------|-------| +| Node.js | ✅ | Works great | +| WhatsApp (Baileys) | ✅ | Pure JS, no issues | +| Telegram | ✅ | Pure JS, no issues | +| gog (Gmail CLI) | ⚠️ | Check for ARM release | +| Chromium (browser) | ✅ | `sudo apt install chromium-browser` | + +If a skill fails, check if its binary has an ARM build. Many Go/Rust tools do; some don't. + +### 32-bit vs 64-bit + +**Always use 64-bit OS.** Node.js and many modern tools require it. Check with: + +```bash +uname -m +# Should show: aarch64 (64-bit) not armv7l (32-bit) +``` + +--- + +## Recommended Model Setup + +Since the Pi is just the Gateway (models run in the cloud), use API-based models: + +```json +{ + "agents": { + "defaults": { + "model": { + "primary": "anthropic/claude-sonnet-4-20250514", + "fallbacks": ["openai/gpt-4o-mini"] + } + } + } +} +``` + +**Don't try to run local LLMs on a Pi** — even small models are too slow. Let Claude/GPT do the heavy lifting. + +--- + +## Auto-Start on Boot + +The onboarding wizard sets this up, but to verify: + +```bash +# Check service is enabled +sudo systemctl is-enabled clawdbot + +# Enable if not +sudo systemctl enable clawdbot + +# Start on boot +sudo systemctl start clawdbot +``` + +--- + +## Troubleshooting + +### Out of Memory (OOM) + +```bash +# Check memory +free -h + +# Add more swap (see Step 5) +# Or reduce services running on the Pi +``` + +### Slow Performance + +- Use USB SSD instead of SD card +- Disable unused services: `sudo systemctl disable cups bluetooth avahi-daemon` +- Check CPU throttling: `vcgencmd get_throttled` (should return `0x0`) + +### Service Won't Start + +```bash +# Check logs +journalctl -u clawdbot --no-pager -n 100 + +# Common fix: rebuild +cd ~/clawdbot # if using hackable install +npm run build +sudo systemctl restart clawdbot +``` + +### ARM Binary Issues + +If a skill fails with "exec format error": +1. Check if the binary has an ARM64 build +2. Try building from source +3. Or use a Docker container with ARM support + +### WiFi Drops + +For headless Pis on WiFi: + +```bash +# Disable WiFi power management +sudo iwconfig wlan0 power off + +# Make permanent +echo 'wireless-power off' | sudo tee -a /etc/network/interfaces +``` + +--- + +## Cost Comparison + +| Setup | One-Time Cost | Monthly Cost | Notes | +|-------|---------------|--------------|-------| +| **Pi 4 (2GB)** | ~$45 | $0 | + power (~$5/yr) | +| **Pi 4 (4GB)** | ~$55 | $0 | Recommended | +| **Pi 5 (4GB)** | ~$60 | $0 | Best performance | +| **Pi 5 (8GB)** | ~$80 | $0 | Overkill but future-proof | +| DigitalOcean | $0 | $6/mo | $72/year | +| Hetzner | $0 | €3.79/mo | ~$50/year | + +**Break-even:** A Pi pays for itself in ~6-12 months vs cloud VPS. + +--- + +## See Also + +- [Linux guide](/platforms/linux) — general Linux setup +- [DigitalOcean guide](/platforms/digitalocean) — cloud alternative +- [Hetzner guide](/platforms/hetzner) — Docker setup +- [Tailscale](/gateway/tailscale) — remote access +- [Nodes](/nodes) — pair your laptop/phone with the Pi gateway From 9ba142e8a5ac5dcb22577a25a47dd395f26031ab Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:34:09 -0600 Subject: [PATCH 045/196] Docs: add GCP Compute Engine deployment guide (#1848) Co-authored-by: hougangdev --- CHANGELOG.md | 1 + docs/docs.json | 9 + docs/platforms/gcp.md | 498 ++++++++++++++++++++++++++++++++++++++++ docs/platforms/index.md | 1 + docs/vps.md | 1 + 5 files changed, 510 insertions(+) create mode 100644 docs/platforms/gcp.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 27fa13f18..35f3ad89c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Status: unreleased. - Docs: add Claude Max API Proxy guide. (#1875) Thanks @atalovesyou. - Docs: add DigitalOcean deployment guide. (#1870) Thanks @0xJonHoldsCrypto. - Docs: add Raspberry Pi install guide. (#1871) Thanks @0xJonHoldsCrypto. +- Docs: add GCP Compute Engine deployment guide. (#1848) Thanks @hougangdev. - Docs: credit both contributors for Control UI refresh. (#1852) Thanks @EnzeD. - Onboarding: add Venice API key to non-interactive flow. (#1893) Thanks @jonisjongithub. - Tlon: format thread reply IDs as @ud. (#1837) Thanks @wca4a. diff --git a/docs/docs.json b/docs/docs.json index 983585bff..b0f0ee802 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -788,6 +788,14 @@ { "source": "/install/railway/", "destination": "/railway" + }, + { + "source": "/gcp", + "destination": "/platforms/gcp" + }, + { + "source": "/gcp/", + "destination": "/platforms/gcp" } ], "navigation": { @@ -1057,6 +1065,7 @@ "platforms/linux", "platforms/fly", "platforms/hetzner", + "platforms/gcp", "platforms/exe-dev" ] }, diff --git a/docs/platforms/gcp.md b/docs/platforms/gcp.md new file mode 100644 index 000000000..cffa03ace --- /dev/null +++ b/docs/platforms/gcp.md @@ -0,0 +1,498 @@ +--- +summary: "Run Clawdbot Gateway 24/7 on a GCP Compute Engine VM (Docker) with durable state" +read_when: + - You want Clawdbot running 24/7 on GCP + - You want a production-grade, always-on Gateway on your own VM + - You want full control over persistence, binaries, and restart behavior +--- + +# Clawdbot on GCP Compute Engine (Docker, Production VPS Guide) + +## Goal + +Run a persistent Clawdbot Gateway on a GCP Compute Engine VM using Docker, with durable state, baked-in binaries, and safe restart behavior. + +If you want "Clawdbot 24/7 for ~$5-12/mo", this is a reliable setup on Google Cloud. +Pricing varies by machine type and region; pick the smallest VM that fits your workload and scale up if you hit OOMs. + +## What are we doing (simple terms)? + +- Create a GCP project and enable billing +- Create a Compute Engine VM +- Install Docker (isolated app runtime) +- Start the Clawdbot Gateway in Docker +- Persist `~/.clawdbot` + `~/clawd` on the host (survives restarts/rebuilds) +- Access the Control UI from your laptop via an SSH tunnel + +The Gateway can be accessed via: +- SSH port forwarding from your laptop +- Direct port exposure if you manage firewalling and tokens yourself + +This guide uses Debian on GCP Compute Engine. +Ubuntu also works; map packages accordingly. +For the generic Docker flow, see [Docker](/install/docker). + +--- + +## Quick path (experienced operators) + +1) Create GCP project + enable Compute Engine API +2) Create Compute Engine VM (e2-small, Debian 12, 20GB) +3) SSH into the VM +4) Install Docker +5) Clone Clawdbot repository +6) Create persistent host directories +7) Configure `.env` and `docker-compose.yml` +8) Bake required binaries, build, and launch + +--- + +## What you need + +- GCP account (free tier eligible for e2-micro) +- gcloud CLI installed (or use Cloud Console) +- SSH access from your laptop +- Basic comfort with SSH + copy/paste +- ~20-30 minutes +- Docker and Docker Compose +- Model auth credentials +- Optional provider credentials + - WhatsApp QR + - Telegram bot token + - Gmail OAuth + +--- + +## 1) Install gcloud CLI (or use Console) + +**Option A: gcloud CLI** (recommended for automation) + +Install from https://cloud.google.com/sdk/docs/install + +Initialize and authenticate: + +```bash +gcloud init +gcloud auth login +``` + +**Option B: Cloud Console** + +All steps can be done via the web UI at https://console.cloud.google.com + +--- + +## 2) Create a GCP project + +**CLI:** + +```bash +gcloud projects create my-clawdbot-project --name="Clawdbot Gateway" +gcloud config set project my-clawdbot-project +``` + +Enable billing at https://console.cloud.google.com/billing (required for Compute Engine). + +Enable the Compute Engine API: + +```bash +gcloud services enable compute.googleapis.com +``` + +**Console:** + +1. Go to IAM & Admin > Create Project +2. Name it and create +3. Enable billing for the project +4. Navigate to APIs & Services > Enable APIs > search "Compute Engine API" > Enable + +--- + +## 3) Create the VM + +**Machine types:** + +| Type | Specs | Cost | Notes | +|------|-------|------|-------| +| e2-small | 2 vCPU, 2GB RAM | ~$12/mo | Recommended | +| e2-micro | 2 vCPU (shared), 1GB RAM | Free tier eligible | May OOM under load | + +**CLI:** + +```bash +gcloud compute instances create clawdbot-gateway \ + --zone=us-central1-a \ + --machine-type=e2-small \ + --boot-disk-size=20GB \ + --image-family=debian-12 \ + --image-project=debian-cloud +``` + +**Console:** + +1. Go to Compute Engine > VM instances > Create instance +2. Name: `clawdbot-gateway` +3. Region: `us-central1`, Zone: `us-central1-a` +4. Machine type: `e2-small` +5. Boot disk: Debian 12, 20GB +6. Create + +--- + +## 4) SSH into the VM + +**CLI:** + +```bash +gcloud compute ssh clawdbot-gateway --zone=us-central1-a +``` + +**Console:** + +Click the "SSH" button next to your VM in the Compute Engine dashboard. + +Note: SSH key propagation can take 1-2 minutes after VM creation. If connection is refused, wait and retry. + +--- + +## 5) Install Docker (on the VM) + +```bash +sudo apt-get update +sudo apt-get install -y git curl ca-certificates +curl -fsSL https://get.docker.com | sudo sh +sudo usermod -aG docker $USER +``` + +Log out and back in for the group change to take effect: + +```bash +exit +``` + +Then SSH back in: + +```bash +gcloud compute ssh clawdbot-gateway --zone=us-central1-a +``` + +Verify: + +```bash +docker --version +docker compose version +``` + +--- + +## 6) Clone the Clawdbot repository + +```bash +git clone https://github.com/clawdbot/clawdbot.git +cd clawdbot +``` + +This guide assumes you will build a custom image to guarantee binary persistence. + +--- + +## 7) Create persistent host directories + +Docker containers are ephemeral. +All long-lived state must live on the host. + +```bash +mkdir -p ~/.clawdbot +mkdir -p ~/clawd +``` + +--- + +## 8) Configure environment variables + +Create `.env` in the repository root. + +```bash +CLAWDBOT_IMAGE=clawdbot:latest +CLAWDBOT_GATEWAY_TOKEN=change-me-now +CLAWDBOT_GATEWAY_BIND=lan +CLAWDBOT_GATEWAY_PORT=18789 + +CLAWDBOT_CONFIG_DIR=/home/$USER/.clawdbot +CLAWDBOT_WORKSPACE_DIR=/home/$USER/clawd + +GOG_KEYRING_PASSWORD=change-me-now +XDG_CONFIG_HOME=/home/node/.clawdbot +``` + +Generate strong secrets: + +```bash +openssl rand -hex 32 +``` + +**Do not commit this file.** + +--- + +## 9) Docker Compose configuration + +Create or update `docker-compose.yml`. + +```yaml +services: + clawdbot-gateway: + image: ${CLAWDBOT_IMAGE} + build: . + restart: unless-stopped + env_file: + - .env + environment: + - HOME=/home/node + - NODE_ENV=production + - TERM=xterm-256color + - CLAWDBOT_GATEWAY_BIND=${CLAWDBOT_GATEWAY_BIND} + - CLAWDBOT_GATEWAY_PORT=${CLAWDBOT_GATEWAY_PORT} + - CLAWDBOT_GATEWAY_TOKEN=${CLAWDBOT_GATEWAY_TOKEN} + - GOG_KEYRING_PASSWORD=${GOG_KEYRING_PASSWORD} + - XDG_CONFIG_HOME=${XDG_CONFIG_HOME} + - PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + volumes: + - ${CLAWDBOT_CONFIG_DIR}:/home/node/.clawdbot + - ${CLAWDBOT_WORKSPACE_DIR}:/home/node/clawd + ports: + # Recommended: keep the Gateway loopback-only on the VM; access via SSH tunnel. + # To expose it publicly, remove the `127.0.0.1:` prefix and firewall accordingly. + - "127.0.0.1:${CLAWDBOT_GATEWAY_PORT}:18789" + + # Optional: only if you run iOS/Android nodes against this VM and need Canvas host. + # If you expose this publicly, read /gateway/security and firewall accordingly. + # - "18793:18793" + command: + [ + "node", + "dist/index.js", + "gateway", + "--bind", + "${CLAWDBOT_GATEWAY_BIND}", + "--port", + "${CLAWDBOT_GATEWAY_PORT}" + ] +``` + +--- + +## 10) Bake required binaries into the image (critical) + +Installing binaries inside a running container is a trap. +Anything installed at runtime will be lost on restart. + +All external binaries required by skills must be installed at image build time. + +The examples below show three common binaries only: +- `gog` for Gmail access +- `goplaces` for Google Places +- `wacli` for WhatsApp + +These are examples, not a complete list. +You may install as many binaries as needed using the same pattern. + +If you add new skills later that depend on additional binaries, you must: +1. Update the Dockerfile +2. Rebuild the image +3. Restart the containers + +**Example Dockerfile** + +```dockerfile +FROM node:22-bookworm + +RUN apt-get update && apt-get install -y socat && rm -rf /var/lib/apt/lists/* + +# Example binary 1: Gmail CLI +RUN curl -L https://github.com/steipete/gog/releases/latest/download/gog_Linux_x86_64.tar.gz \ + | tar -xz -C /usr/local/bin && chmod +x /usr/local/bin/gog + +# Example binary 2: Google Places CLI +RUN curl -L https://github.com/steipete/goplaces/releases/latest/download/goplaces_Linux_x86_64.tar.gz \ + | tar -xz -C /usr/local/bin && chmod +x /usr/local/bin/goplaces + +# Example binary 3: WhatsApp CLI +RUN curl -L https://github.com/steipete/wacli/releases/latest/download/wacli_Linux_x86_64.tar.gz \ + | tar -xz -C /usr/local/bin && chmod +x /usr/local/bin/wacli + +# Add more binaries below using the same pattern + +WORKDIR /app +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./ +COPY ui/package.json ./ui/package.json +COPY scripts ./scripts + +RUN corepack enable +RUN pnpm install --frozen-lockfile + +COPY . . +RUN pnpm build +RUN pnpm ui:install +RUN pnpm ui:build + +ENV NODE_ENV=production + +CMD ["node","dist/index.js"] +``` + +--- + +## 11) Build and launch + +```bash +docker compose build +docker compose up -d clawdbot-gateway +``` + +Verify binaries: + +```bash +docker compose exec clawdbot-gateway which gog +docker compose exec clawdbot-gateway which goplaces +docker compose exec clawdbot-gateway which wacli +``` + +Expected output: + +``` +/usr/local/bin/gog +/usr/local/bin/goplaces +/usr/local/bin/wacli +``` + +--- + +## 12) Verify Gateway + +```bash +docker compose logs -f clawdbot-gateway +``` + +Success: + +``` +[gateway] listening on ws://0.0.0.0:18789 +``` + +--- + +## 13) Access from your laptop + +Create an SSH tunnel to forward the Gateway port: + +```bash +gcloud compute ssh clawdbot-gateway --zone=us-central1-a -- -L 18789:127.0.0.1:18789 +``` + +Open in your browser: + +`http://127.0.0.1:18789/` + +Paste your gateway token. + +--- + +## What persists where (source of truth) + +Clawdbot runs in Docker, but Docker is not the source of truth. +All long-lived state must survive restarts, rebuilds, and reboots. + +| Component | Location | Persistence mechanism | Notes | +|---|---|---|---| +| Gateway config | `/home/node/.clawdbot/` | Host volume mount | Includes `clawdbot.json`, tokens | +| Model auth profiles | `/home/node/.clawdbot/` | Host volume mount | OAuth tokens, API keys | +| Skill configs | `/home/node/.clawdbot/skills/` | Host volume mount | Skill-level state | +| Agent workspace | `/home/node/clawd/` | Host volume mount | Code and agent artifacts | +| WhatsApp session | `/home/node/.clawdbot/` | Host volume mount | Preserves QR login | +| Gmail keyring | `/home/node/.clawdbot/` | Host volume + password | Requires `GOG_KEYRING_PASSWORD` | +| External binaries | `/usr/local/bin/` | Docker image | Must be baked at build time | +| Node runtime | Container filesystem | Docker image | Rebuilt every image build | +| OS packages | Container filesystem | Docker image | Do not install at runtime | +| Docker container | Ephemeral | Restartable | Safe to destroy | + +--- + +## Updates + +To update Clawdbot on the VM: + +```bash +cd ~/clawdbot +git pull +docker compose build +docker compose up -d +``` + +--- + +## Troubleshooting + +**SSH connection refused** + +SSH key propagation can take 1-2 minutes after VM creation. Wait and retry. + +**OS Login issues** + +Check your OS Login profile: + +```bash +gcloud compute os-login describe-profile +``` + +Ensure your account has the required IAM permissions (Compute OS Login or Compute OS Admin Login). + +**Out of memory (OOM)** + +If using e2-micro and hitting OOM, upgrade to e2-small or e2-medium: + +```bash +# Stop the VM first +gcloud compute instances stop clawdbot-gateway --zone=us-central1-a + +# Change machine type +gcloud compute instances set-machine-type clawdbot-gateway \ + --zone=us-central1-a \ + --machine-type=e2-small + +# Start the VM +gcloud compute instances start clawdbot-gateway --zone=us-central1-a +``` + +--- + +## Service accounts (security best practice) + +For personal use, your default user account works fine. + +For automation or CI/CD pipelines, create a dedicated service account with minimal permissions: + +1. Create a service account: + ```bash + gcloud iam service-accounts create clawdbot-deploy \ + --display-name="Clawdbot Deployment" + ``` + +2. Grant Compute Instance Admin role (or narrower custom role): + ```bash + gcloud projects add-iam-policy-binding my-clawdbot-project \ + --member="serviceAccount:clawdbot-deploy@my-clawdbot-project.iam.gserviceaccount.com" \ + --role="roles/compute.instanceAdmin.v1" + ``` + +Avoid using the Owner role for automation. Use the principle of least privilege. + +See https://cloud.google.com/iam/docs/understanding-roles for IAM role details. + +--- + +## Next steps + +- Set up messaging channels: [Channels](/channels) +- Pair local devices as nodes: [Nodes](/nodes) +- Configure the Gateway: [Gateway configuration](/gateway/configuration) diff --git a/docs/platforms/index.md b/docs/platforms/index.md index 1b5c85129..d53073026 100644 --- a/docs/platforms/index.md +++ b/docs/platforms/index.md @@ -27,6 +27,7 @@ Native companion apps for Windows are also planned; the Gateway is recommended v - Railway (one-click): [Railway](/railway) - Fly.io: [Fly.io](/platforms/fly) - Hetzner (Docker): [Hetzner](/platforms/hetzner) +- GCP (Compute Engine): [GCP](/platforms/gcp) - exe.dev (VM + HTTPS proxy): [exe.dev](/platforms/exe-dev) ## Common links diff --git a/docs/vps.md b/docs/vps.md index a6d267513..23e88255b 100644 --- a/docs/vps.md +++ b/docs/vps.md @@ -14,6 +14,7 @@ deployments work at a high level. - **Railway** (one‑click + browser setup): [Railway](/railway) - **Fly.io**: [Fly.io](/platforms/fly) - **Hetzner (Docker)**: [Hetzner](/platforms/hetzner) +- **GCP (Compute Engine)**: [GCP](/platforms/gcp) - **exe.dev** (VM + HTTPS proxy): [exe.dev](/platforms/exe-dev) - **AWS (EC2/Lightsail/free tier)**: works well too. Video guide: https://x.com/techfrenAJ/status/2014934471095812547 From e040f6338a1c7e88b2c85d74d7daa153a4910206 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:38:04 -0600 Subject: [PATCH 046/196] Docs: update clawtributors list --- README.md | 8 ++++---- scripts/clawtributors-map.json | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 47f3a9090..217a4b61c 100644 --- a/README.md +++ b/README.md @@ -484,7 +484,7 @@ Thanks to all clawtributors: vignesh07 mteam88 dbhurley Mariano Belinky Eng. Juan Combetto TSavo julianengel bradleypriest benithors rohannagpal timolins f-trycua benostein nachx639 pvoo sreekaransrinath gupsammy cristip73 stefangalescu nachoiacovino Vasanth Rao Naik Sabavat petter-b cpojer scald gumadeiras andranik-sahakyan davidguttman sleontenko denysvitali orlyjamie - sircrumpet peschee rafaelreis-r thewilloftheshadow ratulsarna lutr0 danielz1z emanuelst KristijanJovanovski rdev + thewilloftheshadow sircrumpet peschee rafaelreis-r ratulsarna lutr0 danielz1z emanuelst KristijanJovanovski rdev joshrad-dev kiranjd osolmaz adityashaw2 CashWilliams sheeek artuskg Takhoffman onutc pauloportella neooriginal manuelhettich minghinmatthewlam myfunc travisirby buddyh connorshea kyleok mcinteerj dependabot[bot] John-Rood timkrase uos-status gerardward2007 obviyus roshanasingh4 tosh-hamburg azade-c JonUleis bjesuiter @@ -504,7 +504,7 @@ Thanks to all clawtributors: Lloyd loukotal louzhixian martinpucik Matt mini Miles mrdbstn MSch Mustafa Tag Eldeen ndraiman nexty5870 Noctivoro prathamdby ptn1411 reeltimeapps RLTCmpe Rolf Fredheim Rony Kelner Samrat Jha senoldogann Seredeep sergical shiv19 shiyuanhai siraht snopoke testingabc321 The Admiral thesash Ubuntu - voidserf Vultr-Clawd Admin Wimmie wstock yazinsai ymat19 Zach Knickerbocker aaronn Alphonse-arianee Azade - carlulsoe ddyo Erik latitudeki5223 Manuel Maly Mourad Boustani odrobnik pcty-nextgen-ios-builder Quentin Randy Torres - rhjoh ronak-guliani William Stock + voidserf Vultr-Clawd Admin Wimmie wstock yazinsai ymat19 Zach Knickerbocker 0xJonHoldsCrypto aaronn Alphonse-arianee + atalovesyou Azade carlulsoe ddyo Erik hougangdev latitudeki5223 Manuel Maly Mourad Boustani odrobnik + pcty-nextgen-ios-builder Quentin Randy Torres rhjoh ronak-guliani William Stock

diff --git a/scripts/clawtributors-map.json b/scripts/clawtributors-map.json index 8899afc93..d652938a6 100644 --- a/scripts/clawtributors-map.json +++ b/scripts/clawtributors-map.json @@ -12,7 +12,10 @@ "manmal", "thesash", "rhjoh", - "ysqander" + "ysqander", + "atalovesyou", + "0xJonHoldsCrypto", + "hougangdev" ], "seedCommit": "d6863f87", "placeholderAvatar": "assets/avatar-placeholder.svg", From 34ce004151c5a03d4beab5cfeddb36cce8373165 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:40:00 -0600 Subject: [PATCH 047/196] Gateway: prefer newest session entries in merge (#1823) --- CHANGELOG.md | 1 + src/gateway/session-utils.ts | 48 +++++++++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35f3ad89c..262c69057 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Status: unreleased. - Docs: credit both contributors for Control UI refresh. (#1852) Thanks @EnzeD. - Onboarding: add Venice API key to non-interactive flow. (#1893) Thanks @jonisjongithub. - Tlon: format thread reply IDs as @ud. (#1837) Thanks @wca4a. +- Gateway: prefer newest session metadata when combining stores. (#1823) Thanks @emanuelst. - CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. - macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. - Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. diff --git a/src/gateway/session-utils.ts b/src/gateway/session-utils.ts index c4046a08e..1cb4cc5c3 100644 --- a/src/gateway/session-utils.ts +++ b/src/gateway/session-utils.ts @@ -381,6 +381,31 @@ export function resolveGatewaySessionStoreTarget(params: { cfg: ClawdbotConfig; }; } +// Merge with existing entry based on latest timestamp to ensure data consistency and avoid overwriting with less complete data. +function mergeSessionEntryIntoCombined(params: { + combined: Record; + entry: SessionEntry; + agentId: string; + canonicalKey: string; +}) { + const { combined, entry, agentId, canonicalKey } = params; + const existing = combined[canonicalKey]; + + if (existing && (existing.updatedAt ?? 0) > (entry.updatedAt ?? 0)) { + combined[canonicalKey] = { + ...entry, + ...existing, + spawnedBy: canonicalizeSpawnedByForAgent(agentId, existing.spawnedBy ?? entry.spawnedBy), + }; + } else { + combined[canonicalKey] = { + ...existing, + ...entry, + spawnedBy: canonicalizeSpawnedByForAgent(agentId, entry.spawnedBy ?? existing?.spawnedBy), + }; + } +} + export function loadCombinedSessionStoreForGateway(cfg: ClawdbotConfig): { storePath: string; store: Record; @@ -393,10 +418,12 @@ export function loadCombinedSessionStoreForGateway(cfg: ClawdbotConfig): { const combined: Record = {}; for (const [key, entry] of Object.entries(store)) { const canonicalKey = canonicalizeSessionKeyForAgent(defaultAgentId, key); - combined[canonicalKey] = { - ...entry, - spawnedBy: canonicalizeSpawnedByForAgent(defaultAgentId, entry.spawnedBy), - }; + mergeSessionEntryIntoCombined({ + combined, + entry, + agentId: defaultAgentId, + canonicalKey, + }); } return { storePath, store: combined }; } @@ -408,13 +435,12 @@ export function loadCombinedSessionStoreForGateway(cfg: ClawdbotConfig): { const store = loadSessionStore(storePath); for (const [key, entry] of Object.entries(store)) { const canonicalKey = canonicalizeSessionKeyForAgent(agentId, key); - // Merge with existing entry if present (avoid overwriting with less complete data) - const existing = combined[canonicalKey]; - combined[canonicalKey] = { - ...existing, - ...entry, - spawnedBy: canonicalizeSpawnedByForAgent(agentId, entry.spawnedBy ?? existing?.spawnedBy), - }; + mergeSessionEntryIntoCombined({ + combined, + entry, + agentId, + canonicalKey, + }); } } From 08183fe0090d692725b9eac3fb38e09dc4c88e44 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 22:49:09 -0600 Subject: [PATCH 048/196] Web UI: keep sub-agent announce replies visible (#1977) --- CHANGELOG.md | 1 + ui/src/ui/controllers/chat.test.ts | 99 ++++++++++++++++++++++++++++++ ui/src/ui/controllers/chat.ts | 13 +++- 3 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 ui/src/ui/controllers/chat.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 262c69057..21a066ff7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Status: unreleased. - Onboarding: add Venice API key to non-interactive flow. (#1893) Thanks @jonisjongithub. - Tlon: format thread reply IDs as @ud. (#1837) Thanks @wca4a. - Gateway: prefer newest session metadata when combining stores. (#1823) Thanks @emanuelst. +- Web UI: keep sub-agent announce replies visible in WebChat. (#1977) Thanks @andrescardonas7. - CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. - macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. - Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. diff --git a/ui/src/ui/controllers/chat.test.ts b/ui/src/ui/controllers/chat.test.ts new file mode 100644 index 000000000..c75ceefc4 --- /dev/null +++ b/ui/src/ui/controllers/chat.test.ts @@ -0,0 +1,99 @@ +import { describe, expect, it } from "vitest"; + +import { + handleChatEvent, + type ChatEventPayload, + type ChatState, +} from "./chat"; + +function createState(overrides: Partial = {}): ChatState { + return { + client: null, + connected: true, + sessionKey: "main", + chatLoading: false, + chatMessages: [], + chatThinkingLevel: null, + chatSending: false, + chatMessage: "", + chatRunId: null, + chatStream: null, + chatStreamStartedAt: null, + lastError: null, + ...overrides, + }; +} + +describe("handleChatEvent", () => { + it("returns null when payload is missing", () => { + const state = createState(); + expect(handleChatEvent(state, undefined)).toBe(null); + }); + + it("returns null when sessionKey does not match", () => { + const state = createState({ sessionKey: "main" }); + const payload: ChatEventPayload = { + runId: "run-1", + sessionKey: "other", + state: "final", + }; + expect(handleChatEvent(state, payload)).toBe(null); + }); + + it("returns null for delta from another run", () => { + const state = createState({ + sessionKey: "main", + chatRunId: "run-user", + chatStream: "Hello", + }); + const payload: ChatEventPayload = { + runId: "run-announce", + sessionKey: "main", + state: "delta", + message: { role: "assistant", content: [{ type: "text", text: "Done" }] }, + }; + expect(handleChatEvent(state, payload)).toBe(null); + expect(state.chatRunId).toBe("run-user"); + expect(state.chatStream).toBe("Hello"); + }); + + it("returns 'final' for final from another run (e.g. sub-agent announce) without clearing state", () => { + const state = createState({ + sessionKey: "main", + chatRunId: "run-user", + chatStream: "Working...", + chatStreamStartedAt: 123, + }); + const payload: ChatEventPayload = { + runId: "run-announce", + sessionKey: "main", + state: "final", + message: { + role: "assistant", + content: [{ type: "text", text: "Sub-agent findings" }], + }, + }; + expect(handleChatEvent(state, payload)).toBe("final"); + expect(state.chatRunId).toBe("run-user"); + expect(state.chatStream).toBe("Working..."); + expect(state.chatStreamStartedAt).toBe(123); + }); + + it("processes final from own run and clears state", () => { + const state = createState({ + sessionKey: "main", + chatRunId: "run-1", + chatStream: "Reply", + chatStreamStartedAt: 100, + }); + const payload: ChatEventPayload = { + runId: "run-1", + sessionKey: "main", + state: "final", + }; + expect(handleChatEvent(state, payload)).toBe("final"); + expect(state.chatRunId).toBe(null); + expect(state.chatStream).toBe(null); + expect(state.chatStreamStartedAt).toBe(null); + }); +}); diff --git a/ui/src/ui/controllers/chat.ts b/ui/src/ui/controllers/chat.ts index 53027c6ea..3d967f672 100644 --- a/ui/src/ui/controllers/chat.ts +++ b/ui/src/ui/controllers/chat.ts @@ -1,5 +1,5 @@ -import type { GatewayBrowserClient } from "../gateway"; import { extractText } from "../chat/message-extract"; +import type { GatewayBrowserClient } from "../gateway"; import { generateUUID } from "../uuid"; export type ChatState = { @@ -115,8 +115,17 @@ export function handleChatEvent( ) { if (!payload) return null; if (payload.sessionKey !== state.sessionKey) return null; - if (payload.runId && state.chatRunId && payload.runId !== state.chatRunId) + + // Final from another run (e.g. sub-agent announce): refresh history to show new message. + // See https://github.com/clawdbot/clawdbot/issues/1909 + if ( + payload.runId && + state.chatRunId && + payload.runId !== state.chatRunId + ) { + if (payload.state === "final") return "final"; return null; + } if (payload.state === "delta") { const next = extractText(payload.message); From fabdf2f6f749a43e1f0b4be4f0da2557c74bdd52 Mon Sep 17 00:00:00 2001 From: joeynyc Date: Sun, 25 Jan 2026 13:45:09 -0500 Subject: [PATCH 049/196] feat(webchat): add image paste support - Add paste event handler to chat textarea to capture clipboard images - Add image preview UI with thumbnails and remove buttons - Update sendChatMessage to pass attachments to chat.send RPC - Add CSS styles for attachment preview (light/dark theme support) Closes #1681 (image paste support portion) Co-Authored-By: Claude Opus 4.5 --- ui/src/styles/chat/layout.css | 88 ++++++++++++++++++- ui/src/ui/app-chat.ts | 16 +++- ui/src/ui/app-render.ts | 2 + ui/src/ui/app.ts | 1 + ui/src/ui/controllers/chat.ts | 57 +++++++++++- ui/src/ui/views/chat.ts | 160 ++++++++++++++++++++++++++-------- 6 files changed, 282 insertions(+), 42 deletions(-) diff --git a/ui/src/styles/chat/layout.css b/ui/src/styles/chat/layout.css index e137cb8c8..951266a98 100644 --- a/ui/src/styles/chat/layout.css +++ b/ui/src/styles/chat/layout.css @@ -103,7 +103,7 @@ bottom: 0; flex-shrink: 0; display: flex; - align-items: stretch; + flex-direction: column; gap: 12px; margin-top: auto; /* Push to bottom of flex container */ padding: 12px 4px 4px; @@ -111,6 +111,92 @@ z-index: 10; } +/* Image attachments preview */ +.chat-attachments { + display: flex; + flex-wrap: wrap; + gap: 8px; + padding: 8px; + background: var(--panel); + border-radius: 8px; + border: 1px solid var(--border); +} + +.chat-attachment { + position: relative; + width: 80px; + height: 80px; + border-radius: 6px; + overflow: hidden; + border: 1px solid var(--border); + background: var(--bg); +} + +.chat-attachment__img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.chat-attachment__remove { + position: absolute; + top: 4px; + right: 4px; + width: 20px; + height: 20px; + border-radius: 50%; + border: none; + background: rgba(0, 0, 0, 0.7); + color: #fff; + font-size: 12px; + line-height: 1; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 150ms ease-out; +} + +.chat-attachment:hover .chat-attachment__remove { + opacity: 1; +} + +.chat-attachment__remove:hover { + background: rgba(220, 38, 38, 0.9); +} + +.chat-attachment__remove svg { + width: 12px; + height: 12px; + stroke: currentColor; + fill: none; + stroke-width: 2px; +} + +/* Light theme attachment overrides */ +:root[data-theme="light"] .chat-attachments { + background: #f8fafc; + border-color: rgba(16, 24, 40, 0.1); +} + +:root[data-theme="light"] .chat-attachment { + border-color: rgba(16, 24, 40, 0.15); + background: #fff; +} + +:root[data-theme="light"] .chat-attachment__remove { + background: rgba(0, 0, 0, 0.6); +} + +/* Compose input row - horizontal layout */ +.chat-compose__row { + display: flex; + align-items: stretch; + gap: 12px; + flex: 1; +} + :root[data-theme="light"] .chat-compose { background: linear-gradient(to bottom, transparent, var(--bg-content) 20%); } diff --git a/ui/src/ui/app-chat.ts b/ui/src/ui/app-chat.ts index 81aae3c88..3ff74935d 100644 --- a/ui/src/ui/app-chat.ts +++ b/ui/src/ui/app-chat.ts @@ -1,4 +1,4 @@ -import { abortChatRun, loadChatHistory, sendChatMessage } from "./controllers/chat"; +import { abortChatRun, loadChatHistory, sendChatMessage, type ChatAttachment } from "./controllers/chat"; import { loadSessions } from "./controllers/sessions"; import { generateUUID } from "./uuid"; import { resetToolStream } from "./app-tool-stream"; @@ -12,6 +12,7 @@ import type { ClawdbotApp } from "./app"; type ChatHost = { connected: boolean; chatMessage: string; + chatAttachments: ChatAttachment[]; chatQueue: Array<{ id: string; text: string; createdAt: number }>; chatRunId: string | null; chatSending: boolean; @@ -61,10 +62,10 @@ function enqueueChatMessage(host: ChatHost, text: string) { async function sendChatMessageNow( host: ChatHost, message: string, - opts?: { previousDraft?: string; restoreDraft?: boolean }, + opts?: { previousDraft?: string; restoreDraft?: boolean; attachments?: ChatAttachment[] }, ) { resetToolStream(host as unknown as Parameters[0]); - const ok = await sendChatMessage(host as unknown as ClawdbotApp, message); + const ok = await sendChatMessage(host as unknown as ClawdbotApp, message, opts?.attachments); if (!ok && opts?.previousDraft != null) { host.chatMessage = opts.previousDraft; } @@ -104,7 +105,11 @@ export async function handleSendChat( if (!host.connected) return; const previousDraft = host.chatMessage; const message = (messageOverride ?? host.chatMessage).trim(); - if (!message) return; + const attachments = host.chatAttachments ?? []; + const hasAttachments = attachments.length > 0; + + // Allow sending with just attachments (no message text required) + if (!message && !hasAttachments) return; if (isChatStopCommand(message)) { await handleAbortChat(host); @@ -113,6 +118,8 @@ export async function handleSendChat( if (messageOverride == null) { host.chatMessage = ""; + // Clear attachments when sending + host.chatAttachments = []; } if (isChatBusy(host)) { @@ -123,6 +130,7 @@ export async function handleSendChat( await sendChatMessageNow(host, message, { previousDraft: messageOverride == null ? previousDraft : undefined, restoreDraft: Boolean(messageOverride && opts?.restoreDraft), + attachments: hasAttachments ? attachments : undefined, }); } diff --git a/ui/src/ui/app-render.ts b/ui/src/ui/app-render.ts index db29bd7ec..38b16b084 100644 --- a/ui/src/ui/app-render.ts +++ b/ui/src/ui/app-render.ts @@ -477,6 +477,8 @@ export function renderApp(state: AppViewState) { }, onChatScroll: (event) => state.handleChatScroll(event), onDraftChange: (next) => (state.chatMessage = next), + attachments: state.chatAttachments, + onAttachmentsChange: (next) => (state.chatAttachments = next), onSend: () => state.handleSendChat(), canAbort: Boolean(state.chatRunId), onAbort: () => void state.handleAbortChat(), diff --git a/ui/src/ui/app.ts b/ui/src/ui/app.ts index 0e21d283a..310305ff9 100644 --- a/ui/src/ui/app.ts +++ b/ui/src/ui/app.ts @@ -129,6 +129,7 @@ export class ClawdbotApp extends LitElement { @state() chatAvatarUrl: string | null = null; @state() chatThinkingLevel: string | null = null; @state() chatQueue: ChatQueueItem[] = []; + @state() chatAttachments: Array<{ id: string; dataUrl: string; mimeType: string }> = []; // Sidebar state for tool output viewing @state() sidebarOpen = false; @state() sidebarContent: string | null = null; diff --git a/ui/src/ui/controllers/chat.ts b/ui/src/ui/controllers/chat.ts index 3d967f672..644d49358 100644 --- a/ui/src/ui/controllers/chat.ts +++ b/ui/src/ui/controllers/chat.ts @@ -2,6 +2,12 @@ import { extractText } from "../chat/message-extract"; import type { GatewayBrowserClient } from "../gateway"; import { generateUUID } from "../uuid"; +export type ChatAttachment = { + id: string; + dataUrl: string; + mimeType: string; +}; + export type ChatState = { client: GatewayBrowserClient | null; connected: boolean; @@ -11,6 +17,7 @@ export type ChatState = { chatThinkingLevel: string | null; chatSending: boolean; chatMessage: string; + chatAttachments: ChatAttachment[]; chatRunId: string | null; chatStream: string | null; chatStreamStartedAt: number | null; @@ -43,17 +50,44 @@ export async function loadChatHistory(state: ChatState) { } } -export async function sendChatMessage(state: ChatState, message: string): Promise { +function dataUrlToBase64(dataUrl: string): { content: string; mimeType: string } | null { + const match = /^data:([^;]+);base64,(.+)$/.exec(dataUrl); + if (!match) return null; + return { mimeType: match[1], content: match[2] }; +} + +export async function sendChatMessage( + state: ChatState, + message: string, + attachments?: ChatAttachment[], +): Promise { if (!state.client || !state.connected) return false; const msg = message.trim(); - if (!msg) return false; + const hasAttachments = attachments && attachments.length > 0; + if (!msg && !hasAttachments) return false; const now = Date.now(); + + // Build user message content blocks + const contentBlocks: Array<{ type: string; text?: string; source?: unknown }> = []; + if (msg) { + contentBlocks.push({ type: "text", text: msg }); + } + // Add image previews to the message for display + if (hasAttachments) { + for (const att of attachments) { + contentBlocks.push({ + type: "image", + source: { type: "base64", media_type: att.mimeType, data: att.dataUrl }, + }); + } + } + state.chatMessages = [ ...state.chatMessages, { role: "user", - content: [{ type: "text", text: msg }], + content: contentBlocks, timestamp: now, }, ]; @@ -64,12 +98,29 @@ export async function sendChatMessage(state: ChatState, message: string): Promis state.chatRunId = runId; state.chatStream = ""; state.chatStreamStartedAt = now; + + // Convert attachments to API format + const apiAttachments = hasAttachments + ? attachments + .map((att) => { + const parsed = dataUrlToBase64(att.dataUrl); + if (!parsed) return null; + return { + type: "image", + mimeType: parsed.mimeType, + content: parsed.content, + }; + }) + .filter((a): a is NonNullable => a !== null) + : undefined; + try { await state.client.request("chat.send", { sessionKey: state.sessionKey, message: msg, deliver: false, idempotencyKey: runId, + attachments: apiAttachments, }); return true; } catch (err) { diff --git a/ui/src/ui/views/chat.ts b/ui/src/ui/views/chat.ts index dd61ca0ec..17fc8401f 100644 --- a/ui/src/ui/views/chat.ts +++ b/ui/src/ui/views/chat.ts @@ -22,6 +22,12 @@ export type CompactionIndicatorStatus = { completedAt: number | null; }; +export type ChatAttachment = { + id: string; + dataUrl: string; + mimeType: string; +}; + export type ChatProps = { sessionKey: string; onSessionKeyChange: (next: string) => void; @@ -52,6 +58,9 @@ export type ChatProps = { splitRatio?: number; assistantName: string; assistantAvatar: string | null; + // Image attachments + attachments?: ChatAttachment[]; + onAttachmentsChange?: (attachments: ChatAttachment[]) => void; // Event handlers onRefresh: () => void; onToggleFocusMode: () => void; @@ -95,6 +104,82 @@ function renderCompactionIndicator(status: CompactionIndicatorStatus | null | un return nothing; } +function generateAttachmentId(): string { + return `att-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`; +} + +function handlePaste( + e: ClipboardEvent, + props: ChatProps, +) { + const items = e.clipboardData?.items; + if (!items || !props.onAttachmentsChange) return; + + const imageItems: DataTransferItem[] = []; + for (let i = 0; i < items.length; i++) { + const item = items[i]; + if (item.type.startsWith("image/")) { + imageItems.push(item); + } + } + + if (imageItems.length === 0) return; + + e.preventDefault(); + + for (const item of imageItems) { + const file = item.getAsFile(); + if (!file) continue; + + const reader = new FileReader(); + reader.onload = () => { + const dataUrl = reader.result as string; + const newAttachment: ChatAttachment = { + id: generateAttachmentId(), + dataUrl, + mimeType: file.type, + }; + const current = props.attachments ?? []; + props.onAttachmentsChange?.([...current, newAttachment]); + }; + reader.readAsDataURL(file); + } +} + +function renderAttachmentPreview(props: ChatProps) { + const attachments = props.attachments ?? []; + if (attachments.length === 0) return nothing; + + return html` +
+ ${attachments.map( + (att) => html` +
+ Attachment preview + +
+ `, + )} +
+ `; +} + export function renderChat(props: ChatProps) { const canCompose = props.connected; const isBusy = props.sending || props.stream !== null; @@ -109,8 +194,11 @@ export function renderChat(props: ChatProps) { avatar: props.assistantAvatar ?? props.assistantAvatarUrl ?? null, }; + const hasAttachments = (props.attachments?.length ?? 0) > 0; const composePlaceholder = props.connected - ? "Message (↩ to send, Shift+↩ for line breaks)" + ? hasAttachments + ? "Add a message or paste more images..." + : "Message (↩ to send, Shift+↩ for line breaks, paste images)" : "Connect to the gateway to start chatting…"; const splitRatio = props.splitRatio ?? 0.6; @@ -235,39 +323,43 @@ export function renderChat(props: ChatProps) { : nothing}
- -
- - + ${renderAttachmentPreview(props)} +
+ +
+ + +
From 9ba4b1e32b5a4f50b2c9b2294d6ba21d66e38bb7 Mon Sep 17 00:00:00 2001 From: Clawd Date: Sun, 25 Jan 2026 22:46:09 +0300 Subject: [PATCH 050/196] fix(webchat): improve image paste UI layout and display - Fix preview container width (use inline-flex + fit-content) - Fix flex layout conflict in components.css (grid -> flex column) - Change preview thumbnail to object-fit: contain (no cropping) - Add image rendering in sent message bubbles - Add CSS for chat-message-images display Improves upon #1900 --- ui/src/styles/chat/layout.css | 33 +++++++++++++++- ui/src/styles/components.css | 5 +-- ui/src/ui/chat/grouped-render.ts | 66 +++++++++++++++++++++++++++++++- 3 files changed, 98 insertions(+), 6 deletions(-) diff --git a/ui/src/styles/chat/layout.css b/ui/src/styles/chat/layout.css index 951266a98..e11fedb71 100644 --- a/ui/src/styles/chat/layout.css +++ b/ui/src/styles/chat/layout.css @@ -113,13 +113,16 @@ /* Image attachments preview */ .chat-attachments { - display: flex; + display: inline-flex; flex-wrap: wrap; gap: 8px; padding: 8px; background: var(--panel); border-radius: 8px; border: 1px solid var(--border); + width: fit-content; + max-width: 100%; + align-self: flex-start; /* Don't stretch in flex column parent */ } .chat-attachment { @@ -135,7 +138,7 @@ .chat-attachment__img { width: 100%; height: 100%; - object-fit: cover; + object-fit: contain; } .chat-attachment__remove { @@ -189,6 +192,32 @@ background: rgba(0, 0, 0, 0.6); } +/* Message images (sent images displayed in chat) */ +.chat-message-images { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 8px; +} + +.chat-message-image { + max-width: 300px; + max-height: 200px; + border-radius: 8px; + object-fit: contain; + cursor: pointer; + transition: transform 150ms ease-out; +} + +.chat-message-image:hover { + transform: scale(1.02); +} + +/* User message images align right */ +.chat-group.user .chat-message-images { + justify-content: flex-end; +} + /* Compose input row - horizontal layout */ .chat-compose__row { display: flex; diff --git a/ui/src/styles/components.css b/ui/src/styles/components.css index a78e0ef0a..27dfe62d1 100644 --- a/ui/src/styles/components.css +++ b/ui/src/styles/components.css @@ -1303,9 +1303,8 @@ /* Chat compose */ .chat-compose { margin-top: 12px; - display: grid; - grid-template-columns: minmax(0, 1fr) auto; - align-items: end; + display: flex; + flex-direction: column; gap: 10px; } diff --git a/ui/src/ui/chat/grouped-render.ts b/ui/src/ui/chat/grouped-render.ts index ea1c7ffda..4a9ccec14 100644 --- a/ui/src/ui/chat/grouped-render.ts +++ b/ui/src/ui/chat/grouped-render.ts @@ -13,6 +13,48 @@ import { } from "./message-extract"; import { extractToolCards, renderToolCardSidebar } from "./tool-cards"; +type ImageBlock = { + url: string; + alt?: string; +}; + +function extractImages(message: unknown): ImageBlock[] { + const m = message as Record; + const content = m.content; + const images: ImageBlock[] = []; + + if (Array.isArray(content)) { + for (const block of content) { + if (typeof block !== "object" || block === null) continue; + const b = block as Record; + + if (b.type === "image") { + // Handle source object format (from sendChatMessage) + const source = b.source as Record | undefined; + if (source?.type === "base64" && typeof source.data === "string") { + const data = source.data as string; + const mediaType = (source.media_type as string) || "image/png"; + // If data is already a data URL, use it directly + const url = data.startsWith("data:") + ? data + : `data:${mediaType};base64,${data}`; + images.push({ url }); + } else if (typeof b.url === "string") { + images.push({ url: b.url }); + } + } else if (b.type === "image_url") { + // OpenAI format + const imageUrl = b.image_url as Record | undefined; + if (typeof imageUrl?.url === "string") { + images.push({ url: imageUrl.url }); + } + } + } + } + + return images; +} + export function renderReadingIndicatorGroup(assistant?: AssistantIdentity) { return html`
@@ -163,6 +205,25 @@ function isAvatarUrl(value: string): boolean { ); } +function renderMessageImages(images: ImageBlock[]) { + if (images.length === 0) return nothing; + + return html` +
+ ${images.map( + (img) => html` + ${img.alt window.open(img.url, "_blank")} + /> + `, + )} +
+ `; +} + function renderGroupedMessage( message: unknown, opts: { isStreaming: boolean; showReasoning: boolean }, @@ -179,6 +240,8 @@ function renderGroupedMessage( const toolCards = extractToolCards(message); const hasToolCards = toolCards.length > 0; + const images = extractImages(message); + const hasImages = images.length > 0; const extractedText = extractTextCached(message); const extractedThinking = @@ -207,11 +270,12 @@ function renderGroupedMessage( )}`; } - if (!markdown && !hasToolCards) return nothing; + if (!markdown && !hasToolCards && !hasImages) return nothing; return html`
${canCopyMarkdown ? renderCopyAsMarkdownButton(markdown!) : nothing} + ${renderMessageImages(images)} ${reasoningMarkdown ? html`
${unsafeHTML( toSanitizedMarkdownHtml(reasoningMarkdown), From 6859e1e6a66691282f2394cd8f8ab2eef3e8c45d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 26 Jan 2026 05:32:29 +0000 Subject: [PATCH 051/196] fix(webchat): support image-only sends --- CHANGELOG.md | 3 ++ src/gateway/protocol/schema/logs-chat.ts | 2 +- src/gateway/server-methods/chat.ts | 9 +++++ ...erver.chat.gateway-server-chat.e2e.test.ts | 33 +++++++++++++++++ ui/src/ui/app-chat.ts | 36 ++++++++++++++----- ui/src/ui/app-render.ts | 1 + ui/src/ui/app-view-state.ts | 3 +- ui/src/ui/app.ts | 4 +-- ui/src/ui/controllers/chat.ts | 7 +--- ui/src/ui/ui-types.ts | 7 ++++ ui/src/ui/views/chat.ts | 15 ++++---- 11 files changed, 93 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21a066ff7..9742150a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,9 @@ Status: unreleased. - Slack: clear ack reaction after streamed replies. (#2044) Thanks @fancyboi999. - macOS: keep custom SSH usernames in remote target. (#2046) Thanks @algal. +### Fixes +- Web UI: improve WebChat image paste previews and allow image-only sends. (#1925) Thanks @smartprogrammer93. + ## 2026.1.24-3 ### Fixes diff --git a/src/gateway/protocol/schema/logs-chat.ts b/src/gateway/protocol/schema/logs-chat.ts index 7b684771a..dc04a29d5 100644 --- a/src/gateway/protocol/schema/logs-chat.ts +++ b/src/gateway/protocol/schema/logs-chat.ts @@ -35,7 +35,7 @@ export const ChatHistoryParamsSchema = Type.Object( export const ChatSendParamsSchema = Type.Object( { sessionKey: NonEmptyString, - message: NonEmptyString, + message: Type.String(), thinking: Type.Optional(Type.String()), deliver: Type.Optional(Type.Boolean()), attachments: Type.Optional(Type.Array(Type.Unknown())), diff --git a/src/gateway/server-methods/chat.ts b/src/gateway/server-methods/chat.ts index 50f441779..9010a6f21 100644 --- a/src/gateway/server-methods/chat.ts +++ b/src/gateway/server-methods/chat.ts @@ -338,6 +338,15 @@ export const chatHandlers: GatewayRequestHandlers = { : undefined, })) .filter((a) => a.content) ?? []; + const rawMessage = p.message.trim(); + if (!rawMessage && normalizedAttachments.length === 0) { + respond( + false, + undefined, + errorShape(ErrorCodes.INVALID_REQUEST, "message or attachment required"), + ); + return; + } let parsedMessage = p.message; let parsedImages: ChatImageContent[] = []; if (normalizedAttachments.length > 0) { diff --git a/src/gateway/server.chat.gateway-server-chat.e2e.test.ts b/src/gateway/server.chat.gateway-server-chat.e2e.test.ts index 54f772580..6827b24c4 100644 --- a/src/gateway/server.chat.gateway-server-chat.e2e.test.ts +++ b/src/gateway/server.chat.gateway-server-chat.e2e.test.ts @@ -208,6 +208,39 @@ describe("gateway server chat", () => { | undefined; expect(imgOpts?.images).toEqual([{ type: "image", data: pngB64, mimeType: "image/png" }]); + const callsBeforeImageOnly = spy.mock.calls.length; + const reqIdOnly = "chat-img-only"; + ws.send( + JSON.stringify({ + type: "req", + id: reqIdOnly, + method: "chat.send", + params: { + sessionKey: "main", + message: "", + idempotencyKey: "idem-img-only", + attachments: [ + { + type: "image", + mimeType: "image/png", + fileName: "dot.png", + content: `data:image/png;base64,${pngB64}`, + }, + ], + }, + }), + ); + + const imgOnlyRes = await onceMessage(ws, (o) => o.type === "res" && o.id === reqIdOnly, 8000); + expect(imgOnlyRes.ok).toBe(true); + expect(imgOnlyRes.payload?.runId).toBeDefined(); + + await waitFor(() => spy.mock.calls.length > callsBeforeImageOnly, 8000); + const imgOnlyOpts = spy.mock.calls.at(-1)?.[1] as + | { images?: Array<{ type: string; data: string; mimeType: string }> } + | undefined; + expect(imgOnlyOpts?.images).toEqual([{ type: "image", data: pngB64, mimeType: "image/png" }]); + const historyDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-gw-")); tempDirs.push(historyDir); testState.sessionStorePath = path.join(historyDir, "sessions.json"); diff --git a/ui/src/ui/app-chat.ts b/ui/src/ui/app-chat.ts index 3ff74935d..c5f883716 100644 --- a/ui/src/ui/app-chat.ts +++ b/ui/src/ui/app-chat.ts @@ -1,4 +1,4 @@ -import { abortChatRun, loadChatHistory, sendChatMessage, type ChatAttachment } from "./controllers/chat"; +import { abortChatRun, loadChatHistory, sendChatMessage } from "./controllers/chat"; import { loadSessions } from "./controllers/sessions"; import { generateUUID } from "./uuid"; import { resetToolStream } from "./app-tool-stream"; @@ -8,12 +8,13 @@ import { normalizeBasePath } from "./navigation"; import type { GatewayHelloOk } from "./gateway"; import { parseAgentSessionKey } from "../../../src/sessions/session-key-utils.js"; import type { ClawdbotApp } from "./app"; +import type { ChatAttachment, ChatQueueItem } from "./ui-types"; type ChatHost = { connected: boolean; chatMessage: string; chatAttachments: ChatAttachment[]; - chatQueue: Array<{ id: string; text: string; createdAt: number }>; + chatQueue: ChatQueueItem[]; chatRunId: string | null; chatSending: boolean; sessionKey: string; @@ -46,15 +47,17 @@ export async function handleAbortChat(host: ChatHost) { await abortChatRun(host as unknown as ClawdbotApp); } -function enqueueChatMessage(host: ChatHost, text: string) { +function enqueueChatMessage(host: ChatHost, text: string, attachments?: ChatAttachment[]) { const trimmed = text.trim(); - if (!trimmed) return; + const hasAttachments = Boolean(attachments && attachments.length > 0); + if (!trimmed && !hasAttachments) return; host.chatQueue = [ ...host.chatQueue, { id: generateUUID(), text: trimmed, createdAt: Date.now(), + attachments: hasAttachments ? attachments?.map((att) => ({ ...att })) : undefined, }, ]; } @@ -62,19 +65,31 @@ function enqueueChatMessage(host: ChatHost, text: string) { async function sendChatMessageNow( host: ChatHost, message: string, - opts?: { previousDraft?: string; restoreDraft?: boolean; attachments?: ChatAttachment[] }, + opts?: { + previousDraft?: string; + restoreDraft?: boolean; + attachments?: ChatAttachment[]; + previousAttachments?: ChatAttachment[]; + restoreAttachments?: boolean; + }, ) { resetToolStream(host as unknown as Parameters[0]); const ok = await sendChatMessage(host as unknown as ClawdbotApp, message, opts?.attachments); if (!ok && opts?.previousDraft != null) { host.chatMessage = opts.previousDraft; } + if (!ok && opts?.previousAttachments) { + host.chatAttachments = opts.previousAttachments; + } if (ok) { setLastActiveSessionKey(host as unknown as Parameters[0], host.sessionKey); } if (ok && opts?.restoreDraft && opts.previousDraft?.trim()) { host.chatMessage = opts.previousDraft; } + if (ok && opts?.restoreAttachments && opts.previousAttachments?.length) { + host.chatAttachments = opts.previousAttachments; + } scheduleChatScroll(host as unknown as Parameters[0]); if (ok && !host.chatRunId) { void flushChatQueue(host); @@ -87,7 +102,7 @@ async function flushChatQueue(host: ChatHost) { const [next, ...rest] = host.chatQueue; if (!next) return; host.chatQueue = rest; - const ok = await sendChatMessageNow(host, next.text); + const ok = await sendChatMessageNow(host, next.text, { attachments: next.attachments }); if (!ok) { host.chatQueue = [next, ...host.chatQueue]; } @@ -106,7 +121,8 @@ export async function handleSendChat( const previousDraft = host.chatMessage; const message = (messageOverride ?? host.chatMessage).trim(); const attachments = host.chatAttachments ?? []; - const hasAttachments = attachments.length > 0; + const attachmentsToSend = messageOverride == null ? attachments : []; + const hasAttachments = attachmentsToSend.length > 0; // Allow sending with just attachments (no message text required) if (!message && !hasAttachments) return; @@ -123,14 +139,16 @@ export async function handleSendChat( } if (isChatBusy(host)) { - enqueueChatMessage(host, message); + enqueueChatMessage(host, message, attachmentsToSend); return; } await sendChatMessageNow(host, message, { previousDraft: messageOverride == null ? previousDraft : undefined, restoreDraft: Boolean(messageOverride && opts?.restoreDraft), - attachments: hasAttachments ? attachments : undefined, + attachments: hasAttachments ? attachmentsToSend : undefined, + previousAttachments: messageOverride == null ? attachments : undefined, + restoreAttachments: Boolean(messageOverride && opts?.restoreDraft), }); } diff --git a/ui/src/ui/app-render.ts b/ui/src/ui/app-render.ts index 38b16b084..fe67c86f1 100644 --- a/ui/src/ui/app-render.ts +++ b/ui/src/ui/app-render.ts @@ -431,6 +431,7 @@ export function renderApp(state: AppViewState) { onSessionKeyChange: (next) => { state.sessionKey = next; state.chatMessage = ""; + state.chatAttachments = []; state.chatStream = null; state.chatStreamStartedAt = null; state.chatRunId = null; diff --git a/ui/src/ui/app-view-state.ts b/ui/src/ui/app-view-state.ts index f589c760c..069465e32 100644 --- a/ui/src/ui/app-view-state.ts +++ b/ui/src/ui/app-view-state.ts @@ -19,7 +19,7 @@ import type { SkillStatusReport, StatusSummary, } from "./types"; -import type { ChatQueueItem, CronFormState } from "./ui-types"; +import type { ChatAttachment, ChatQueueItem, CronFormState } from "./ui-types"; import type { EventLogEntry } from "./app-events"; import type { SkillMessage } from "./controllers/skills"; import type { @@ -49,6 +49,7 @@ export type AppViewState = { chatLoading: boolean; chatSending: boolean; chatMessage: string; + chatAttachments: ChatAttachment[]; chatMessages: unknown[]; chatToolMessages: unknown[]; chatStream: string | null; diff --git a/ui/src/ui/app.ts b/ui/src/ui/app.ts index 310305ff9..649e76342 100644 --- a/ui/src/ui/app.ts +++ b/ui/src/ui/app.ts @@ -24,7 +24,7 @@ import type { StatusSummary, NostrProfile, } from "./types"; -import { type ChatQueueItem, type CronFormState } from "./ui-types"; +import { type ChatAttachment, type ChatQueueItem, type CronFormState } from "./ui-types"; import type { EventLogEntry } from "./app-events"; import { DEFAULT_CRON_FORM, DEFAULT_LOG_LEVEL_FILTERS } from "./app-defaults"; import type { @@ -129,7 +129,7 @@ export class ClawdbotApp extends LitElement { @state() chatAvatarUrl: string | null = null; @state() chatThinkingLevel: string | null = null; @state() chatQueue: ChatQueueItem[] = []; - @state() chatAttachments: Array<{ id: string; dataUrl: string; mimeType: string }> = []; + @state() chatAttachments: ChatAttachment[] = []; // Sidebar state for tool output viewing @state() sidebarOpen = false; @state() sidebarContent: string | null = null; diff --git a/ui/src/ui/controllers/chat.ts b/ui/src/ui/controllers/chat.ts index 644d49358..518c35fe1 100644 --- a/ui/src/ui/controllers/chat.ts +++ b/ui/src/ui/controllers/chat.ts @@ -1,12 +1,7 @@ import { extractText } from "../chat/message-extract"; import type { GatewayBrowserClient } from "../gateway"; import { generateUUID } from "../uuid"; - -export type ChatAttachment = { - id: string; - dataUrl: string; - mimeType: string; -}; +import type { ChatAttachment } from "../ui-types"; export type ChatState = { client: GatewayBrowserClient | null; diff --git a/ui/src/ui/ui-types.ts b/ui/src/ui/ui-types.ts index 428c4c381..196d6d114 100644 --- a/ui/src/ui/ui-types.ts +++ b/ui/src/ui/ui-types.ts @@ -1,7 +1,14 @@ +export type ChatAttachment = { + id: string; + dataUrl: string; + mimeType: string; +}; + export type ChatQueueItem = { id: string; text: string; createdAt: number; + attachments?: ChatAttachment[]; }; export const CRON_CHANNEL_LAST = "last"; diff --git a/ui/src/ui/views/chat.ts b/ui/src/ui/views/chat.ts index 17fc8401f..a9b4da572 100644 --- a/ui/src/ui/views/chat.ts +++ b/ui/src/ui/views/chat.ts @@ -1,7 +1,7 @@ import { html, nothing } from "lit"; import { repeat } from "lit/directives/repeat.js"; import type { SessionsListResult } from "../types"; -import type { ChatQueueItem } from "../ui-types"; +import type { ChatAttachment, ChatQueueItem } from "../ui-types"; import type { ChatItem, MessageGroup } from "../types/chat-types"; import { icons } from "../icons"; import { @@ -22,12 +22,6 @@ export type CompactionIndicatorStatus = { completedAt: number | null; }; -export type ChatAttachment = { - id: string; - dataUrl: string; - mimeType: string; -}; - export type ChatProps = { sessionKey: string; onSessionKeyChange: (next: string) => void; @@ -305,7 +299,12 @@ export function renderChat(props: ChatProps) { ${props.queue.map( (item) => html`
-
${item.text}
+
+ ${item.text || + (item.attachments?.length + ? `Image (${item.attachments.length})` + : "")} +
- `}function ju(e){return zu({text:()=>e,label:or})}const qu={icon:"puzzle",detailKeys:["command","path","url","targetUrl","targetId","ref","element","node","nodeId","id","requestId","to","channelId","guildId","userId","name","query","pattern","messageId"]},Vu={bash:{icon:"wrench",title:"Bash",detailKeys:["command"]},process:{icon:"wrench",title:"Process",detailKeys:["sessionId"]},read:{icon:"fileText",title:"Read",detailKeys:["path"]},write:{icon:"edit",title:"Write",detailKeys:["path"]},edit:{icon:"penLine",title:"Edit",detailKeys:["path"]},attach:{icon:"paperclip",title:"Attach",detailKeys:["path","url","fileName"]},browser:{icon:"globe",title:"Browser",actions:{status:{label:"status"},start:{label:"start"},stop:{label:"stop"},tabs:{label:"tabs"},open:{label:"open",detailKeys:["targetUrl"]},focus:{label:"focus",detailKeys:["targetId"]},close:{label:"close",detailKeys:["targetId"]},snapshot:{label:"snapshot",detailKeys:["targetUrl","targetId","ref","element","format"]},screenshot:{label:"screenshot",detailKeys:["targetUrl","targetId","ref","element"]},navigate:{label:"navigate",detailKeys:["targetUrl","targetId"]},console:{label:"console",detailKeys:["level","targetId"]},pdf:{label:"pdf",detailKeys:["targetId"]},upload:{label:"upload",detailKeys:["paths","ref","inputRef","element","targetId"]},dialog:{label:"dialog",detailKeys:["accept","promptText","targetId"]},act:{label:"act",detailKeys:["request.kind","request.ref","request.selector","request.text","request.value"]}}},canvas:{icon:"image",title:"Canvas",actions:{present:{label:"present",detailKeys:["target","node","nodeId"]},hide:{label:"hide",detailKeys:["node","nodeId"]},navigate:{label:"navigate",detailKeys:["url","node","nodeId"]},eval:{label:"eval",detailKeys:["javaScript","node","nodeId"]},snapshot:{label:"snapshot",detailKeys:["format","node","nodeId"]},a2ui_push:{label:"A2UI push",detailKeys:["jsonlPath","node","nodeId"]},a2ui_reset:{label:"A2UI reset",detailKeys:["node","nodeId"]}}},nodes:{icon:"smartphone",title:"Nodes",actions:{status:{label:"status"},describe:{label:"describe",detailKeys:["node","nodeId"]},pending:{label:"pending"},approve:{label:"approve",detailKeys:["requestId"]},reject:{label:"reject",detailKeys:["requestId"]},notify:{label:"notify",detailKeys:["node","nodeId","title","body"]},camera_snap:{label:"camera snap",detailKeys:["node","nodeId","facing","deviceId"]},camera_list:{label:"camera list",detailKeys:["node","nodeId"]},camera_clip:{label:"camera clip",detailKeys:["node","nodeId","facing","duration","durationMs"]},screen_record:{label:"screen record",detailKeys:["node","nodeId","duration","durationMs","fps","screenIndex"]}}},cron:{icon:"loader",title:"Cron",actions:{status:{label:"status"},list:{label:"list"},add:{label:"add",detailKeys:["job.name","job.id","job.schedule","job.cron"]},update:{label:"update",detailKeys:["id"]},remove:{label:"remove",detailKeys:["id"]},run:{label:"run",detailKeys:["id"]},runs:{label:"runs",detailKeys:["id"]},wake:{label:"wake",detailKeys:["text","mode"]}}},gateway:{icon:"plug",title:"Gateway",actions:{restart:{label:"restart",detailKeys:["reason","delayMs"]},"config.get":{label:"config get"},"config.schema":{label:"config schema"},"config.apply":{label:"config apply",detailKeys:["restartDelayMs"]},"update.run":{label:"update run",detailKeys:["restartDelayMs"]}}},whatsapp_login:{icon:"circle",title:"WhatsApp Login",actions:{start:{label:"start"},wait:{label:"wait"}}},discord:{icon:"messageSquare",title:"Discord",actions:{react:{label:"react",detailKeys:["channelId","messageId","emoji"]},reactions:{label:"reactions",detailKeys:["channelId","messageId"]},sticker:{label:"sticker",detailKeys:["to","stickerIds"]},poll:{label:"poll",detailKeys:["question","to"]},permissions:{label:"permissions",detailKeys:["channelId"]},readMessages:{label:"read messages",detailKeys:["channelId","limit"]},sendMessage:{label:"send",detailKeys:["to","content"]},editMessage:{label:"edit",detailKeys:["channelId","messageId"]},deleteMessage:{label:"delete",detailKeys:["channelId","messageId"]},threadCreate:{label:"thread create",detailKeys:["channelId","name"]},threadList:{label:"thread list",detailKeys:["guildId","channelId"]},threadReply:{label:"thread reply",detailKeys:["channelId","content"]},pinMessage:{label:"pin",detailKeys:["channelId","messageId"]},unpinMessage:{label:"unpin",detailKeys:["channelId","messageId"]},listPins:{label:"list pins",detailKeys:["channelId"]},searchMessages:{label:"search",detailKeys:["guildId","content"]},memberInfo:{label:"member",detailKeys:["guildId","userId"]},roleInfo:{label:"roles",detailKeys:["guildId"]},emojiList:{label:"emoji list",detailKeys:["guildId"]},roleAdd:{label:"role add",detailKeys:["guildId","userId","roleId"]},roleRemove:{label:"role remove",detailKeys:["guildId","userId","roleId"]},channelInfo:{label:"channel",detailKeys:["channelId"]},channelList:{label:"channels",detailKeys:["guildId"]},voiceStatus:{label:"voice",detailKeys:["guildId","userId"]},eventList:{label:"events",detailKeys:["guildId"]},eventCreate:{label:"event create",detailKeys:["guildId","name"]},timeout:{label:"timeout",detailKeys:["guildId","userId"]},kick:{label:"kick",detailKeys:["guildId","userId"]},ban:{label:"ban",detailKeys:["guildId","userId"]}}},slack:{icon:"messageSquare",title:"Slack",actions:{react:{label:"react",detailKeys:["channelId","messageId","emoji"]},reactions:{label:"reactions",detailKeys:["channelId","messageId"]},sendMessage:{label:"send",detailKeys:["to","content"]},editMessage:{label:"edit",detailKeys:["channelId","messageId"]},deleteMessage:{label:"delete",detailKeys:["channelId","messageId"]},readMessages:{label:"read messages",detailKeys:["channelId","limit"]},pinMessage:{label:"pin",detailKeys:["channelId","messageId"]},unpinMessage:{label:"unpin",detailKeys:["channelId","messageId"]},listPins:{label:"list pins",detailKeys:["channelId"]},memberInfo:{label:"member",detailKeys:["userId"]},emojiList:{label:"emoji list"}}}},Wu={fallback:qu,tools:Vu},rr=Wu,Sa=rr.fallback??{icon:"puzzle"},Gu=rr.tools??{};function Yu(e){return(e??"tool").trim()}function Qu(e){const t=e.replace(/_/g," ").trim();return t?t.split(/\s+/).map(n=>n.length<=2&&n.toUpperCase()===n?n:`${n.at(0)?.toUpperCase()??""}${n.slice(1)}`).join(" "):"Tool"}function Zu(e){const t=e?.trim();if(t)return t.replace(/_/g," ")}function lr(e){if(e!=null){if(typeof e=="string"){const t=e.trim();if(!t)return;const n=t.split(/\r?\n/)[0]?.trim()??"";return n?n.length>160?`${n.slice(0,157)}…`:n:void 0}if(typeof e=="number"||typeof e=="boolean")return String(e);if(Array.isArray(e)){const t=e.map(s=>lr(s)).filter(s=>!!s);if(t.length===0)return;const n=t.slice(0,3).join(", ");return t.length>3?`${n}…`:n}}}function Ju(e,t){if(!e||typeof e!="object")return;let n=e;for(const s of t.split(".")){if(!s||!n||typeof n!="object")return;n=n[s]}return n}function Xu(e,t){for(const n of t){const s=Ju(e,n),i=lr(s);if(i)return i}}function ep(e){if(!e||typeof e!="object")return;const t=e,n=typeof t.path=="string"?t.path:void 0;if(!n)return;const s=typeof t.offset=="number"?t.offset:void 0,i=typeof t.limit=="number"?t.limit:void 0;return s!==void 0&&i!==void 0?`${n}:${s}-${s+i}`:n}function tp(e){if(!e||typeof e!="object")return;const t=e;return typeof t.path=="string"?t.path:void 0}function np(e,t){if(!(!e||!t))return e.actions?.[t]??void 0}function sp(e){const t=Yu(e.name),n=t.toLowerCase(),s=Gu[n],i=s?.icon??Sa.icon??"puzzle",a=s?.title??Qu(t),o=s?.label??t,c=e.args&&typeof e.args=="object"?e.args.action:void 0,l=typeof c=="string"?c.trim():void 0,p=np(s,l),d=Zu(p?.label??l);let u;n==="read"&&(u=ep(e.args)),!u&&(n==="write"||n==="edit"||n==="attach")&&(u=tp(e.args));const h=p?.detailKeys??s?.detailKeys??Sa.detailKeys??[];return!u&&h.length>0&&(u=Xu(e.args,h)),!u&&e.meta&&(u=e.meta),u&&(u=ap(u)),{name:t,icon:i,title:a,label:o,verb:d,detail:u}}function ip(e){const t=[];if(e.verb&&t.push(e.verb),e.detail&&t.push(e.detail),t.length!==0)return t.join(" · ")}function ap(e){return e&&e.replace(/\/Users\/[^/]+/g,"~").replace(/\/home\/[^/]+/g,"~")}const op=80,rp=2,_a=100;function lp(e){const t=e.trim();if(t.startsWith("{")||t.startsWith("["))try{const n=JSON.parse(t);return"```json\n"+JSON.stringify(n,null,2)+"\n```"}catch{}return e}function cp(e){const t=e.split(` -`),n=t.slice(0,rp),s=n.join(` -`);return s.length>_a?s.slice(0,_a)+"…":n.lengthi.kind==="result")){const i=typeof t.toolName=="string"&&t.toolName||typeof t.tool_name=="string"&&t.tool_name||"tool",a=oo(e)??void 0;s.push({kind:"result",name:i,text:a})}return s}function Ta(e,t){const n=sp({name:e.name,args:e.args}),s=ip(n),i=!!e.text?.trim(),a=!!t,o=a?()=>{if(i){t(lp(e.text));return}const u=`## ${n.label} - -${s?`**Command:** \`${s}\` - -`:""}*No output — tool completed successfully.*`;t(u)}:void 0,c=i&&(e.text?.length??0)<=op,l=i&&!c,p=i&&c,d=!i;return r` -
{u.key!=="Enter"&&u.key!==" "||(u.preventDefault(),o?.())}:g} - > -
-
- ${Q[n.icon]} - ${n.label} -
- ${a?r`${i?"View":""} ${Q.check}`:g} - ${d&&!a?r`${Q.check}`:g} -
- ${s?r`
${s}
`:g} - ${d?r`
Completed
`:g} - ${l?r`
${cp(e.text)}
`:g} - ${p?r`
${e.text}
`:g} -
- `}function up(e){return Array.isArray(e)?e.filter(Boolean):[]}function pp(e){if(typeof e!="string")return e;const t=e.trim();if(!t||!t.startsWith("{")&&!t.startsWith("["))return e;try{return JSON.parse(t)}catch{return e}}function fp(e){if(typeof e.text=="string")return e.text;if(typeof e.content=="string")return e.content}function hp(e){return r` -
- ${li("assistant",e)} -
- -
-
- `}function gp(e,t,n,s){const i=new Date(t).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"}),a=s?.name??"Assistant";return r` -
- ${li("assistant",s)} -
- ${cr({role:"assistant",content:[{type:"text",text:e}],timestamp:t},{isStreaming:!0,showReasoning:!1},n)} - -
-
- `}function vp(e,t){const n=Js(e.role),s=t.assistantName??"Assistant",i=n==="user"?"You":n==="assistant"?s:n,a=n==="user"?"user":n==="assistant"?"assistant":"other",o=new Date(e.timestamp).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"});return r` -
- ${li(e.role,{name:s,avatar:t.assistantAvatar??null})} -
- ${e.messages.map((c,l)=>cr(c.message,{isStreaming:e.isStreaming&&l===e.messages.length-1,showReasoning:t.showReasoning},t.onOpenSidebar))} - -
-
- `}function li(e,t){const n=Js(e),s=t?.name?.trim()||"Assistant",i=t?.avatar?.trim()||"",a=n==="user"?"U":n==="assistant"?s.charAt(0).toUpperCase()||"A":n==="tool"?"⚙":"?",o=n==="user"?"user":n==="assistant"?"assistant":n==="tool"?"tool":"other";return i&&n==="assistant"?mp(i)?r`${s}`:r`
${i}
`:r`
${a}
`}function mp(e){return/^https?:\/\//i.test(e)||/^data:image\//i.test(e)||/^\//.test(e)}function cr(e,t,n){const s=e,i=typeof s.role=="string"?s.role:"unknown",a=jo(e)||i.toLowerCase()==="toolresult"||i.toLowerCase()==="tool_result"||typeof s.toolCallId=="string"||typeof s.tool_call_id=="string",o=dp(e),c=o.length>0,l=oo(e),p=t.showReasoning&&i==="assistant"?Al(e):null,d=l?.trim()?l:null,u=p?_l(p):null,h=d,v=i==="assistant"&&!!h?.trim(),w=["chat-bubble",v?"has-copy":"",t.isStreaming?"streaming":"","fade-in"].filter(Boolean).join(" ");return!h&&c&&a?r`${o.map($=>Ta($,n))}`:!h&&!c?g:r` -
- ${v?ju(h):g} - ${u?r`
${gs(ks(u))}
`:g} - ${h?r`
${gs(ks(h))}
`:g} - ${o.map($=>Ta($,n))} -
- `}function bp(e){return r` - - `}var yp=Object.defineProperty,wp=Object.getOwnPropertyDescriptor,mn=(e,t,n,s)=>{for(var i=s>1?void 0:s?wp(t,n):t,a=e.length-1,o;a>=0;a--)(o=e[a])&&(i=(s?o(t,n,i):o(i))||i);return s&&i&&yp(t,n,i),i};let nt=class extends Ze{constructor(){super(...arguments),this.splitRatio=.6,this.minRatio=.4,this.maxRatio=.7,this.isDragging=!1,this.startX=0,this.startRatio=0,this.handleMouseDown=e=>{this.isDragging=!0,this.startX=e.clientX,this.startRatio=this.splitRatio,this.classList.add("dragging"),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("mouseup",this.handleMouseUp),e.preventDefault()},this.handleMouseMove=e=>{if(!this.isDragging)return;const t=this.parentElement;if(!t)return;const n=t.getBoundingClientRect().width,i=(e.clientX-this.startX)/n;let a=this.startRatio+i;a=Math.max(this.minRatio,Math.min(this.maxRatio,a)),this.dispatchEvent(new CustomEvent("resize",{detail:{splitRatio:a},bubbles:!0,composed:!0}))},this.handleMouseUp=()=>{this.isDragging=!1,this.classList.remove("dragging"),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp)}}render(){return r``}connectedCallback(){super.connectedCallback(),this.addEventListener("mousedown",this.handleMouseDown)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("mousedown",this.handleMouseDown),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp)}};nt.styles=Dr` - :host { - width: 4px; - cursor: col-resize; - background: var(--border, #333); - transition: background 150ms ease-out; - flex-shrink: 0; - position: relative; - } - - :host::before { - content: ""; - position: absolute; - top: 0; - left: -4px; - right: -4px; - bottom: 0; - } - - :host(:hover) { - background: var(--accent, #007bff); - } - - :host(.dragging) { - background: var(--accent, #007bff); - } - `;mn([on({type:Number})],nt.prototype,"splitRatio",2);mn([on({type:Number})],nt.prototype,"minRatio",2);mn([on({type:Number})],nt.prototype,"maxRatio",2);nt=mn([Ja("resizable-divider")],nt);const $p=5e3;function xp(e){return e?e.active?r` -
- ${Q.loader} Compacting context... -
- `:e.completedAt&&Date.now()-e.completedAt<$p?r` -
- ${Q.check} Context compacted -
- `:g:g}function kp(e){const t=e.connected,n=e.sending||e.stream!==null,s=!!(e.canAbort&&e.onAbort),a=e.sessions?.sessions?.find(h=>h.key===e.sessionKey)?.reasoningLevel??"off",o=e.showThinking&&a!=="off",c={name:e.assistantName,avatar:e.assistantAvatar??e.assistantAvatarUrl??null},l=e.connected?"Message (↩ to send, Shift+↩ for line breaks)":"Connect to the gateway to start chatting…",p=e.splitRatio??.6,d=!!(e.sidebarOpen&&e.onCloseSidebar),u=r` -
- ${e.loading?r`
Loading chat…
`:g} - ${Ho(Sp(e),h=>h.key,h=>h.kind==="reading-indicator"?hp(c):h.kind==="stream"?gp(h.text,h.startedAt,e.onOpenSidebar,c):h.kind==="group"?vp(h,{onOpenSidebar:e.onOpenSidebar,showReasoning:o,assistantName:e.assistantName,assistantAvatar:c.avatar}):g)} -
- `;return r` -
- ${e.disabledReason?r`
${e.disabledReason}
`:g} - - ${e.error?r`
${e.error}
`:g} - - ${xp(e.compactionStatus)} - - ${e.focusMode?r` - - `:g} - -
-
- ${u} -
- - ${d?r` - e.onSplitRatioChange?.(h.detail.splitRatio)} - > -
- ${bp({content:e.sidebarContent??null,error:e.sidebarError??null,onClose:e.onCloseSidebar,onViewRawText:()=>{!e.sidebarContent||!e.onOpenSidebar||e.onOpenSidebar(`\`\`\` -${e.sidebarContent} -\`\`\``)}})} -
- `:g} -
- - ${e.queue.length?r` -
-
Queued (${e.queue.length})
-
- ${e.queue.map(h=>r` -
-
${h.text}
- -
- `)} -
-
- `:g} - -
- -
- - -
-
-
- `}const Ca=200;function Ap(e){const t=[];let n=null;for(const s of e){if(s.kind!=="message"){n&&(t.push(n),n=null),t.push(s);continue}const i=zo(s.message),a=Js(i.role),o=i.timestamp||Date.now();!n||n.role!==a?(n&&t.push(n),n={kind:"group",key:`group:${a}:${s.key}`,role:a,messages:[{message:s.message,key:s.key}],timestamp:o,isStreaming:!1}):n.messages.push({message:s.message,key:s.key})}return n&&t.push(n),t}function Sp(e){const t=[],n=Array.isArray(e.messages)?e.messages:[],s=Array.isArray(e.toolMessages)?e.toolMessages:[],i=Math.max(0,n.length-Ca);i>0&&t.push({kind:"message",key:"chat:history:notice",message:{role:"system",content:`Showing last ${Ca} messages (${i} hidden).`,timestamp:Date.now()}});for(let a=i;a0?t.push({kind:"stream",key:a,text:e.stream,startedAt:e.streamStartedAt??Date.now()}):t.push({kind:"reading-indicator",key:a})}return Ap(t)}function Ea(e,t){const n=e,s=typeof n.toolCallId=="string"?n.toolCallId:"";if(s)return`tool:${s}`;const i=typeof n.id=="string"?n.id:"";if(i)return`msg:${i}`;const a=typeof n.messageId=="string"?n.messageId:"";if(a)return`msg:${a}`;const o=typeof n.timestamp=="number"?n.timestamp:null,c=typeof n.role=="string"?n.role:"unknown";return o!=null?`msg:${c}:${o}:${t}`:`msg:${c}:${t}`}function ue(e){if(e)return Array.isArray(e.type)?e.type.filter(n=>n!=="null")[0]??e.type[0]:e.type}function dr(e){if(!e)return"";if(e.default!==void 0)return e.default;switch(ue(e)){case"object":return{};case"array":return[];case"boolean":return!1;case"number":case"integer":return 0;case"string":return"";default:return""}}function bn(e){return e.filter(t=>typeof t=="string").join(".")}function te(e,t){const n=bn(e),s=t[n];if(s)return s;const i=n.split(".");for(const[a,o]of Object.entries(t)){if(!a.includes("*"))continue;const c=a.split(".");if(c.length!==i.length)continue;let l=!0;for(let p=0;pt.toUpperCase())}function _p(e){const t=bn(e).toLowerCase();return t.includes("token")||t.includes("password")||t.includes("secret")||t.includes("apikey")||t.endsWith("key")}const Tp=new Set(["title","description","default","nullable"]);function Cp(e){return Object.keys(e??{}).filter(n=>!Tp.has(n)).length===0}function Ep(e){if(e===void 0)return"";try{return JSON.stringify(e,null,2)??""}catch{return""}}const _t={chevronDown:r``,plus:r``,minus:r``,trash:r``,edit:r``};function ye(e){const{schema:t,value:n,path:s,hints:i,unsupported:a,disabled:o,onPatch:c}=e,l=e.showLabel??!0,p=ue(t),d=te(s,i),u=d?.label??t.title??we(String(s.at(-1))),h=d?.help??t.description,v=bn(s);if(a.has(v))return r`
-
${u}
-
Unsupported schema node. Use Raw mode.
-
`;if(t.anyOf||t.oneOf){const $=(t.anyOf??t.oneOf??[]).filter(C=>!(C.type==="null"||Array.isArray(C.type)&&C.type.includes("null")));if($.length===1)return ye({...e,schema:$[0]});const k=C=>{if(C.const!==void 0)return C.const;if(C.enum&&C.enum.length===1)return C.enum[0]},T=$.map(k),M=T.every(C=>C!==void 0);if(M&&T.length>0&&T.length<=5){const C=n??t.default;return r` -
- ${l?r``:g} - ${h?r`
${h}
`:g} -
- ${T.map((E,pe)=>r` - - `)} -
-
- `}if(M&&T.length>5)return Ma({...e,options:T,value:n??t.default});const P=new Set($.map(C=>ue(C)).filter(Boolean)),L=new Set([...P].map(C=>C==="integer"?"number":C));if([...L].every(C=>["string","number","boolean"].includes(C))){const C=L.has("string"),E=L.has("number");if(L.has("boolean")&&L.size===1)return ye({...e,schema:{...t,type:"boolean",anyOf:void 0,oneOf:void 0}});if(C||E)return La({...e,inputType:E&&!C?"number":"text"})}}if(t.enum){const w=t.enum;if(w.length<=5){const $=n??t.default;return r` -
- ${l?r``:g} - ${h?r`
${h}
`:g} -
- ${w.map(k=>r` - - `)} -
-
- `}return Ma({...e,options:w,value:n??t.default})}if(p==="object")return Mp(e);if(p==="array")return Ip(e);if(p==="boolean"){const w=typeof n=="boolean"?n:typeof t.default=="boolean"?t.default:!1;return r` - - `}return p==="number"||p==="integer"?Lp(e):p==="string"?La({...e,inputType:"text"}):r` -
-
${u}
-
Unsupported type: ${p}. Use Raw mode.
-
- `}function La(e){const{schema:t,value:n,path:s,hints:i,disabled:a,onPatch:o,inputType:c}=e,l=e.showLabel??!0,p=te(s,i),d=p?.label??t.title??we(String(s.at(-1))),u=p?.help??t.description,h=p?.sensitive??_p(s),v=p?.placeholder??(h?"••••":t.default!==void 0?`Default: ${t.default}`:""),w=n??"";return r` -
- ${l?r``:g} - ${u?r`
${u}
`:g} -
- {const k=$.target.value;if(c==="number"){if(k.trim()===""){o(s,void 0);return}const T=Number(k);o(s,Number.isNaN(T)?k:T);return}o(s,k)}} - /> - ${t.default!==void 0?r` - - `:g} -
-
- `}function Lp(e){const{schema:t,value:n,path:s,hints:i,disabled:a,onPatch:o}=e,c=e.showLabel??!0,l=te(s,i),p=l?.label??t.title??we(String(s.at(-1))),d=l?.help??t.description,u=n??t.default??"",h=typeof u=="number"?u:0;return r` -
- ${c?r``:g} - ${d?r`
${d}
`:g} -
- - {const w=v.target.value,$=w===""?void 0:Number(w);o(s,$)}} - /> - -
-
- `}function Ma(e){const{schema:t,value:n,path:s,hints:i,disabled:a,options:o,onPatch:c}=e,l=e.showLabel??!0,p=te(s,i),d=p?.label??t.title??we(String(s.at(-1))),u=p?.help??t.description,h=n??t.default,v=o.findIndex($=>$===h||String($)===String(h)),w="__unset__";return r` -
- ${l?r``:g} - ${u?r`
${u}
`:g} - -
- `}function Mp(e){const{schema:t,value:n,path:s,hints:i,unsupported:a,disabled:o,onPatch:c}=e;e.showLabel;const l=te(s,i),p=l?.label??t.title??we(String(s.at(-1))),d=l?.help??t.description,u=n??t.default,h=u&&typeof u=="object"&&!Array.isArray(u)?u:{},v=t.properties??{},$=Object.entries(v).sort((P,L)=>{const C=te([...s,P[0]],i)?.order??0,E=te([...s,L[0]],i)?.order??0;return C!==E?C-E:P[0].localeCompare(L[0])}),k=new Set(Object.keys(v)),T=t.additionalProperties,M=!!T&&typeof T=="object";return s.length===1?r` -
- ${$.map(([P,L])=>ye({schema:L,value:h[P],path:[...s,P],hints:i,unsupported:a,disabled:o,onPatch:c}))} - ${M?Ia({schema:T,value:h,path:s,hints:i,unsupported:a,disabled:o,reservedKeys:k,onPatch:c}):g} -
- `:r` -
- - ${p} - ${_t.chevronDown} - - ${d?r`
${d}
`:g} -
- ${$.map(([P,L])=>ye({schema:L,value:h[P],path:[...s,P],hints:i,unsupported:a,disabled:o,onPatch:c}))} - ${M?Ia({schema:T,value:h,path:s,hints:i,unsupported:a,disabled:o,reservedKeys:k,onPatch:c}):g} -
-
- `}function Ip(e){const{schema:t,value:n,path:s,hints:i,unsupported:a,disabled:o,onPatch:c}=e,l=e.showLabel??!0,p=te(s,i),d=p?.label??t.title??we(String(s.at(-1))),u=p?.help??t.description,h=Array.isArray(t.items)?t.items[0]:t.items;if(!h)return r` -
-
${d}
-
Unsupported array schema. Use Raw mode.
-
- `;const v=Array.isArray(n)?n:Array.isArray(t.default)?t.default:[];return r` -
-
- ${l?r`${d}`:g} - ${v.length} item${v.length!==1?"s":""} - -
- ${u?r`
${u}
`:g} - - ${v.length===0?r` -
- No items yet. Click "Add" to create one. -
- `:r` -
- ${v.map((w,$)=>r` -
-
- #${$+1} - -
-
- ${ye({schema:h,value:w,path:[...s,$],hints:i,unsupported:a,disabled:o,showLabel:!1,onPatch:c})} -
-
- `)} -
- `} -
- `}function Ia(e){const{schema:t,value:n,path:s,hints:i,unsupported:a,disabled:o,reservedKeys:c,onPatch:l}=e,p=Cp(t),d=Object.entries(n??{}).filter(([u])=>!c.has(u));return r` -
-
- Custom entries - -
- - ${d.length===0?r` -
No custom entries.
- `:r` -
- ${d.map(([u,h])=>{const v=[...s,u],w=Ep(h);return r` -
-
- {const k=$.target.value.trim();if(!k||k===u)return;const T={...n??{}};k in T||(T[k]=T[u],delete T[u],l(s,T))}} - /> -
-
- ${p?r` - - `:ye({schema:t,value:h,path:v,hints:i,unsupported:a,disabled:o,showLabel:!1,onPatch:l})} -
- -
- `})} -
- `} -
- `}const Ra={env:r``,update:r``,agents:r``,auth:r``,channels:r``,messages:r``,commands:r``,hooks:r``,skills:r``,tools:r``,gateway:r``,wizard:r``,meta:r``,logging:r``,browser:r``,ui:r``,models:r``,bindings:r``,broadcast:r``,audio:r``,session:r``,cron:r``,web:r``,discovery:r``,canvasHost:r``,talk:r``,plugins:r``,default:r``},ci={env:{label:"Environment Variables",description:"Environment variables passed to the gateway process"},update:{label:"Updates",description:"Auto-update settings and release channel"},agents:{label:"Agents",description:"Agent configurations, models, and identities"},auth:{label:"Authentication",description:"API keys and authentication profiles"},channels:{label:"Channels",description:"Messaging channels (Telegram, Discord, Slack, etc.)"},messages:{label:"Messages",description:"Message handling and routing settings"},commands:{label:"Commands",description:"Custom slash commands"},hooks:{label:"Hooks",description:"Webhooks and event hooks"},skills:{label:"Skills",description:"Skill packs and capabilities"},tools:{label:"Tools",description:"Tool configurations (browser, search, etc.)"},gateway:{label:"Gateway",description:"Gateway server settings (port, auth, binding)"},wizard:{label:"Setup Wizard",description:"Setup wizard state and history"},meta:{label:"Metadata",description:"Gateway metadata and version information"},logging:{label:"Logging",description:"Log levels and output configuration"},browser:{label:"Browser",description:"Browser automation settings"},ui:{label:"UI",description:"User interface preferences"},models:{label:"Models",description:"AI model configurations and providers"},bindings:{label:"Bindings",description:"Key bindings and shortcuts"},broadcast:{label:"Broadcast",description:"Broadcast and notification settings"},audio:{label:"Audio",description:"Audio input/output settings"},session:{label:"Session",description:"Session management and persistence"},cron:{label:"Cron",description:"Scheduled tasks and automation"},web:{label:"Web",description:"Web server and API settings"},discovery:{label:"Discovery",description:"Service discovery and networking"},canvasHost:{label:"Canvas Host",description:"Canvas rendering and display"},talk:{label:"Talk",description:"Voice and speech settings"},plugins:{label:"Plugins",description:"Plugin management and extensions"}};function Pa(e){return Ra[e]??Ra.default}function Rp(e,t,n){if(!n)return!0;const s=n.toLowerCase(),i=ci[e];return e.toLowerCase().includes(s)||i&&(i.label.toLowerCase().includes(s)||i.description.toLowerCase().includes(s))?!0:mt(t,s)}function mt(e,t){if(e.title?.toLowerCase().includes(t)||e.description?.toLowerCase().includes(t)||e.enum?.some(s=>String(s).toLowerCase().includes(t)))return!0;if(e.properties){for(const[s,i]of Object.entries(e.properties))if(s.toLowerCase().includes(t)||mt(i,t))return!0}if(e.items){const s=Array.isArray(e.items)?e.items:[e.items];for(const i of s)if(i&&mt(i,t))return!0}if(e.additionalProperties&&typeof e.additionalProperties=="object"&&mt(e.additionalProperties,t))return!0;const n=e.anyOf??e.oneOf??e.allOf;if(n){for(const s of n)if(s&&mt(s,t))return!0}return!1}function Pp(e){if(!e.schema)return r`
Schema unavailable.
`;const t=e.schema,n=e.value??{};if(ue(t)!=="object"||!t.properties)return r`
Unsupported schema. Use Raw.
`;const s=new Set(e.unsupportedPaths??[]),i=t.properties,a=e.searchQuery??"",o=e.activeSection,c=e.activeSubsection??null,p=Object.entries(i).sort((u,h)=>{const v=te([u[0]],e.uiHints)?.order??50,w=te([h[0]],e.uiHints)?.order??50;return v!==w?v-w:u[0].localeCompare(h[0])}).filter(([u,h])=>!(o&&u!==o||a&&!Rp(u,h,a)));let d=null;if(o&&c&&p.length===1){const u=p[0]?.[1];u&&ue(u)==="object"&&u.properties&&u.properties[c]&&(d={sectionKey:o,subsectionKey:c,schema:u.properties[c]})}return p.length===0?r` -
-
${Q.search}
-
- ${a?`No settings match "${a}"`:"No settings in this section"} -
-
- `:r` -
- ${d?(()=>{const{sectionKey:u,subsectionKey:h,schema:v}=d,w=te([u,h],e.uiHints),$=w?.label??v.title??we(h),k=w?.help??v.description??"",T=n[u],M=T&&typeof T=="object"?T[h]:void 0,P=`config-section-${u}-${h}`;return r` -
-
- ${Pa(u)} -
-

${$}

- ${k?r`

${k}

`:g} -
-
-
- ${ye({schema:v,value:M,path:[u,h],hints:e.uiHints,unsupported:s,disabled:e.disabled??!1,showLabel:!1,onPatch:e.onPatch})} -
-
- `})():p.map(([u,h])=>{const v=ci[u]??{label:u.charAt(0).toUpperCase()+u.slice(1),description:h.description??""};return r` -
-
- ${Pa(u)} -
-

${v.label}

- ${v.description?r`

${v.description}

`:g} -
-
-
- ${ye({schema:h,value:n[u],path:[u],hints:e.uiHints,unsupported:s,disabled:e.disabled??!1,showLabel:!1,onPatch:e.onPatch})} -
-
- `})} -
- `}const Np=new Set(["title","description","default","nullable"]);function Op(e){return Object.keys(e??{}).filter(n=>!Np.has(n)).length===0}function ur(e){const t=e.filter(i=>i!=null),n=t.length!==e.length,s=[];for(const i of t)s.some(a=>Object.is(a,i))||s.push(i);return{enumValues:s,nullable:n}}function pr(e){return!e||typeof e!="object"?{schema:null,unsupportedPaths:[""]}:wt(e,[])}function wt(e,t){const n=new Set,s={...e},i=bn(t)||"";if(e.anyOf||e.oneOf||e.allOf){const c=Dp(e,t);return c||{schema:e,unsupportedPaths:[i]}}const a=Array.isArray(e.type)&&e.type.includes("null"),o=ue(e)??(e.properties||e.additionalProperties?"object":void 0);if(s.type=o??e.type,s.nullable=a||e.nullable,s.enum){const{enumValues:c,nullable:l}=ur(s.enum);s.enum=c,l&&(s.nullable=!0),c.length===0&&n.add(i)}if(o==="object"){const c=e.properties??{},l={};for(const[p,d]of Object.entries(c)){const u=wt(d,[...t,p]);u.schema&&(l[p]=u.schema);for(const h of u.unsupportedPaths)n.add(h)}if(s.properties=l,e.additionalProperties===!0)n.add(i);else if(e.additionalProperties===!1)s.additionalProperties=!1;else if(e.additionalProperties&&typeof e.additionalProperties=="object"&&!Op(e.additionalProperties)){const p=wt(e.additionalProperties,[...t,"*"]);s.additionalProperties=p.schema??e.additionalProperties,p.unsupportedPaths.length>0&&n.add(i)}}else if(o==="array"){const c=Array.isArray(e.items)?e.items[0]:e.items;if(!c)n.add(i);else{const l=wt(c,[...t,"*"]);s.items=l.schema??c,l.unsupportedPaths.length>0&&n.add(i)}}else o!=="string"&&o!=="number"&&o!=="integer"&&o!=="boolean"&&!s.enum&&n.add(i);return{schema:s,unsupportedPaths:Array.from(n)}}function Dp(e,t){if(e.allOf)return null;const n=e.anyOf??e.oneOf;if(!n)return null;const s=[],i=[];let a=!1;for(const c of n){if(!c||typeof c!="object")return null;if(Array.isArray(c.enum)){const{enumValues:l,nullable:p}=ur(c.enum);s.push(...l),p&&(a=!0);continue}if("const"in c){if(c.const==null){a=!0;continue}s.push(c.const);continue}if(ue(c)==="null"){a=!0;continue}i.push(c)}if(s.length>0&&i.length===0){const c=[];for(const l of s)c.some(p=>Object.is(p,l))||c.push(l);return{schema:{...e,enum:c,nullable:a,anyOf:void 0,oneOf:void 0,allOf:void 0},unsupportedPaths:[]}}if(i.length===1){const c=wt(i[0],t);return c.schema&&(c.schema.nullable=a||c.schema.nullable),c}const o=["string","number","integer","boolean"];return i.length>0&&s.length===0&&i.every(c=>c.type&&o.includes(String(c.type)))?{schema:{...e,nullable:a},unsupportedPaths:[]}:null}const As={all:r``,env:r``,update:r``,agents:r``,auth:r``,channels:r``,messages:r``,commands:r``,hooks:r``,skills:r``,tools:r``,gateway:r``,wizard:r``,meta:r``,logging:r``,browser:r``,ui:r``,models:r``,bindings:r``,broadcast:r``,audio:r``,session:r``,cron:r``,web:r``,discovery:r``,canvasHost:r``,talk:r``,plugins:r``,default:r``},Na=[{key:"env",label:"Environment"},{key:"update",label:"Updates"},{key:"agents",label:"Agents"},{key:"auth",label:"Authentication"},{key:"channels",label:"Channels"},{key:"messages",label:"Messages"},{key:"commands",label:"Commands"},{key:"hooks",label:"Hooks"},{key:"skills",label:"Skills"},{key:"tools",label:"Tools"},{key:"gateway",label:"Gateway"},{key:"wizard",label:"Setup Wizard"}],Oa="__all__";function Da(e){return As[e]??As.default}function Bp(e,t){const n=ci[e];return n||{label:t?.title??we(e),description:t?.description??""}}function Fp(e){const{key:t,schema:n,uiHints:s}=e;if(!n||ue(n)!=="object"||!n.properties)return[];const i=Object.entries(n.properties).map(([a,o])=>{const c=te([t,a],s),l=c?.label??o.title??we(a),p=c?.help??o.description??"",d=c?.order??50;return{key:a,label:l,description:p,order:d}});return i.sort((a,o)=>a.order!==o.order?a.order-o.order:a.key.localeCompare(o.key)),i}function Up(e,t){if(!e||!t)return[];const n=[];function s(i,a,o){if(i===a)return;if(typeof i!=typeof a){n.push({path:o,from:i,to:a});return}if(typeof i!="object"||i===null||a===null){i!==a&&n.push({path:o,from:i,to:a});return}if(Array.isArray(i)&&Array.isArray(a)){JSON.stringify(i)!==JSON.stringify(a)&&n.push({path:o,from:i,to:a});return}const c=i,l=a,p=new Set([...Object.keys(c),...Object.keys(l)]);for(const d of p)s(c[d],l[d],o?`${o}.${d}`:d)}return s(e,t,""),n}function Ba(e,t=40){let n;try{n=JSON.stringify(e)??String(e)}catch{n=String(e)}return n.length<=t?n:n.slice(0,t-3)+"..."}function Kp(e){const t=e.valid==null?"unknown":e.valid?"valid":"invalid",n=pr(e.schema),s=n.schema?n.unsupportedPaths.length>0:!1,i=n.schema?.properties??{},a=Na.filter(E=>E.key in i),o=new Set(Na.map(E=>E.key)),c=Object.keys(i).filter(E=>!o.has(E)).map(E=>({key:E,label:E.charAt(0).toUpperCase()+E.slice(1)})),l=[...a,...c],p=e.activeSection&&n.schema&&ue(n.schema)==="object"?n.schema.properties?.[e.activeSection]:void 0,d=e.activeSection?Bp(e.activeSection,p):null,u=e.activeSection?Fp({key:e.activeSection,schema:p,uiHints:e.uiHints}):[],h=e.formMode==="form"&&!!e.activeSection&&u.length>0,v=e.activeSubsection===Oa,w=e.searchQuery||v?null:e.activeSubsection??u[0]?.key??null,$=e.formMode==="form"?Up(e.originalValue,e.formValue):[],k=e.formMode==="raw"&&e.raw!==e.originalRaw,T=e.formMode==="form"?$.length>0:k,M=!!e.formValue&&!e.loading&&!!n.schema,P=e.connected&&!e.saving&&T&&(e.formMode==="raw"?!0:M),L=e.connected&&!e.applying&&!e.updating&&T&&(e.formMode==="raw"?!0:M),C=e.connected&&!e.applying&&!e.updating;return r` -
- - - - -
- -
-
- ${T?r` - ${e.formMode==="raw"?"Unsaved changes":`${$.length} unsaved change${$.length!==1?"s":""}`} - `:r` - No changes - `} -
-
- - - - -
-
- - - ${T&&e.formMode==="form"?r` -
- - View ${$.length} pending change${$.length!==1?"s":""} - - - - -
- ${$.map(E=>r` -
-
${E.path}
-
- ${Ba(E.from)} - - ${Ba(E.to)} -
-
- `)} -
-
- `:g} - - ${d&&e.formMode==="form"?r` -
-
${Da(e.activeSection??"")}
-
-
${d.label}
- ${d.description?r`
${d.description}
`:g} -
-
- `:g} - - ${h?r` -
- - ${u.map(E=>r` - - `)} -
- `:g} - - -
- ${e.formMode==="form"?r` - ${e.schemaLoading?r`
-
- Loading schema… -
`:Pp({schema:n.schema,uiHints:e.uiHints,value:e.formValue,disabled:e.loading||!e.formValue,unsupportedPaths:n.unsupportedPaths,onPatch:e.onFormPatch,searchQuery:e.searchQuery,activeSection:e.activeSection,activeSubsection:w})} - ${s?r`
- Form view can't safely edit some fields. - Use Raw to avoid losing config entries. -
`:g} - `:r` - - `} -
- - ${e.issues.length>0?r`
-
${JSON.stringify(e.issues,null,2)}
-
`:g} -
-
- `}function Hp(e){if(!e&&e!==0)return"n/a";const t=Math.round(e/1e3);if(t<60)return`${t}s`;const n=Math.round(t/60);return n<60?`${n}m`:`${Math.round(n/60)}h`}function zp(e,t){const n=t.snapshot,s=n?.channels;if(!n||!s)return!1;const i=s[e],a=typeof i?.configured=="boolean"&&i.configured,o=typeof i?.running=="boolean"&&i.running,c=typeof i?.connected=="boolean"&&i.connected,p=(n.channelAccounts?.[e]??[]).some(d=>d.configured||d.running||d.connected);return a||o||c||p}function jp(e,t){return t?.[e]?.length??0}function fr(e,t){const n=jp(e,t);return n<2?g:r``}function qp(e,t){let n=e;for(const s of t){if(!n)return null;const i=ue(n);if(i==="object"){const a=n.properties??{};if(typeof s=="string"&&a[s]){n=a[s];continue}const o=n.additionalProperties;if(typeof s=="string"&&o&&typeof o=="object"){n=o;continue}return null}if(i==="array"){if(typeof s!="number")return null;n=(Array.isArray(n.items)?n.items[0]:n.items)??null;continue}return null}return n}function Vp(e,t){const s=(e.channels??{})[t],i=e[t];return(s&&typeof s=="object"?s:null)??(i&&typeof i=="object"?i:null)??{}}function Wp(e){const t=pr(e.schema),n=t.schema;if(!n)return r`
Schema unavailable. Use Raw.
`;const s=qp(n,["channels",e.channelId]);if(!s)return r`
Channel config schema unavailable.
`;const i=e.configValue??{},a=Vp(i,e.channelId);return r` -
- ${ye({schema:s,value:a,path:["channels",e.channelId],hints:e.uiHints,unsupported:new Set(t.unsupportedPaths),disabled:e.disabled,showLabel:!1,onPatch:e.onPatch})} -
- `}function $e(e){const{channelId:t,props:n}=e,s=n.configSaving||n.configSchemaLoading;return r` -
- ${n.configSchemaLoading?r`
Loading config schema…
`:Wp({channelId:t,configValue:n.configForm,schema:n.configSchema,uiHints:n.configUiHints,disabled:s,onPatch:n.onConfigPatch})} -
- - -
-
- `}function Gp(e){const{props:t,discord:n,accountCountLabel:s}=e;return r` -
-
Discord
-
Bot status and channel configuration.
- ${s} - -
-
- Configured - ${n?.configured?"Yes":"No"} -
-
- Running - ${n?.running?"Yes":"No"} -
-
- Last start - ${n?.lastStartAt?O(n.lastStartAt):"n/a"} -
-
- Last probe - ${n?.lastProbeAt?O(n.lastProbeAt):"n/a"} -
-
- - ${n?.lastError?r`
- ${n.lastError} -
`:g} - - ${n?.probe?r`
- Probe ${n.probe.ok?"ok":"failed"} · - ${n.probe.status??""} ${n.probe.error??""} -
`:g} - - ${$e({channelId:"discord",props:t})} - -
- -
-
- `}function Yp(e){const{props:t,googleChat:n,accountCountLabel:s}=e;return r` -
-
Google Chat
-
Chat API webhook status and channel configuration.
- ${s} - -
-
- Configured - ${n?n.configured?"Yes":"No":"n/a"} -
-
- Running - ${n?n.running?"Yes":"No":"n/a"} -
-
- Credential - ${n?.credentialSource??"n/a"} -
-
- Audience - - ${n?.audienceType?`${n.audienceType}${n.audience?` · ${n.audience}`:""}`:"n/a"} - -
-
- Last start - ${n?.lastStartAt?O(n.lastStartAt):"n/a"} -
-
- Last probe - ${n?.lastProbeAt?O(n.lastProbeAt):"n/a"} -
-
- - ${n?.lastError?r`
- ${n.lastError} -
`:g} - - ${n?.probe?r`
- Probe ${n.probe.ok?"ok":"failed"} · - ${n.probe.status??""} ${n.probe.error??""} -
`:g} - - ${$e({channelId:"googlechat",props:t})} - -
- -
-
- `}function Qp(e){const{props:t,imessage:n,accountCountLabel:s}=e;return r` -
-
iMessage
-
macOS bridge status and channel configuration.
- ${s} - -
-
- Configured - ${n?.configured?"Yes":"No"} -
-
- Running - ${n?.running?"Yes":"No"} -
-
- Last start - ${n?.lastStartAt?O(n.lastStartAt):"n/a"} -
-
- Last probe - ${n?.lastProbeAt?O(n.lastProbeAt):"n/a"} -
-
- - ${n?.lastError?r`
- ${n.lastError} -
`:g} - - ${n?.probe?r`
- Probe ${n.probe.ok?"ok":"failed"} · - ${n.probe.error??""} -
`:g} - - ${$e({channelId:"imessage",props:t})} - -
- -
-
- `}function Zp(e){const{values:t,original:n}=e;return t.name!==n.name||t.displayName!==n.displayName||t.about!==n.about||t.picture!==n.picture||t.banner!==n.banner||t.website!==n.website||t.nip05!==n.nip05||t.lud16!==n.lud16}function Jp(e){const{state:t,callbacks:n,accountId:s}=e,i=Zp(t),a=(c,l,p={})=>{const{type:d="text",placeholder:u,maxLength:h,help:v}=p,w=t.values[c]??"",$=t.fieldErrors[c],k=`nostr-profile-${c}`;return d==="textarea"?r` -
- - - ${v?r`
${v}
`:g} - ${$?r`
${$}
`:g} -
- `:r` -
- - {const M=T.target;n.onFieldChange(c,M.value)}} - ?disabled=${t.saving} - /> - ${v?r`
${v}
`:g} - ${$?r`
${$}
`:g} -
- `},o=()=>{const c=t.values.picture;return c?r` -
- Profile picture preview{const p=l.target;p.style.display="none"}} - @load=${l=>{const p=l.target;p.style.display="block"}} - /> -
- `:g};return r` -
-
-
Edit Profile
-
Account: ${s}
-
- - ${t.error?r`
${t.error}
`:g} - - ${t.success?r`
${t.success}
`:g} - - ${o()} - - ${a("name","Username",{placeholder:"satoshi",maxLength:256,help:"Short username (e.g., satoshi)"})} - - ${a("displayName","Display Name",{placeholder:"Satoshi Nakamoto",maxLength:256,help:"Your full display name"})} - - ${a("about","Bio",{type:"textarea",placeholder:"Tell people about yourself...",maxLength:2e3,help:"A brief bio or description"})} - - ${a("picture","Avatar URL",{type:"url",placeholder:"https://example.com/avatar.jpg",help:"HTTPS URL to your profile picture"})} - - ${t.showAdvanced?r` -
-
Advanced
- - ${a("banner","Banner URL",{type:"url",placeholder:"https://example.com/banner.jpg",help:"HTTPS URL to a banner image"})} - - ${a("website","Website",{type:"url",placeholder:"https://example.com",help:"Your personal website"})} - - ${a("nip05","NIP-05 Identifier",{placeholder:"you@example.com",help:"Verifiable identifier (e.g., you@domain.com)"})} - - ${a("lud16","Lightning Address",{placeholder:"you@getalby.com",help:"Lightning address for tips (LUD-16)"})} -
- `:g} - -
- - - - - - - -
- - ${i?r`
- You have unsaved changes -
`:g} -
- `}function Xp(e){const t={name:e?.name??"",displayName:e?.displayName??"",about:e?.about??"",picture:e?.picture??"",banner:e?.banner??"",website:e?.website??"",nip05:e?.nip05??"",lud16:e?.lud16??""};return{values:t,original:{...t},saving:!1,importing:!1,error:null,success:null,fieldErrors:{},showAdvanced:!!(e?.banner||e?.website||e?.nip05||e?.lud16)}}function Fa(e){return e?e.length<=20?e:`${e.slice(0,8)}...${e.slice(-8)}`:"n/a"}function ef(e){const{props:t,nostr:n,nostrAccounts:s,accountCountLabel:i,profileFormState:a,profileFormCallbacks:o,onEditProfile:c}=e,l=s[0],p=n?.configured??l?.configured??!1,d=n?.running??l?.running??!1,u=n?.publicKey??l?.publicKey,h=n?.lastStartAt??l?.lastStartAt??null,v=n?.lastError??l?.lastError??null,w=s.length>1,$=a!=null,k=M=>{const P=M.publicKey,L=M.profile,C=L?.displayName??L?.name??M.name??M.accountId;return r` - - `},T=()=>{if($&&o)return Jp({state:a,callbacks:o,accountId:s[0]?.accountId??"default"});const M=l?.profile??n?.profile,{name:P,displayName:L,about:C,picture:E,nip05:pe}=M??{},yn=P||L||C||E||pe;return r` -
-
-
Profile
- ${p?r` - - `:g} -
- ${yn?r` -
- ${E?r` -
- Profile picture{wn.target.style.display="none"}} - /> -
- `:g} - ${P?r`
Name${P}
`:g} - ${L?r`
Display Name${L}
`:g} - ${C?r`
About${C}
`:g} - ${pe?r`
NIP-05${pe}
`:g} -
- `:r` -
- No profile set. Click "Edit Profile" to add your name, bio, and avatar. -
- `} -
- `};return r` -
-
Nostr
-
Decentralized DMs via Nostr relays (NIP-04).
- ${i} - - ${w?r` - - `:r` -
-
- Configured - ${p?"Yes":"No"} -
-
- Running - ${d?"Yes":"No"} -
-
- Public Key - ${Fa(u)} -
-
- Last start - ${h?O(h):"n/a"} -
-
- `} - - ${v?r`
${v}
`:g} - - ${T()} - - ${$e({channelId:"nostr",props:t})} - -
- -
-
- `}function tf(e){const{props:t,signal:n,accountCountLabel:s}=e;return r` -
-
Signal
-
signal-cli status and channel configuration.
- ${s} - -
-
- Configured - ${n?.configured?"Yes":"No"} -
-
- Running - ${n?.running?"Yes":"No"} -
-
- Base URL - ${n?.baseUrl??"n/a"} -
-
- Last start - ${n?.lastStartAt?O(n.lastStartAt):"n/a"} -
-
- Last probe - ${n?.lastProbeAt?O(n.lastProbeAt):"n/a"} -
-
- - ${n?.lastError?r`
- ${n.lastError} -
`:g} - - ${n?.probe?r`
- Probe ${n.probe.ok?"ok":"failed"} · - ${n.probe.status??""} ${n.probe.error??""} -
`:g} - - ${$e({channelId:"signal",props:t})} - -
- -
-
- `}function nf(e){const{props:t,slack:n,accountCountLabel:s}=e;return r` -
-
Slack
-
Socket mode status and channel configuration.
- ${s} - -
-
- Configured - ${n?.configured?"Yes":"No"} -
-
- Running - ${n?.running?"Yes":"No"} -
-
- Last start - ${n?.lastStartAt?O(n.lastStartAt):"n/a"} -
-
- Last probe - ${n?.lastProbeAt?O(n.lastProbeAt):"n/a"} -
-
- - ${n?.lastError?r`
- ${n.lastError} -
`:g} - - ${n?.probe?r`
- Probe ${n.probe.ok?"ok":"failed"} · - ${n.probe.status??""} ${n.probe.error??""} -
`:g} - - ${$e({channelId:"slack",props:t})} - -
- -
-
- `}function sf(e){const{props:t,telegram:n,telegramAccounts:s,accountCountLabel:i}=e,a=s.length>1,o=c=>{const p=c.probe?.bot?.username,d=c.name||c.accountId;return r` - - `};return r` -
-
Telegram
-
Bot status and channel configuration.
- ${i} - - ${a?r` - - `:r` -
-
- Configured - ${n?.configured?"Yes":"No"} -
-
- Running - ${n?.running?"Yes":"No"} -
-
- Mode - ${n?.mode??"n/a"} -
-
- Last start - ${n?.lastStartAt?O(n.lastStartAt):"n/a"} -
-
- Last probe - ${n?.lastProbeAt?O(n.lastProbeAt):"n/a"} -
-
- `} - - ${n?.lastError?r`
- ${n.lastError} -
`:g} - - ${n?.probe?r`
- Probe ${n.probe.ok?"ok":"failed"} · - ${n.probe.status??""} ${n.probe.error??""} -
`:g} - - ${$e({channelId:"telegram",props:t})} - -
- -
-
- `}function af(e){const{props:t,whatsapp:n,accountCountLabel:s}=e;return r` -
-
WhatsApp
-
Link WhatsApp Web and monitor connection health.
- ${s} - -
-
- Configured - ${n?.configured?"Yes":"No"} -
-
- Linked - ${n?.linked?"Yes":"No"} -
-
- Running - ${n?.running?"Yes":"No"} -
-
- Connected - ${n?.connected?"Yes":"No"} -
-
- Last connect - - ${n?.lastConnectedAt?O(n.lastConnectedAt):"n/a"} - -
-
- Last message - - ${n?.lastMessageAt?O(n.lastMessageAt):"n/a"} - -
-
- Auth age - - ${n?.authAgeMs!=null?Hp(n.authAgeMs):"n/a"} - -
-
- - ${n?.lastError?r`
- ${n.lastError} -
`:g} - - ${t.whatsappMessage?r`
- ${t.whatsappMessage} -
`:g} - - ${t.whatsappQrDataUrl?r`
- WhatsApp QR -
`:g} - -
- - - - - -
- - ${$e({channelId:"whatsapp",props:t})} -
- `}function of(e){const t=e.snapshot?.channels,n=t?.whatsapp??void 0,s=t?.telegram??void 0,i=t?.discord??null;t?.googlechat;const a=t?.slack??null,o=t?.signal??null,c=t?.imessage??null,l=t?.nostr??null,d=rf(e.snapshot).map((u,h)=>({key:u,enabled:zp(u,e),order:h})).sort((u,h)=>u.enabled!==h.enabled?u.enabled?-1:1:u.order-h.order);return r` -
- ${d.map(u=>lf(u.key,e,{whatsapp:n,telegram:s,discord:i,slack:a,signal:o,imessage:c,nostr:l,channelAccounts:e.snapshot?.channelAccounts??null}))} -
- -
-
-
-
Channel health
-
Channel status snapshots from the gateway.
-
-
${e.lastSuccessAt?O(e.lastSuccessAt):"n/a"}
-
- ${e.lastError?r`
- ${e.lastError} -
`:g} -
-${e.snapshot?JSON.stringify(e.snapshot,null,2):"No snapshot yet."}
-      
-
- `}function rf(e){return e?.channelMeta?.length?e.channelMeta.map(t=>t.id):e?.channelOrder?.length?e.channelOrder:["whatsapp","telegram","discord","googlechat","slack","signal","imessage","nostr"]}function lf(e,t,n){const s=fr(e,n.channelAccounts);switch(e){case"whatsapp":return af({props:t,whatsapp:n.whatsapp,accountCountLabel:s});case"telegram":return sf({props:t,telegram:n.telegram,telegramAccounts:n.channelAccounts?.telegram??[],accountCountLabel:s});case"discord":return Gp({props:t,discord:n.discord,accountCountLabel:s});case"googlechat":return Yp({props:t,accountCountLabel:s});case"slack":return nf({props:t,slack:n.slack,accountCountLabel:s});case"signal":return tf({props:t,signal:n.signal,accountCountLabel:s});case"imessage":return Qp({props:t,imessage:n.imessage,accountCountLabel:s});case"nostr":{const i=n.channelAccounts?.nostr??[],a=i[0],o=a?.accountId??"default",c=a?.profile??null,l=t.nostrProfileAccountId===o?t.nostrProfileFormState:null,p=l?{onFieldChange:t.onNostrProfileFieldChange,onSave:t.onNostrProfileSave,onImport:t.onNostrProfileImport,onCancel:t.onNostrProfileCancel,onToggleAdvanced:t.onNostrProfileToggleAdvanced}:null;return ef({props:t,nostr:n.nostr,nostrAccounts:i,accountCountLabel:s,profileFormState:l,profileFormCallbacks:p,onEditProfile:()=>t.onNostrProfileEdit(o,c)})}default:return cf(e,t,n.channelAccounts??{})}}function cf(e,t,n){const s=uf(t.snapshot,e),i=t.snapshot?.channels?.[e],a=typeof i?.configured=="boolean"?i.configured:void 0,o=typeof i?.running=="boolean"?i.running:void 0,c=typeof i?.connected=="boolean"?i.connected:void 0,l=typeof i?.lastError=="string"?i.lastError:void 0,p=n[e]??[],d=fr(e,n);return r` -
-
${s}
-
Channel status and configuration.
- ${d} - - ${p.length>0?r` - - `:r` -
-
- Configured - ${a==null?"n/a":a?"Yes":"No"} -
-
- Running - ${o==null?"n/a":o?"Yes":"No"} -
-
- Connected - ${c==null?"n/a":c?"Yes":"No"} -
-
- `} - - ${l?r`
- ${l} -
`:g} - - ${$e({channelId:e,props:t})} -
- `}function df(e){return e?.channelMeta?.length?Object.fromEntries(e.channelMeta.map(t=>[t.id,t])):{}}function uf(e,t){return df(e)[t]?.label??e?.channelLabels?.[t]??t}const pf=600*1e3;function hr(e){return e.lastInboundAt?Date.now()-e.lastInboundAt
- `}function vf(e){const t=e.host??"unknown",n=e.ip?`(${e.ip})`:"",s=e.mode??"",i=e.version??"";return`${t} ${n} ${s} ${i}`.trim()}function mf(e){const t=e.ts??null;return t?O(t):"n/a"}function gr(e){return e?`${At(e)} (${O(e)})`:"n/a"}function bf(e){if(e.totalTokens==null)return"n/a";const t=e.totalTokens??0,n=e.contextTokens??0;return n?`${t} / ${n}`:String(t)}function yf(e){if(e==null)return"";try{return JSON.stringify(e,null,2)}catch{return String(e)}}function wf(e){const t=e.state??{},n=t.nextRunAtMs?At(t.nextRunAtMs):"n/a",s=t.lastRunAtMs?At(t.lastRunAtMs):"n/a";return`${t.lastStatus??"n/a"} · next ${n} · last ${s}`}function $f(e){const t=e.schedule;return t.kind==="at"?`At ${At(t.atMs)}`:t.kind==="every"?`Every ${io(t.everyMs)}`:`Cron ${t.expr}${t.tz?` (${t.tz})`:""}`}function xf(e){const t=e.payload;return t.kind==="systemEvent"?`System: ${t.text}`:`Agent: ${t.message}`}function kf(e){const t=["last",...e.channels.filter(Boolean)],n=e.form.channel?.trim();n&&!t.includes(n)&&t.push(n);const s=new Set;return t.filter(i=>s.has(i)?!1:(s.add(i),!0))}function Af(e,t){if(t==="last")return"last";const n=e.channelMeta?.find(s=>s.id===t);return n?.label?n.label:e.channelLabels?.[t]??t}function Sf(e){const t=kf(e);return r` -
-
-
Scheduler
-
Gateway-owned cron scheduler status.
-
-
-
Enabled
-
- ${e.status?e.status.enabled?"Yes":"No":"n/a"} -
-
-
-
Jobs
-
${e.status?.jobs??"n/a"}
-
-
-
Next wake
-
${gr(e.status?.nextWakeAtMs??null)}
-
-
-
- - ${e.error?r`${e.error}`:g} -
-
- -
-
New Job
-
Create a scheduled wakeup or agent run.
-
- - - - - -
- ${_f(e)} -
- - - -
- - ${e.form.payloadKind==="agentTurn"?r` -
- - - - - ${e.form.sessionTarget==="isolated"?r` - - `:g} -
- `:g} -
- -
-
-
- -
-
Jobs
-
All scheduled jobs stored in the gateway.
- ${e.jobs.length===0?r`
No jobs yet.
`:r` -
- ${e.jobs.map(n=>Tf(n,e))} -
- `} -
- -
-
Run history
-
Latest runs for ${e.runsJobId??"(select a job)"}.
- ${e.runsJobId==null?r` -
- Select a job to inspect run history. -
- `:e.runs.length===0?r`
No runs yet.
`:r` -
- ${e.runs.map(n=>Cf(n))} -
- `} -
- `}function _f(e){const t=e.form;return t.scheduleKind==="at"?r` - - `:t.scheduleKind==="every"?r` -
- - -
- `:r` -
- - -
- `}function Tf(e,t){const s=`list-item list-item-clickable${t.runsJobId===e.id?" list-item-selected":""}`;return r` -
t.onLoadRuns(e.id)}> -
-
${e.name}
-
${$f(e)}
-
${xf(e)}
- ${e.agentId?r`
Agent: ${e.agentId}
`:g} -
- ${e.enabled?"enabled":"disabled"} - ${e.sessionTarget} - ${e.wakeMode} -
-
-
-
${wf(e)}
-
- - - - -
-
-
- `}function Cf(e){return r` -
-
-
${e.status}
-
${e.summary??""}
-
-
-
${At(e.ts)}
-
${e.durationMs??0}ms
- ${e.error?r`
${e.error}
`:g} -
-
- `}function Ef(e){return r` -
-
-
-
-
Snapshots
-
Status, health, and heartbeat data.
-
- -
-
-
-
Status
-
${JSON.stringify(e.status??{},null,2)}
-
-
-
Health
-
${JSON.stringify(e.health??{},null,2)}
-
-
-
Last heartbeat
-
${JSON.stringify(e.heartbeat??{},null,2)}
-
-
-
- -
-
Manual RPC
-
Send a raw gateway method with JSON params.
-
- - -
-
- -
- ${e.callError?r`
- ${e.callError} -
`:g} - ${e.callResult?r`
${e.callResult}
`:g} -
-
- -
-
Models
-
Catalog from models.list.
-
${JSON.stringify(e.models??[],null,2)}
-
- -
-
Event Log
-
Latest gateway events.
- ${e.eventLog.length===0?r`
No events yet.
`:r` -
- ${e.eventLog.map(t=>r` -
-
-
${t.event}
-
${new Date(t.ts).toLocaleTimeString()}
-
-
-
${yf(t.payload)}
-
-
- `)} -
- `} -
- `}function Lf(e){return r` -
-
-
-
Connected Instances
-
Presence beacons from the gateway and clients.
-
- -
- ${e.lastError?r`
- ${e.lastError} -
`:g} - ${e.statusMessage?r`
- ${e.statusMessage} -
`:g} -
- ${e.entries.length===0?r`
No instances reported yet.
`:e.entries.map(t=>Mf(t))} -
-
- `}function Mf(e){const t=e.lastInputSeconds!=null?`${e.lastInputSeconds}s ago`:"n/a",n=e.mode??"unknown",s=Array.isArray(e.roles)?e.roles.filter(Boolean):[],i=Array.isArray(e.scopes)?e.scopes.filter(Boolean):[],a=i.length>0?i.length>3?`${i.length} scopes`:`scopes: ${i.join(", ")}`:null;return r` -
-
-
${e.host??"unknown host"}
-
${vf(e)}
-
- ${n} - ${s.map(o=>r`${o}`)} - ${a?r`${a}`:g} - ${e.platform?r`${e.platform}`:g} - ${e.deviceFamily?r`${e.deviceFamily}`:g} - ${e.modelIdentifier?r`${e.modelIdentifier}`:g} - ${e.version?r`${e.version}`:g} -
-
-
-
${mf(e)}
-
Last input ${t}
-
Reason ${e.reason??""}
-
-
- `}const Ua=["trace","debug","info","warn","error","fatal"];function If(e){if(!e)return"";const t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleTimeString()}function Rf(e,t){return t?[e.message,e.subsystem,e.raw].filter(Boolean).join(" ").toLowerCase().includes(t):!0}function Pf(e){const t=e.filterText.trim().toLowerCase(),n=Ua.some(a=>!e.levelFilters[a]),s=e.entries.filter(a=>a.level&&!e.levelFilters[a.level]?!1:Rf(a,t)),i=t||n?"filtered":"visible";return r` -
-
-
-
Logs
-
Gateway file logs (JSONL).
-
-
- - -
-
- -
- - -
- -
- ${Ua.map(a=>r` - - `)} -
- - ${e.file?r`
File: ${e.file}
`:g} - ${e.truncated?r`
- Log output truncated; showing latest chunk. -
`:g} - ${e.error?r`
${e.error}
`:g} - -
- ${s.length===0?r`
No log entries.
`:s.map(a=>r` -
-
${If(a.time)}
-
${a.level??""}
-
${a.subsystem??""}
-
${a.message??a.raw}
-
- `)} -
-
- `}function Nf(e){const t=Kf(e),n=Wf(e);return r` - ${Yf(n)} - ${Gf(t)} - ${Of(e)} -
-
-
-
Nodes
-
Paired devices and live links.
-
- -
-
- ${e.nodes.length===0?r`
No nodes found.
`:e.nodes.map(s=>ah(s))} -
-
- `}function Of(e){const t=e.devicesList??{pending:[],paired:[]},n=Array.isArray(t.pending)?t.pending:[],s=Array.isArray(t.paired)?t.paired:[];return r` -
-
-
-
Devices
-
Pairing requests + role tokens.
-
- -
- ${e.devicesError?r`
${e.devicesError}
`:g} -
- ${n.length>0?r` -
Pending
- ${n.map(i=>Df(i,e))} - `:g} - ${s.length>0?r` -
Paired
- ${s.map(i=>Bf(i,e))} - `:g} - ${n.length===0&&s.length===0?r`
No paired devices.
`:g} -
-
- `}function Df(e,t){const n=e.displayName?.trim()||e.deviceId,s=typeof e.ts=="number"?O(e.ts):"n/a",i=e.role?.trim()?`role: ${e.role}`:"role: -",a=e.isRepair?" · repair":"",o=e.remoteIp?` · ${e.remoteIp}`:"";return r` -
-
-
${n}
-
${e.deviceId}${o}
-
- ${i} · requested ${s}${a} -
-
-
-
- - -
-
-
- `}function Bf(e,t){const n=e.displayName?.trim()||e.deviceId,s=e.remoteIp?` · ${e.remoteIp}`:"",i=`roles: ${is(e.roles)}`,a=`scopes: ${is(e.scopes)}`,o=Array.isArray(e.tokens)?e.tokens:[];return r` -
-
-
${n}
-
${e.deviceId}${s}
-
${i} · ${a}
- ${o.length===0?r`
Tokens: none
`:r` -
Tokens
-
- ${o.map(c=>Ff(e.deviceId,c,t))} -
- `} -
-
- `}function Ff(e,t,n){const s=t.revokedAtMs?"revoked":"active",i=`scopes: ${is(t.scopes)}`,a=O(t.rotatedAtMs??t.createdAtMs??t.lastUsedAtMs??null);return r` -
-
${t.role} · ${s} · ${i} · ${a}
-
- - ${t.revokedAtMs?g:r` - - `} -
-
- `}const Ae="__defaults__",Ka=[{value:"deny",label:"Deny"},{value:"allowlist",label:"Allowlist"},{value:"full",label:"Full"}],Uf=[{value:"off",label:"Off"},{value:"on-miss",label:"On miss"},{value:"always",label:"Always"}];function Kf(e){const t=e.configForm,n=nh(e.nodes),{defaultBinding:s,agents:i}=ih(t),a=!!t,o=e.configSaving||e.configFormMode==="raw";return{ready:a,disabled:o,configDirty:e.configDirty,configLoading:e.configLoading,configSaving:e.configSaving,defaultBinding:s,agents:i,nodes:n,onBindDefault:e.onBindDefault,onBindAgent:e.onBindAgent,onSave:e.onSaveBindings,onLoadConfig:e.onLoadConfig,formMode:e.configFormMode}}function Ha(e){return e==="allowlist"||e==="full"||e==="deny"?e:"deny"}function Hf(e){return e==="always"||e==="off"||e==="on-miss"?e:"on-miss"}function zf(e){const t=e?.defaults??{};return{security:Ha(t.security),ask:Hf(t.ask),askFallback:Ha(t.askFallback??"deny"),autoAllowSkills:!!(t.autoAllowSkills??!1)}}function jf(e){const t=e?.agents??{},n=Array.isArray(t.list)?t.list:[],s=[];return n.forEach(i=>{if(!i||typeof i!="object")return;const a=i,o=typeof a.id=="string"?a.id.trim():"";if(!o)return;const c=typeof a.name=="string"?a.name.trim():void 0,l=a.default===!0;s.push({id:o,name:c||void 0,isDefault:l})}),s}function qf(e,t){const n=jf(e),s=Object.keys(t?.agents??{}),i=new Map;n.forEach(o=>i.set(o.id,o)),s.forEach(o=>{i.has(o)||i.set(o,{id:o})});const a=Array.from(i.values());return a.length===0&&a.push({id:"main",isDefault:!0}),a.sort((o,c)=>{if(o.isDefault&&!c.isDefault)return-1;if(!o.isDefault&&c.isDefault)return 1;const l=o.name?.trim()?o.name:o.id,p=c.name?.trim()?c.name:c.id;return l.localeCompare(p)}),a}function Vf(e,t){return e===Ae?Ae:e&&t.some(n=>n.id===e)?e:Ae}function Wf(e){const t=e.execApprovalsForm??e.execApprovalsSnapshot?.file??null,n=!!t,s=zf(t),i=qf(e.configForm,t),a=sh(e.nodes),o=e.execApprovalsTarget;let c=o==="node"&&e.execApprovalsTargetNodeId?e.execApprovalsTargetNodeId:null;o==="node"&&c&&!a.some(u=>u.id===c)&&(c=null);const l=Vf(e.execApprovalsSelectedAgent,i),p=l!==Ae?(t?.agents??{})[l]??null:null,d=Array.isArray(p?.allowlist)?p.allowlist??[]:[];return{ready:n,disabled:e.execApprovalsSaving||e.execApprovalsLoading,dirty:e.execApprovalsDirty,loading:e.execApprovalsLoading,saving:e.execApprovalsSaving,form:t,defaults:s,selectedScope:l,selectedAgent:p,agents:i,allowlist:d,target:o,targetNodeId:c,targetNodes:a,onSelectScope:e.onExecApprovalsSelectAgent,onSelectTarget:e.onExecApprovalsTargetChange,onPatch:e.onExecApprovalsPatch,onRemove:e.onExecApprovalsRemove,onLoad:e.onLoadExecApprovals,onSave:e.onSaveExecApprovals}}function Gf(e){const t=e.nodes.length>0,n=e.defaultBinding??"";return r` -
-
-
-
Exec node binding
-
- Pin agents to a specific node when using exec host=node. -
-
- -
- - ${e.formMode==="raw"?r`
- Switch the Config tab to Form mode to edit bindings here. -
`:g} - - ${e.ready?r` -
-
-
-
Default binding
-
Used when agents do not override a node binding.
-
-
- - ${t?g:r`
No nodes with system.run available.
`} -
-
- - ${e.agents.length===0?r`
No agents found.
`:e.agents.map(s=>th(s,e))} -
- `:r`
-
Load config to edit bindings.
- -
`} -
- `}function Yf(e){const t=e.ready,n=e.target!=="node"||!!e.targetNodeId;return r` -
-
-
-
Exec approvals
-
- Allowlist and approval policy for exec host=gateway/node. -
-
- -
- - ${Qf(e)} - - ${t?r` - ${Zf(e)} - ${Jf(e)} - ${e.selectedScope===Ae?g:Xf(e)} - `:r`
-
Load exec approvals to edit allowlists.
- -
`} -
- `}function Qf(e){const t=e.targetNodes.length>0,n=e.targetNodeId??"";return r` -
-
-
-
Target
-
- Gateway edits local approvals; node edits the selected node. -
-
-
- - ${e.target==="node"?r` - - `:g} -
-
- ${e.target==="node"&&!t?r`
No nodes advertise exec approvals yet.
`:g} -
- `}function Zf(e){return r` -
- Scope -
- - ${e.agents.map(t=>{const n=t.name?.trim()?`${t.name} (${t.id})`:t.id;return r` - - `})} -
-
- `}function Jf(e){const t=e.selectedScope===Ae,n=e.defaults,s=e.selectedAgent??{},i=t?["defaults"]:["agents",e.selectedScope],a=typeof s.security=="string"?s.security:void 0,o=typeof s.ask=="string"?s.ask:void 0,c=typeof s.askFallback=="string"?s.askFallback:void 0,l=t?n.security:a??"__default__",p=t?n.ask:o??"__default__",d=t?n.askFallback:c??"__default__",u=typeof s.autoAllowSkills=="boolean"?s.autoAllowSkills:void 0,h=u??n.autoAllowSkills,v=u==null;return r` -
-
-
-
Security
-
- ${t?"Default security mode.":`Default: ${n.security}.`} -
-
-
- -
-
- -
-
-
Ask
-
- ${t?"Default prompt policy.":`Default: ${n.ask}.`} -
-
-
- -
-
- -
-
-
Ask fallback
-
- ${t?"Applied when the UI prompt is unavailable.":`Default: ${n.askFallback}.`} -
-
-
- -
-
- -
-
-
Auto-allow skill CLIs
-
- ${t?"Allow skill executables listed by the Gateway.":v?`Using default (${n.autoAllowSkills?"on":"off"}).`:`Override (${h?"on":"off"}).`} -
-
-
- - ${!t&&!v?r``:g} -
-
-
- `}function Xf(e){const t=["agents",e.selectedScope,"allowlist"],n=e.allowlist;return r` -
-
-
Allowlist
-
Case-insensitive glob patterns.
-
- -
-
- ${n.length===0?r`
No allowlist entries yet.
`:n.map((s,i)=>eh(e,s,i))} -
- `}function eh(e,t,n){const s=t.lastUsedAt?O(t.lastUsedAt):"never",i=t.lastUsedCommand?as(t.lastUsedCommand,120):null,a=t.lastResolvedPath?as(t.lastResolvedPath,120):null;return r` -
-
-
${t.pattern?.trim()?t.pattern:"New pattern"}
-
Last used: ${s}
- ${i?r`
${i}
`:g} - ${a?r`
${a}
`:g} -
-
- - -
-
- `}function th(e,t){const n=e.binding??"__default__",s=e.name?.trim()?`${e.name} (${e.id})`:e.id,i=t.nodes.length>0;return r` -
-
-
${s}
-
- ${e.isDefault?"default agent":"agent"} · - ${n==="__default__"?`uses default (${t.defaultBinding??"any"})`:`override: ${e.binding}`} -
-
-
- -
-
- `}function nh(e){const t=[];for(const n of e){if(!(Array.isArray(n.commands)?n.commands:[]).some(c=>String(c)==="system.run"))continue;const a=typeof n.nodeId=="string"?n.nodeId.trim():"";if(!a)continue;const o=typeof n.displayName=="string"&&n.displayName.trim()?n.displayName.trim():a;t.push({id:a,label:o===a?a:`${o} · ${a}`})}return t.sort((n,s)=>n.label.localeCompare(s.label)),t}function sh(e){const t=[];for(const n of e){if(!(Array.isArray(n.commands)?n.commands:[]).some(c=>String(c)==="system.execApprovals.get"||String(c)==="system.execApprovals.set"))continue;const a=typeof n.nodeId=="string"?n.nodeId.trim():"";if(!a)continue;const o=typeof n.displayName=="string"&&n.displayName.trim()?n.displayName.trim():a;t.push({id:a,label:o===a?a:`${o} · ${a}`})}return t.sort((n,s)=>n.label.localeCompare(s.label)),t}function ih(e){const t={id:"main",name:void 0,index:0,isDefault:!0,binding:null};if(!e||typeof e!="object")return{defaultBinding:null,agents:[t]};const s=(e.tools??{}).exec??{},i=typeof s.node=="string"&&s.node.trim()?s.node.trim():null,a=e.agents??{},o=Array.isArray(a.list)?a.list:[];if(o.length===0)return{defaultBinding:i,agents:[t]};const c=[];return o.forEach((l,p)=>{if(!l||typeof l!="object")return;const d=l,u=typeof d.id=="string"?d.id.trim():"";if(!u)return;const h=typeof d.name=="string"?d.name.trim():void 0,v=d.default===!0,$=(d.tools??{}).exec??{},k=typeof $.node=="string"&&$.node.trim()?$.node.trim():null;c.push({id:u,name:h||void 0,index:p,isDefault:v,binding:k})}),c.length===0&&c.push(t),{defaultBinding:i,agents:c}}function ah(e){const t=!!e.connected,n=!!e.paired,s=typeof e.displayName=="string"&&e.displayName.trim()||(typeof e.nodeId=="string"?e.nodeId:"unknown"),i=Array.isArray(e.caps)?e.caps:[],a=Array.isArray(e.commands)?e.commands:[];return r` -
-
-
${s}
-
- ${typeof e.nodeId=="string"?e.nodeId:""} - ${typeof e.remoteIp=="string"?` · ${e.remoteIp}`:""} - ${typeof e.version=="string"?` · ${e.version}`:""} -
-
- ${n?"paired":"unpaired"} - - ${t?"connected":"offline"} - - ${i.slice(0,12).map(o=>r`${String(o)}`)} - ${a.slice(0,8).map(o=>r`${String(o)}`)} -
-
-
- `}function oh(e){const t=e.hello?.snapshot,n=t?.uptimeMs?io(t.uptimeMs):"n/a",s=t?.policy?.tickIntervalMs?`${t.policy.tickIntervalMs}ms`:"n/a",i=(()=>{if(e.connected||!e.lastError)return null;const o=e.lastError.toLowerCase();if(!(o.includes("unauthorized")||o.includes("connect failed")))return null;const l=!!e.settings.token.trim(),p=!!e.password.trim();return!l&&!p?r` -
- `:r` -
- Auth failed. Re-copy a tokenized URL with - clawdbot dashboard --no-open, or update the token, - then click Connect. - -
- `})(),a=(()=>{if(e.connected||!e.lastError||(typeof window<"u"?window.isSecureContext:!0)!==!1)return null;const c=e.lastError.toLowerCase();return!c.includes("secure context")&&!c.includes("device identity required")?null:r` -
- This page is HTTP, so the browser blocks device identity. Use HTTPS (Tailscale Serve) or - open http://127.0.0.1:18789 on the gateway host. -
- If you must stay on HTTP, set - gateway.controlUi.allowInsecureAuth: true (token-only). -
- -
- `})();return r` -
-
-
Gateway Access
-
Where the dashboard connects and how it authenticates.
-
- - - - -
-
- - - Click Connect to apply connection changes. -
-
- -
-
Snapshot
-
Latest gateway handshake information.
-
-
-
Status
-
- ${e.connected?"Connected":"Disconnected"} -
-
-
-
Uptime
-
${n}
-
-
-
Tick Interval
-
${s}
-
-
-
Last Channels Refresh
-
- ${e.lastChannelsRefresh?O(e.lastChannelsRefresh):"n/a"} -
-
-
- ${e.lastError?r`
-
${e.lastError}
- ${i??""} - ${a??""} -
`:r`
- Use Channels to link WhatsApp, Telegram, Discord, Signal, or iMessage. -
`} -
-
- -
-
-
Instances
-
${e.presenceCount}
-
Presence beacons in the last 5 minutes.
-
-
-
Sessions
-
${e.sessionsCount??"n/a"}
-
Recent session keys tracked by the gateway.
-
-
-
Cron
-
- ${e.cronEnabled==null?"n/a":e.cronEnabled?"Enabled":"Disabled"} -
-
Next wake ${gr(e.cronNext)}
-
-
- -
-
Notes
-
Quick reminders for remote control setups.
-
-
-
Tailscale serve
-
- Prefer serve mode to keep the gateway on loopback with tailnet auth. -
-
-
-
Session hygiene
-
Use /new or sessions.patch to reset context.
-
-
-
Cron reminders
-
Use isolated sessions for recurring runs.
-
-
-
- `}const rh=["","off","minimal","low","medium","high"],lh=["","off","on"],ch=[{value:"",label:"inherit"},{value:"off",label:"off (explicit)"},{value:"on",label:"on"}],dh=["","off","on","stream"];function uh(e){if(!e)return"";const t=e.trim().toLowerCase();return t==="z.ai"||t==="z-ai"?"zai":t}function vr(e){return uh(e)==="zai"}function ph(e){return vr(e)?lh:rh}function fh(e,t){return!t||!e||e==="off"?e:"on"}function hh(e,t){return e?t&&e==="on"?"low":e:null}function gh(e){const t=e.result?.sessions??[];return r` -
-
-
-
Sessions
-
Active session keys and per-session overrides.
-
- -
- -
- - - - -
- - ${e.error?r`
${e.error}
`:g} - -
- ${e.result?`Store: ${e.result.path}`:""} -
- -
-
-
Key
-
Label
-
Kind
-
Updated
-
Tokens
-
Thinking
-
Verbose
-
Reasoning
-
Actions
-
- ${t.length===0?r`
No sessions found.
`:t.map(n=>vh(n,e.basePath,e.onPatch,e.onDelete,e.loading))} -
-
- `}function vh(e,t,n,s,i){const a=e.updatedAt?O(e.updatedAt):"n/a",o=e.thinkingLevel??"",c=vr(e.modelProvider),l=fh(o,c),p=ph(e.modelProvider),d=e.verboseLevel??"",u=e.reasoningLevel??"",h=e.displayName??e.key,v=e.kind!=="global",w=v?`${Rs("chat",t)}?session=${encodeURIComponent(e.key)}`:null;return r` -
-
${v?r`${h}`:h}
-
- {const k=$.target.value.trim();n(e.key,{label:k||null})}} - /> -
-
${e.kind}
-
${a}
-
${bf(e)}
-
- -
-
- -
-
- -
-
- -
-
- `}function mh(e){const t=Math.max(0,e),n=Math.floor(t/1e3);if(n<60)return`${n}s`;const s=Math.floor(n/60);return s<60?`${s}m`:`${Math.floor(s/60)}h`}function Ie(e,t){return t?r`
${e}${t}
`:g}function bh(e){const t=e.execApprovalQueue[0];if(!t)return g;const n=t.request,s=t.expiresAtMs-Date.now(),i=s>0?`expires in ${mh(s)}`:"expired",a=e.execApprovalQueue.length;return r` - - `}function yh(e){const t=e.report?.skills??[],n=e.filter.trim().toLowerCase(),s=n?t.filter(i=>[i.name,i.description,i.source].join(" ").toLowerCase().includes(n)):t;return r` -
-
-
-
Skills
-
Bundled, managed, and workspace skills.
-
- -
- -
- -
${s.length} shown
-
- - ${e.error?r`
${e.error}
`:g} - - ${s.length===0?r`
No skills found.
`:r` -
- ${s.map(i=>wh(i,e))} -
- `} -
- `}function wh(e,t){const n=t.busyKey===e.skillKey,s=t.edits[e.skillKey]??"",i=t.messages[e.skillKey]??null,a=e.install.length>0&&e.missing.bins.length>0,o=[...e.missing.bins.map(l=>`bin:${l}`),...e.missing.env.map(l=>`env:${l}`),...e.missing.config.map(l=>`config:${l}`),...e.missing.os.map(l=>`os:${l}`)],c=[];return e.disabled&&c.push("disabled"),e.blockedByAllowlist&&c.push("blocked by allowlist"),r` -
-
-
- ${e.emoji?`${e.emoji} `:""}${e.name} -
-
${as(e.description,140)}
-
- ${e.source} - - ${e.eligible?"eligible":"blocked"} - - ${e.disabled?r`disabled`:g} -
- ${o.length>0?r` -
- Missing: ${o.join(", ")} -
- `:g} - ${c.length>0?r` -
- Reason: ${c.join(", ")} -
- `:g} -
-
-
- - ${a?r``:g} -
- ${i?r`
- ${i.message} -
`:g} - ${e.primaryEnv?r` -
- API key - t.onEdit(e.skillKey,l.target.value)} - /> -
- - `:g} -
-
- `}function $h(e,t){const n=Rs(t,e.basePath);return r` - {s.defaultPrevented||s.button!==0||s.metaKey||s.ctrlKey||s.shiftKey||s.altKey||(s.preventDefault(),e.setTab(t))}} - title=${ss(t)} - > - - ${ss(t)} - - `}function xh(e){const t=kh(e.sessionKey,e.sessionsResult),n=e.onboarding,s=e.onboarding,i=e.onboarding?!1:e.settings.chatShowThinking,a=e.onboarding?!0:e.settings.chatFocusMode,o=r``,c=r``;return r` -
- - - | - - -
- `}function kh(e,t){const n=new Set,s=[],i=t?.sessions?.find(a=>a.key===e);if(n.add(e),s.push({key:e,displayName:i?.displayName}),t?.sessions)for(const a of t.sessions)n.has(a.key)||(n.add(a.key),s.push({key:a.key,displayName:a.displayName}));return s}const Ah=["system","light","dark"];function Sh(e){const t=Math.max(0,Ah.indexOf(e.theme)),n=s=>i=>{const o={element:i.currentTarget};(i.clientX||i.clientY)&&(o.pointerClientX=i.clientX,o.pointerClientY=i.clientY),e.setTheme(s,o)};return r` -
-
- - - - -
-
- `}function _h(){return r` - - `}function Th(){return r` - - `}function Ch(){return r` - - `}const Eh=/^data:/i,Lh=/^https?:\/\//i;function Mh(e){const t=e.agentsList?.agents??[],s=eo(e.sessionKey)?.agentId??e.agentsList?.defaultId??"main",a=t.find(c=>c.id===s)?.identity,o=a?.avatarUrl??a?.avatar;if(o)return Eh.test(o)||Lh.test(o)?o:a?.avatarUrl}function Ih(e){const t=e.presenceEntries.length,n=e.sessionsResult?.count??null,s=e.cronStatus?.nextWakeAtMs??null,i=e.connected?null:"Disconnected from gateway.",a=e.tab==="chat",o=a&&(e.settings.chatFocusMode||e.onboarding),c=e.onboarding?!1:e.settings.chatShowThinking,l=Mh(e),p=e.chatAvatarUrl??l??null;return r` -
-
-
- -
- -
-
CLAWDBOT
-
Gateway Dashboard
-
-
-
-
-
- - Health - ${e.connected?"OK":"Offline"} -
- ${Sh(e)} -
-
- -
-
-
-
${ss(e.tab)}
-
${ml(e.tab)}
-
-
- ${e.lastError?r`
${e.lastError}
`:g} - ${a?xh(e):g} -
-
- - ${e.tab==="overview"?oh({connected:e.connected,hello:e.hello,settings:e.settings,password:e.password,lastError:e.lastError,presenceCount:t,sessionsCount:n,cronEnabled:e.cronStatus?.enabled??null,cronNext:s,lastChannelsRefresh:e.channelsLastSuccess,onSettingsChange:d=>e.applySettings(d),onPasswordChange:d=>e.password=d,onSessionKeyChange:d=>{e.sessionKey=d,e.chatMessage="",e.resetToolStream(),e.applySettings({...e.settings,sessionKey:d,lastActiveSessionKey:d}),e.loadAssistantIdentity()},onConnect:()=>e.connect(),onRefresh:()=>e.loadOverview()}):g} - - ${e.tab==="channels"?of({connected:e.connected,loading:e.channelsLoading,snapshot:e.channelsSnapshot,lastError:e.channelsError,lastSuccessAt:e.channelsLastSuccess,whatsappMessage:e.whatsappLoginMessage,whatsappQrDataUrl:e.whatsappLoginQrDataUrl,whatsappConnected:e.whatsappLoginConnected,whatsappBusy:e.whatsappBusy,configSchema:e.configSchema,configSchemaLoading:e.configSchemaLoading,configForm:e.configForm,configUiHints:e.configUiHints,configSaving:e.configSaving,configFormDirty:e.configFormDirty,nostrProfileFormState:e.nostrProfileFormState,nostrProfileAccountId:e.nostrProfileAccountId,onRefresh:d=>oe(e,d),onWhatsAppStart:d=>e.handleWhatsAppStart(d),onWhatsAppWait:()=>e.handleWhatsAppWait(),onWhatsAppLogout:()=>e.handleWhatsAppLogout(),onConfigPatch:(d,u)=>Bt(e,d,u),onConfigSave:()=>e.handleChannelConfigSave(),onConfigReload:()=>e.handleChannelConfigReload(),onNostrProfileEdit:(d,u)=>e.handleNostrProfileEdit(d,u),onNostrProfileCancel:()=>e.handleNostrProfileCancel(),onNostrProfileFieldChange:(d,u)=>e.handleNostrProfileFieldChange(d,u),onNostrProfileSave:()=>e.handleNostrProfileSave(),onNostrProfileImport:()=>e.handleNostrProfileImport(),onNostrProfileToggleAdvanced:()=>e.handleNostrProfileToggleAdvanced()}):g} - - ${e.tab==="instances"?Lf({loading:e.presenceLoading,entries:e.presenceEntries,lastError:e.presenceError,statusMessage:e.presenceStatus,onRefresh:()=>js(e)}):g} - - ${e.tab==="sessions"?gh({loading:e.sessionsLoading,result:e.sessionsResult,error:e.sessionsError,activeMinutes:e.sessionsFilterActive,limit:e.sessionsFilterLimit,includeGlobal:e.sessionsIncludeGlobal,includeUnknown:e.sessionsIncludeUnknown,basePath:e.basePath,onFiltersChange:d=>{e.sessionsFilterActive=d.activeMinutes,e.sessionsFilterLimit=d.limit,e.sessionsIncludeGlobal=d.includeGlobal,e.sessionsIncludeUnknown=d.includeUnknown},onRefresh:()=>st(e),onPatch:(d,u)=>Ml(e,d,u),onDelete:d=>Il(e,d)}):g} - - ${e.tab==="cron"?Sf({loading:e.cronLoading,status:e.cronStatus,jobs:e.cronJobs,error:e.cronError,busy:e.cronBusy,form:e.cronForm,channels:e.channelsSnapshot?.channelMeta?.length?e.channelsSnapshot.channelMeta.map(d=>d.id):e.channelsSnapshot?.channelOrder??[],channelLabels:e.channelsSnapshot?.channelLabels??{},channelMeta:e.channelsSnapshot?.channelMeta??[],runsJobId:e.cronRunsJobId,runs:e.cronRuns,onFormChange:d=>e.cronForm={...e.cronForm,...d},onRefresh:()=>e.loadCron(),onAdd:()=>ec(e),onToggle:(d,u)=>tc(e,d,u),onRun:d=>nc(e,d),onRemove:d=>sc(e,d),onLoadRuns:d=>po(e,d)}):g} - - ${e.tab==="skills"?yh({loading:e.skillsLoading,report:e.skillsReport,error:e.skillsError,filter:e.skillsFilter,edits:e.skillEdits,messages:e.skillMessages,busyKey:e.skillsBusyKey,onFilterChange:d=>e.skillsFilter=d,onRefresh:()=>Ct(e,{clearMessages:!0}),onToggle:(d,u)=>Zc(e,d,u),onEdit:(d,u)=>Qc(e,d,u),onSaveKey:d=>Jc(e,d),onInstall:(d,u,h)=>Xc(e,d,u,h)}):g} - - ${e.tab==="nodes"?Nf({loading:e.nodesLoading,nodes:e.nodes,devicesLoading:e.devicesLoading,devicesError:e.devicesError,devicesList:e.devicesList,configForm:e.configForm??e.configSnapshot?.config,configLoading:e.configLoading,configSaving:e.configSaving,configDirty:e.configFormDirty,configFormMode:e.configFormMode,execApprovalsLoading:e.execApprovalsLoading,execApprovalsSaving:e.execApprovalsSaving,execApprovalsDirty:e.execApprovalsDirty,execApprovalsSnapshot:e.execApprovalsSnapshot,execApprovalsForm:e.execApprovalsForm,execApprovalsSelectedAgent:e.execApprovalsSelectedAgent,execApprovalsTarget:e.execApprovalsTarget,execApprovalsTargetNodeId:e.execApprovalsTargetNodeId,onRefresh:()=>pn(e),onDevicesRefresh:()=>Te(e),onDeviceApprove:d=>Uc(e,d),onDeviceReject:d=>Kc(e,d),onDeviceRotate:(d,u,h)=>Hc(e,{deviceId:d,role:u,scopes:h}),onDeviceRevoke:(d,u)=>zc(e,{deviceId:d,role:u}),onLoadConfig:()=>be(e),onLoadExecApprovals:()=>{const d=e.execApprovalsTarget==="node"&&e.execApprovalsTargetNodeId?{kind:"node",nodeId:e.execApprovalsTargetNodeId}:{kind:"gateway"};return zs(e,d)},onBindDefault:d=>{d?Bt(e,["tools","exec","node"],d):Zi(e,["tools","exec","node"])},onBindAgent:(d,u)=>{const h=["agents","list",d,"tools","exec","node"];u?Bt(e,h,u):Zi(e,h)},onSaveBindings:()=>ls(e),onExecApprovalsTargetChange:(d,u)=>{e.execApprovalsTarget=d,e.execApprovalsTargetNodeId=u,e.execApprovalsSnapshot=null,e.execApprovalsForm=null,e.execApprovalsDirty=!1,e.execApprovalsSelectedAgent=null},onExecApprovalsSelectAgent:d=>{e.execApprovalsSelectedAgent=d},onExecApprovalsPatch:(d,u)=>Gc(e,d,u),onExecApprovalsRemove:d=>Yc(e,d),onSaveExecApprovals:()=>{const d=e.execApprovalsTarget==="node"&&e.execApprovalsTargetNodeId?{kind:"node",nodeId:e.execApprovalsTargetNodeId}:{kind:"gateway"};return Wc(e,d)}}):g} - - ${e.tab==="chat"?kp({sessionKey:e.sessionKey,onSessionKeyChange:d=>{e.sessionKey=d,e.chatMessage="",e.chatStream=null,e.chatStreamStartedAt=null,e.chatRunId=null,e.chatQueue=[],e.resetToolStream(),e.resetChatScroll(),e.applySettings({...e.settings,sessionKey:d,lastActiveSessionKey:d}),e.loadAssistantIdentity(),Xe(e),fs(e)},thinkingLevel:e.chatThinkingLevel,showThinking:c,loading:e.chatLoading,sending:e.chatSending,compactionStatus:e.compactionStatus,assistantAvatarUrl:p,messages:e.chatMessages,toolMessages:e.chatToolMessages,stream:e.chatStream,streamStartedAt:e.chatStreamStartedAt,draft:e.chatMessage,queue:e.chatQueue,connected:e.connected,canSend:e.connected,disabledReason:i,error:e.lastError,sessions:e.sessionsResult,focusMode:o,onRefresh:()=>(e.resetToolStream(),Promise.all([Xe(e),fs(e)])),onToggleFocusMode:()=>{e.onboarding||e.applySettings({...e.settings,chatFocusMode:!e.settings.chatFocusMode})},onChatScroll:d=>e.handleChatScroll(d),onDraftChange:d=>e.chatMessage=d,onSend:()=>e.handleSendChat(),canAbort:!!e.chatRunId,onAbort:()=>{e.handleAbortChat()},onQueueRemove:d=>e.removeQueuedMessage(d),onNewSession:()=>e.handleSendChat("/new",{restoreDraft:!0}),sidebarOpen:e.sidebarOpen,sidebarContent:e.sidebarContent,sidebarError:e.sidebarError,splitRatio:e.splitRatio,onOpenSidebar:d=>e.handleOpenSidebar(d),onCloseSidebar:()=>e.handleCloseSidebar(),onSplitRatioChange:d=>e.handleSplitRatioChange(d),assistantName:e.assistantName,assistantAvatar:e.assistantAvatar}):g} - - ${e.tab==="config"?Kp({raw:e.configRaw,originalRaw:e.configRawOriginal,valid:e.configValid,issues:e.configIssues,loading:e.configLoading,saving:e.configSaving,applying:e.configApplying,updating:e.updateRunning,connected:e.connected,schema:e.configSchema,schemaLoading:e.configSchemaLoading,uiHints:e.configUiHints,formMode:e.configFormMode,formValue:e.configForm,originalValue:e.configFormOriginal,searchQuery:e.configSearchQuery,activeSection:e.configActiveSection,activeSubsection:e.configActiveSubsection,onRawChange:d=>{e.configRaw=d},onFormModeChange:d=>e.configFormMode=d,onFormPatch:(d,u)=>Bt(e,d,u),onSearchChange:d=>e.configSearchQuery=d,onSectionChange:d=>{e.configActiveSection=d,e.configActiveSubsection=null},onSubsectionChange:d=>e.configActiveSubsection=d,onReload:()=>be(e),onSave:()=>ls(e),onApply:()=>Ql(e),onUpdate:()=>Zl(e)}):g} - - ${e.tab==="debug"?Ef({loading:e.debugLoading,status:e.debugStatus,health:e.debugHealth,models:e.debugModels,heartbeat:e.debugHeartbeat,eventLog:e.eventLog,callMethod:e.debugCallMethod,callParams:e.debugCallParams,callResult:e.debugCallResult,callError:e.debugCallError,onCallMethodChange:d=>e.debugCallMethod=d,onCallParamsChange:d=>e.debugCallParams=d,onRefresh:()=>dn(e),onCall:()=>rc(e)}):g} - - ${e.tab==="logs"?Pf({loading:e.logsLoading,error:e.logsError,file:e.logsFile,entries:e.logsEntries,filterText:e.logsFilterText,levelFilters:e.logsLevelFilters,autoFollow:e.logsAutoFollow,truncated:e.logsTruncated,onFilterTextChange:d=>e.logsFilterText=d,onLevelToggle:(d,u)=>{e.logsLevelFilters={...e.logsLevelFilters,[d]:u}},onToggleAutoFollow:d=>e.logsAutoFollow=d,onRefresh:()=>Os(e,{reset:!0}),onExport:(d,u)=>e.exportLogs(d,u),onScroll:d=>e.handleLogsScroll(d)}):g} -
- ${bh(e)} -
- `}const Rh={trace:!0,debug:!0,info:!0,warn:!0,error:!0,fatal:!0},Ph={name:"",description:"",agentId:"",enabled:!0,scheduleKind:"every",scheduleAt:"",everyAmount:"30",everyUnit:"minutes",cronExpr:"0 7 * * *",cronTz:"",sessionTarget:"main",wakeMode:"next-heartbeat",payloadKind:"systemEvent",payloadText:"",deliver:!1,channel:"last",to:"",timeoutSeconds:"",postToMainPrefix:""};async function Nh(e){if(!(!e.client||!e.connected)&&!e.agentsLoading){e.agentsLoading=!0,e.agentsError=null;try{const t=await e.client.request("agents.list",{});t&&(e.agentsList=t)}catch(t){e.agentsError=String(t)}finally{e.agentsLoading=!1}}}const mr={WEBCHAT_UI:"webchat-ui",CONTROL_UI:"clawdbot-control-ui",WEBCHAT:"webchat",CLI:"cli",GATEWAY_CLIENT:"gateway-client",MACOS_APP:"clawdbot-macos",IOS_APP:"clawdbot-ios",ANDROID_APP:"clawdbot-android",NODE_HOST:"node-host",TEST:"test",FINGERPRINT:"fingerprint",PROBE:"clawdbot-probe"},za=mr,Ss={WEBCHAT:"webchat",CLI:"cli",UI:"ui",BACKEND:"backend",NODE:"node",PROBE:"probe",TEST:"test"};new Set(Object.values(mr));new Set(Object.values(Ss));function Oh(e){const t=e.version??(e.nonce?"v2":"v1"),n=e.scopes.join(","),s=e.token??"",i=[t,e.deviceId,e.clientId,e.clientMode,e.role,n,String(e.signedAtMs),s];return t==="v2"&&i.push(e.nonce??""),i.join("|")}const Dh=4008;class Bh{constructor(t){this.opts=t,this.ws=null,this.pending=new Map,this.closed=!1,this.lastSeq=null,this.connectNonce=null,this.connectSent=!1,this.connectTimer=null,this.backoffMs=800}start(){this.closed=!1,this.connect()}stop(){this.closed=!0,this.ws?.close(),this.ws=null,this.flushPending(new Error("gateway client stopped"))}get connected(){return this.ws?.readyState===WebSocket.OPEN}connect(){this.closed||(this.ws=new WebSocket(this.opts.url),this.ws.onopen=()=>this.queueConnect(),this.ws.onmessage=t=>this.handleMessage(String(t.data??"")),this.ws.onclose=t=>{const n=String(t.reason??"");this.ws=null,this.flushPending(new Error(`gateway closed (${t.code}): ${n}`)),this.opts.onClose?.({code:t.code,reason:n}),this.scheduleReconnect()},this.ws.onerror=()=>{})}scheduleReconnect(){if(this.closed)return;const t=this.backoffMs;this.backoffMs=Math.min(this.backoffMs*1.7,15e3),window.setTimeout(()=>this.connect(),t)}flushPending(t){for(const[,n]of this.pending)n.reject(t);this.pending.clear()}async sendConnect(){if(this.connectSent)return;this.connectSent=!0,this.connectTimer!==null&&(window.clearTimeout(this.connectTimer),this.connectTimer=null);const t=typeof crypto<"u"&&!!crypto.subtle,n=["operator.admin","operator.approvals","operator.pairing"],s="operator";let i=null,a=!1,o=this.opts.token;if(t){i=await Us();const d=Fc({deviceId:i.deviceId,role:s})?.token;o=d??this.opts.token,a=!!(d&&this.opts.token)}const c=o||this.opts.password?{token:o,password:this.opts.password}:void 0;let l;if(t&&i){const d=Date.now(),u=this.connectNonce??void 0,h=Oh({deviceId:i.deviceId,clientId:this.opts.clientName??za.CONTROL_UI,clientMode:this.opts.mode??Ss.WEBCHAT,role:s,scopes:n,signedAtMs:d,token:o??null,nonce:u}),v=await Dc(i.privateKey,h);l={id:i.deviceId,publicKey:i.publicKey,signature:v,signedAt:d,nonce:u}}const p={minProtocol:3,maxProtocol:3,client:{id:this.opts.clientName??za.CONTROL_UI,version:this.opts.clientVersion??"dev",platform:this.opts.platform??navigator.platform??"web",mode:this.opts.mode??Ss.WEBCHAT,instanceId:this.opts.instanceId},role:s,scopes:n,device:l,caps:[],auth:c,userAgent:navigator.userAgent,locale:navigator.language};this.request("connect",p).then(d=>{d?.auth?.deviceToken&&i&&Eo({deviceId:i.deviceId,role:d.auth.role??s,token:d.auth.deviceToken,scopes:d.auth.scopes??[]}),this.backoffMs=800,this.opts.onHello?.(d)}).catch(()=>{a&&i&&Lo({deviceId:i.deviceId,role:s}),this.ws?.close(Dh,"connect failed")})}handleMessage(t){let n;try{n=JSON.parse(t)}catch{return}const s=n;if(s.type==="event"){const i=n;if(i.event==="connect.challenge"){const o=i.payload,c=o&&typeof o.nonce=="string"?o.nonce:null;c&&(this.connectNonce=c,this.sendConnect());return}const a=typeof i.seq=="number"?i.seq:null;a!==null&&(this.lastSeq!==null&&a>this.lastSeq+1&&this.opts.onGap?.({expected:this.lastSeq+1,received:a}),this.lastSeq=a);try{this.opts.onEvent?.(i)}catch(o){console.error("[gateway] event handler error:",o)}return}if(s.type==="res"){const i=n,a=this.pending.get(i.id);if(!a)return;this.pending.delete(i.id),i.ok?a.resolve(i.payload):a.reject(new Error(i.error?.message??"request failed"));return}}request(t,n){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)return Promise.reject(new Error("gateway not connected"));const s=Ps(),i={type:"req",id:s,method:t,params:n},a=new Promise((o,c)=>{this.pending.set(s,{resolve:l=>o(l),reject:c})});return this.ws.send(JSON.stringify(i)),a}queueConnect(){this.connectNonce=null,this.connectSent=!1,this.connectTimer!==null&&window.clearTimeout(this.connectTimer),this.connectTimer=window.setTimeout(()=>{this.sendConnect()},750)}}function _s(e){return typeof e=="object"&&e!==null}function Fh(e){if(!_s(e))return null;const t=typeof e.id=="string"?e.id.trim():"",n=e.request;if(!t||!_s(n))return null;const s=typeof n.command=="string"?n.command.trim():"";if(!s)return null;const i=typeof e.createdAtMs=="number"?e.createdAtMs:0,a=typeof e.expiresAtMs=="number"?e.expiresAtMs:0;return!i||!a?null:{id:t,request:{command:s,cwd:typeof n.cwd=="string"?n.cwd:null,host:typeof n.host=="string"?n.host:null,security:typeof n.security=="string"?n.security:null,ask:typeof n.ask=="string"?n.ask:null,agentId:typeof n.agentId=="string"?n.agentId:null,resolvedPath:typeof n.resolvedPath=="string"?n.resolvedPath:null,sessionKey:typeof n.sessionKey=="string"?n.sessionKey:null},createdAtMs:i,expiresAtMs:a}}function Uh(e){if(!_s(e))return null;const t=typeof e.id=="string"?e.id.trim():"";return t?{id:t,decision:typeof e.decision=="string"?e.decision:null,resolvedBy:typeof e.resolvedBy=="string"?e.resolvedBy:null,ts:typeof e.ts=="number"?e.ts:null}:null}function br(e){const t=Date.now();return e.filter(n=>n.expiresAtMs>t)}function Kh(e,t){const n=br(e).filter(s=>s.id!==t.id);return n.push(t),n}function ja(e,t){return br(e).filter(n=>n.id!==t)}async function yr(e,t){if(!e.client||!e.connected)return;const n=e.sessionKey.trim(),s=n?{sessionKey:n}:{};try{const i=await e.client.request("agent.identity.get",s);if(!i)return;const a=ns(i);e.assistantName=a.name,e.assistantAvatar=a.avatar,e.assistantAgentId=a.agentId??null}catch{}}function Xn(e,t){const n=(e??"").trim(),s=t.mainSessionKey?.trim();if(!s)return n;if(!n)return s;const i=t.mainKey?.trim()||"main",a=t.defaultAgentId?.trim();return n==="main"||n===i||a&&(n===`agent:${a}:main`||n===`agent:${a}:${i}`)?s:n}function Hh(e,t){if(!t?.mainSessionKey)return;const n=Xn(e.sessionKey,t),s=Xn(e.settings.sessionKey,t),i=Xn(e.settings.lastActiveSessionKey,t),a=n||s||e.sessionKey,o={...e.settings,sessionKey:s||a,lastActiveSessionKey:i||a},c=o.sessionKey!==e.settings.sessionKey||o.lastActiveSessionKey!==e.settings.lastActiveSessionKey;a!==e.sessionKey&&(e.sessionKey=a),c&&ke(e,o)}function wr(e){e.lastError=null,e.hello=null,e.connected=!1,e.execApprovalQueue=[],e.execApprovalError=null,e.client?.stop(),e.client=new Bh({url:e.settings.gatewayUrl,token:e.settings.token.trim()?e.settings.token:void 0,password:e.password.trim()?e.password:void 0,clientName:"clawdbot-control-ui",mode:"webchat",onHello:t=>{e.connected=!0,e.lastError=null,e.hello=t,qh(e,t),yr(e),Nh(e),pn(e,{quiet:!0}),Te(e,{quiet:!0}),Qs(e)},onClose:({code:t,reason:n})=>{e.connected=!1,t!==1012&&(e.lastError=`disconnected (${t}): ${n||"no reason"}`)},onEvent:t=>zh(e,t),onGap:({expected:t,received:n})=>{e.lastError=`event gap detected (expected seq ${t}, got ${n}); refresh recommended`}}),e.client.start()}function zh(e,t){try{jh(e,t)}catch(n){console.error("[gateway] handleGatewayEvent error:",t.event,n)}}function jh(e,t){if(e.eventLogBuffer=[{ts:Date.now(),event:t.event,payload:t.payload},...e.eventLogBuffer].slice(0,250),e.tab==="debug"&&(e.eventLog=e.eventLogBuffer),t.event==="agent"){if(e.onboarding)return;Hl(e,t.payload);return}if(t.event==="chat"){const n=t.payload;n?.sessionKey&&Mo(e,n.sessionKey);const s=Ll(e,n);(s==="final"||s==="error"||s==="aborted")&&(Ns(e),$d(e)),s==="final"&&Xe(e);return}if(t.event==="presence"){const n=t.payload;n?.presence&&Array.isArray(n.presence)&&(e.presenceEntries=n.presence,e.presenceError=null,e.presenceStatus=null);return}if(t.event==="cron"&&e.tab==="cron"&&Zs(e),(t.event==="device.pair.requested"||t.event==="device.pair.resolved")&&Te(e,{quiet:!0}),t.event==="exec.approval.requested"){const n=Fh(t.payload);if(n){e.execApprovalQueue=Kh(e.execApprovalQueue,n),e.execApprovalError=null;const s=Math.max(0,n.expiresAtMs-Date.now()+500);window.setTimeout(()=>{e.execApprovalQueue=ja(e.execApprovalQueue,n.id)},s)}return}if(t.event==="exec.approval.resolved"){const n=Uh(t.payload);n&&(e.execApprovalQueue=ja(e.execApprovalQueue,n.id))}}function qh(e,t){const n=t.snapshot;n?.presence&&Array.isArray(n.presence)&&(e.presenceEntries=n.presence),n?.health&&(e.debugHealth=n.health),n?.sessionDefaults&&Hh(e,n.sessionDefaults)}function Vh(e){e.basePath=ld(),pd(e,!0),cd(e),dd(e),window.addEventListener("popstate",e.popStateHandler),ad(e),wr(e),sd(e),e.tab==="logs"&&Vs(e),e.tab==="debug"&&Gs(e)}function Wh(e){Wl(e)}function Gh(e){window.removeEventListener("popstate",e.popStateHandler),id(e),Ws(e),Ys(e),ud(e),e.topbarObserver?.disconnect(),e.topbarObserver=null}function Yh(e,t){if(e.tab==="chat"&&(t.has("chatMessages")||t.has("chatToolMessages")||t.has("chatStream")||t.has("chatLoading")||t.has("tab"))){const n=t.has("tab"),s=t.has("chatLoading")&&t.get("chatLoading")===!0&&e.chatLoading===!1;ln(e,n||s||!e.chatHasAutoScrolled)}e.tab==="logs"&&(t.has("logsEntries")||t.has("logsAutoFollow")||t.has("tab"))&&e.logsAutoFollow&&e.logsAtBottom&&ro(e,t.has("tab")||t.has("logsAutoFollow"))}async function Qh(e,t){await ic(e,t),await oe(e,!0)}async function Zh(e){await ac(e),await oe(e,!0)}async function Jh(e){await oc(e),await oe(e,!0)}async function Xh(e){await ls(e),await be(e),await oe(e,!0)}async function eg(e){await be(e),await oe(e,!0)}function tg(e){if(!Array.isArray(e))return{};const t={};for(const n of e){if(typeof n!="string")continue;const[s,...i]=n.split(":");if(!s||i.length===0)continue;const a=s.trim(),o=i.join(":").trim();a&&o&&(t[a]=o)}return t}function $r(e){return(e.channelsSnapshot?.channelAccounts?.nostr??[])[0]?.accountId??e.nostrProfileAccountId??"default"}function xr(e,t=""){return`/api/channels/nostr/${encodeURIComponent(e)}/profile${t}`}function ng(e,t,n){e.nostrProfileAccountId=t,e.nostrProfileFormState=Xp(n??void 0)}function sg(e){e.nostrProfileFormState=null,e.nostrProfileAccountId=null}function ig(e,t,n){const s=e.nostrProfileFormState;s&&(e.nostrProfileFormState={...s,values:{...s.values,[t]:n},fieldErrors:{...s.fieldErrors,[t]:""}})}function ag(e){const t=e.nostrProfileFormState;t&&(e.nostrProfileFormState={...t,showAdvanced:!t.showAdvanced})}async function og(e){const t=e.nostrProfileFormState;if(!t||t.saving)return;const n=$r(e);e.nostrProfileFormState={...t,saving:!0,error:null,success:null,fieldErrors:{}};try{const s=await fetch(xr(n),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t.values)}),i=await s.json().catch(()=>null);if(!s.ok||i?.ok===!1||!i){const a=i?.error??`Profile update failed (${s.status})`;e.nostrProfileFormState={...t,saving:!1,error:a,success:null,fieldErrors:tg(i?.details)};return}if(!i.persisted){e.nostrProfileFormState={...t,saving:!1,error:"Profile publish failed on all relays.",success:null};return}e.nostrProfileFormState={...t,saving:!1,error:null,success:"Profile published to relays.",fieldErrors:{},original:{...t.values}},await oe(e,!0)}catch(s){e.nostrProfileFormState={...t,saving:!1,error:`Profile update failed: ${String(s)}`,success:null}}}async function rg(e){const t=e.nostrProfileFormState;if(!t||t.importing)return;const n=$r(e);e.nostrProfileFormState={...t,importing:!0,error:null,success:null};try{const s=await fetch(xr(n,"/import"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({autoMerge:!0})}),i=await s.json().catch(()=>null);if(!s.ok||i?.ok===!1||!i){const l=i?.error??`Profile import failed (${s.status})`;e.nostrProfileFormState={...t,importing:!1,error:l,success:null};return}const a=i.merged??i.imported??null,o=a?{...t.values,...a}:t.values,c=!!(o.banner||o.website||o.nip05||o.lud16);e.nostrProfileFormState={...t,importing:!1,values:o,error:null,success:i.saved?"Profile imported from relays. Review and publish.":"Profile imported. Review and publish.",showAdvanced:c},i.saved&&await oe(e,!0)}catch(s){e.nostrProfileFormState={...t,importing:!1,error:`Profile import failed: ${String(s)}`,success:null}}}var lg=Object.defineProperty,cg=Object.getOwnPropertyDescriptor,b=(e,t,n,s)=>{for(var i=s>1?void 0:s?cg(t,n):t,a=e.length-1,o;a>=0;a--)(o=e[a])&&(i=(s?o(t,n,i):o(i))||i);return s&&i&&lg(t,n,i),i};const es=ul();function dg(){if(!window.location.search)return!1;const t=new URLSearchParams(window.location.search).get("onboarding");if(!t)return!1;const n=t.trim().toLowerCase();return n==="1"||n==="true"||n==="yes"||n==="on"}let m=class extends Ze{constructor(){super(...arguments),this.settings=pl(),this.password="",this.tab="chat",this.onboarding=dg(),this.connected=!1,this.theme=this.settings.theme??"system",this.themeResolved="dark",this.hello=null,this.lastError=null,this.eventLog=[],this.eventLogBuffer=[],this.toolStreamSyncTimer=null,this.sidebarCloseTimer=null,this.assistantName=es.name,this.assistantAvatar=es.avatar,this.assistantAgentId=es.agentId??null,this.sessionKey=this.settings.sessionKey,this.chatLoading=!1,this.chatSending=!1,this.chatMessage="",this.chatMessages=[],this.chatToolMessages=[],this.chatStream=null,this.chatStreamStartedAt=null,this.chatRunId=null,this.compactionStatus=null,this.chatAvatarUrl=null,this.chatThinkingLevel=null,this.chatQueue=[],this.sidebarOpen=!1,this.sidebarContent=null,this.sidebarError=null,this.splitRatio=this.settings.splitRatio,this.nodesLoading=!1,this.nodes=[],this.devicesLoading=!1,this.devicesError=null,this.devicesList=null,this.execApprovalsLoading=!1,this.execApprovalsSaving=!1,this.execApprovalsDirty=!1,this.execApprovalsSnapshot=null,this.execApprovalsForm=null,this.execApprovalsSelectedAgent=null,this.execApprovalsTarget="gateway",this.execApprovalsTargetNodeId=null,this.execApprovalQueue=[],this.execApprovalBusy=!1,this.execApprovalError=null,this.configLoading=!1,this.configRaw=`{ -} -`,this.configRawOriginal="",this.configValid=null,this.configIssues=[],this.configSaving=!1,this.configApplying=!1,this.updateRunning=!1,this.applySessionKey=this.settings.lastActiveSessionKey,this.configSnapshot=null,this.configSchema=null,this.configSchemaVersion=null,this.configSchemaLoading=!1,this.configUiHints={},this.configForm=null,this.configFormOriginal=null,this.configFormDirty=!1,this.configFormMode="form",this.configSearchQuery="",this.configActiveSection=null,this.configActiveSubsection=null,this.channelsLoading=!1,this.channelsSnapshot=null,this.channelsError=null,this.channelsLastSuccess=null,this.whatsappLoginMessage=null,this.whatsappLoginQrDataUrl=null,this.whatsappLoginConnected=null,this.whatsappBusy=!1,this.nostrProfileFormState=null,this.nostrProfileAccountId=null,this.presenceLoading=!1,this.presenceEntries=[],this.presenceError=null,this.presenceStatus=null,this.agentsLoading=!1,this.agentsList=null,this.agentsError=null,this.sessionsLoading=!1,this.sessionsResult=null,this.sessionsError=null,this.sessionsFilterActive="",this.sessionsFilterLimit="120",this.sessionsIncludeGlobal=!0,this.sessionsIncludeUnknown=!1,this.cronLoading=!1,this.cronJobs=[],this.cronStatus=null,this.cronError=null,this.cronForm={...Ph},this.cronRunsJobId=null,this.cronRuns=[],this.cronBusy=!1,this.skillsLoading=!1,this.skillsReport=null,this.skillsError=null,this.skillsFilter="",this.skillEdits={},this.skillsBusyKey=null,this.skillMessages={},this.debugLoading=!1,this.debugStatus=null,this.debugHealth=null,this.debugModels=[],this.debugHeartbeat=null,this.debugCallMethod="",this.debugCallParams="{}",this.debugCallResult=null,this.debugCallError=null,this.logsLoading=!1,this.logsError=null,this.logsFile=null,this.logsEntries=[],this.logsFilterText="",this.logsLevelFilters={...Rh},this.logsAutoFollow=!0,this.logsTruncated=!1,this.logsCursor=null,this.logsLastFetchAt=null,this.logsLimit=500,this.logsMaxBytes=25e4,this.logsAtBottom=!0,this.client=null,this.chatScrollFrame=null,this.chatScrollTimeout=null,this.chatHasAutoScrolled=!1,this.chatUserNearBottom=!0,this.nodesPollInterval=null,this.logsPollInterval=null,this.debugPollInterval=null,this.logsScrollFrame=null,this.toolStreamById=new Map,this.toolStreamOrder=[],this.basePath="",this.popStateHandler=()=>fd(this),this.themeMedia=null,this.themeMediaHandler=null,this.topbarObserver=null}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),Vh(this)}firstUpdated(){Wh(this)}disconnectedCallback(){Gh(this),super.disconnectedCallback()}updated(e){Yh(this,e)}connect(){wr(this)}handleChatScroll(e){zl(this,e)}handleLogsScroll(e){jl(this,e)}exportLogs(e,t){Vl(e,t)}resetToolStream(){Ns(this)}resetChatScroll(){ql(this)}async loadAssistantIdentity(){await yr(this)}applySettings(e){ke(this,e)}setTab(e){od(this,e)}setTheme(e,t){rd(this,e,t)}async loadOverview(){await Po(this)}async loadCron(){await Zs(this)}async handleAbortChat(){await Oo(this)}removeQueuedMessage(e){bd(this,e)}async handleSendChat(e,t){await yd(this,e,t)}async handleWhatsAppStart(e){await Qh(this,e)}async handleWhatsAppWait(){await Zh(this)}async handleWhatsAppLogout(){await Jh(this)}async handleChannelConfigSave(){await Xh(this)}async handleChannelConfigReload(){await eg(this)}handleNostrProfileEdit(e,t){ng(this,e,t)}handleNostrProfileCancel(){sg(this)}handleNostrProfileFieldChange(e,t){ig(this,e,t)}async handleNostrProfileSave(){await og(this)}async handleNostrProfileImport(){await rg(this)}handleNostrProfileToggleAdvanced(){ag(this)}async handleExecApprovalDecision(e){const t=this.execApprovalQueue[0];if(!(!t||!this.client||this.execApprovalBusy)){this.execApprovalBusy=!0,this.execApprovalError=null;try{await this.client.request("exec.approval.resolve",{id:t.id,decision:e}),this.execApprovalQueue=this.execApprovalQueue.filter(n=>n.id!==t.id)}catch(n){this.execApprovalError=`Exec approval failed: ${String(n)}`}finally{this.execApprovalBusy=!1}}}handleOpenSidebar(e){this.sidebarCloseTimer!=null&&(window.clearTimeout(this.sidebarCloseTimer),this.sidebarCloseTimer=null),this.sidebarContent=e,this.sidebarError=null,this.sidebarOpen=!0}handleCloseSidebar(){this.sidebarOpen=!1,this.sidebarCloseTimer!=null&&window.clearTimeout(this.sidebarCloseTimer),this.sidebarCloseTimer=window.setTimeout(()=>{this.sidebarOpen||(this.sidebarContent=null,this.sidebarError=null,this.sidebarCloseTimer=null)},200)}handleSplitRatioChange(e){const t=Math.max(.4,Math.min(.7,e));this.splitRatio=t,this.applySettings({...this.settings,splitRatio:t})}render(){return Ih(this)}};b([y()],m.prototype,"settings",2);b([y()],m.prototype,"password",2);b([y()],m.prototype,"tab",2);b([y()],m.prototype,"onboarding",2);b([y()],m.prototype,"connected",2);b([y()],m.prototype,"theme",2);b([y()],m.prototype,"themeResolved",2);b([y()],m.prototype,"hello",2);b([y()],m.prototype,"lastError",2);b([y()],m.prototype,"eventLog",2);b([y()],m.prototype,"assistantName",2);b([y()],m.prototype,"assistantAvatar",2);b([y()],m.prototype,"assistantAgentId",2);b([y()],m.prototype,"sessionKey",2);b([y()],m.prototype,"chatLoading",2);b([y()],m.prototype,"chatSending",2);b([y()],m.prototype,"chatMessage",2);b([y()],m.prototype,"chatMessages",2);b([y()],m.prototype,"chatToolMessages",2);b([y()],m.prototype,"chatStream",2);b([y()],m.prototype,"chatStreamStartedAt",2);b([y()],m.prototype,"chatRunId",2);b([y()],m.prototype,"compactionStatus",2);b([y()],m.prototype,"chatAvatarUrl",2);b([y()],m.prototype,"chatThinkingLevel",2);b([y()],m.prototype,"chatQueue",2);b([y()],m.prototype,"sidebarOpen",2);b([y()],m.prototype,"sidebarContent",2);b([y()],m.prototype,"sidebarError",2);b([y()],m.prototype,"splitRatio",2);b([y()],m.prototype,"nodesLoading",2);b([y()],m.prototype,"nodes",2);b([y()],m.prototype,"devicesLoading",2);b([y()],m.prototype,"devicesError",2);b([y()],m.prototype,"devicesList",2);b([y()],m.prototype,"execApprovalsLoading",2);b([y()],m.prototype,"execApprovalsSaving",2);b([y()],m.prototype,"execApprovalsDirty",2);b([y()],m.prototype,"execApprovalsSnapshot",2);b([y()],m.prototype,"execApprovalsForm",2);b([y()],m.prototype,"execApprovalsSelectedAgent",2);b([y()],m.prototype,"execApprovalsTarget",2);b([y()],m.prototype,"execApprovalsTargetNodeId",2);b([y()],m.prototype,"execApprovalQueue",2);b([y()],m.prototype,"execApprovalBusy",2);b([y()],m.prototype,"execApprovalError",2);b([y()],m.prototype,"configLoading",2);b([y()],m.prototype,"configRaw",2);b([y()],m.prototype,"configRawOriginal",2);b([y()],m.prototype,"configValid",2);b([y()],m.prototype,"configIssues",2);b([y()],m.prototype,"configSaving",2);b([y()],m.prototype,"configApplying",2);b([y()],m.prototype,"updateRunning",2);b([y()],m.prototype,"applySessionKey",2);b([y()],m.prototype,"configSnapshot",2);b([y()],m.prototype,"configSchema",2);b([y()],m.prototype,"configSchemaVersion",2);b([y()],m.prototype,"configSchemaLoading",2);b([y()],m.prototype,"configUiHints",2);b([y()],m.prototype,"configForm",2);b([y()],m.prototype,"configFormOriginal",2);b([y()],m.prototype,"configFormDirty",2);b([y()],m.prototype,"configFormMode",2);b([y()],m.prototype,"configSearchQuery",2);b([y()],m.prototype,"configActiveSection",2);b([y()],m.prototype,"configActiveSubsection",2);b([y()],m.prototype,"channelsLoading",2);b([y()],m.prototype,"channelsSnapshot",2);b([y()],m.prototype,"channelsError",2);b([y()],m.prototype,"channelsLastSuccess",2);b([y()],m.prototype,"whatsappLoginMessage",2);b([y()],m.prototype,"whatsappLoginQrDataUrl",2);b([y()],m.prototype,"whatsappLoginConnected",2);b([y()],m.prototype,"whatsappBusy",2);b([y()],m.prototype,"nostrProfileFormState",2);b([y()],m.prototype,"nostrProfileAccountId",2);b([y()],m.prototype,"presenceLoading",2);b([y()],m.prototype,"presenceEntries",2);b([y()],m.prototype,"presenceError",2);b([y()],m.prototype,"presenceStatus",2);b([y()],m.prototype,"agentsLoading",2);b([y()],m.prototype,"agentsList",2);b([y()],m.prototype,"agentsError",2);b([y()],m.prototype,"sessionsLoading",2);b([y()],m.prototype,"sessionsResult",2);b([y()],m.prototype,"sessionsError",2);b([y()],m.prototype,"sessionsFilterActive",2);b([y()],m.prototype,"sessionsFilterLimit",2);b([y()],m.prototype,"sessionsIncludeGlobal",2);b([y()],m.prototype,"sessionsIncludeUnknown",2);b([y()],m.prototype,"cronLoading",2);b([y()],m.prototype,"cronJobs",2);b([y()],m.prototype,"cronStatus",2);b([y()],m.prototype,"cronError",2);b([y()],m.prototype,"cronForm",2);b([y()],m.prototype,"cronRunsJobId",2);b([y()],m.prototype,"cronRuns",2);b([y()],m.prototype,"cronBusy",2);b([y()],m.prototype,"skillsLoading",2);b([y()],m.prototype,"skillsReport",2);b([y()],m.prototype,"skillsError",2);b([y()],m.prototype,"skillsFilter",2);b([y()],m.prototype,"skillEdits",2);b([y()],m.prototype,"skillsBusyKey",2);b([y()],m.prototype,"skillMessages",2);b([y()],m.prototype,"debugLoading",2);b([y()],m.prototype,"debugStatus",2);b([y()],m.prototype,"debugHealth",2);b([y()],m.prototype,"debugModels",2);b([y()],m.prototype,"debugHeartbeat",2);b([y()],m.prototype,"debugCallMethod",2);b([y()],m.prototype,"debugCallParams",2);b([y()],m.prototype,"debugCallResult",2);b([y()],m.prototype,"debugCallError",2);b([y()],m.prototype,"logsLoading",2);b([y()],m.prototype,"logsError",2);b([y()],m.prototype,"logsFile",2);b([y()],m.prototype,"logsEntries",2);b([y()],m.prototype,"logsFilterText",2);b([y()],m.prototype,"logsLevelFilters",2);b([y()],m.prototype,"logsAutoFollow",2);b([y()],m.prototype,"logsTruncated",2);b([y()],m.prototype,"logsCursor",2);b([y()],m.prototype,"logsLastFetchAt",2);b([y()],m.prototype,"logsLimit",2);b([y()],m.prototype,"logsMaxBytes",2);b([y()],m.prototype,"logsAtBottom",2);m=b([Ja("clawdbot-app")],m); -//# sourceMappingURL=index-DQcOTEYz.js.map diff --git a/dist/control-ui/assets/index-DQcOTEYz.js.map b/dist/control-ui/assets/index-DQcOTEYz.js.map deleted file mode 100644 index d48222472..000000000 --- a/dist/control-ui/assets/index-DQcOTEYz.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index-DQcOTEYz.js","sources":["../../../node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/css-tag.js","../../../node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/reactive-element.js","../../../node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/lit-html.js","../../../node_modules/.pnpm/lit-element@4.2.2/node_modules/lit-element/lit-element.js","../../../node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/custom-element.js","../../../node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/property.js","../../../node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/state.js","../../../ui/src/ui/assistant-identity.ts","../../../ui/src/ui/storage.ts","../../../src/sessions/session-key-utils.ts","../../../ui/src/ui/navigation.ts","../../../ui/src/ui/icons.ts","../../../src/shared/text/reasoning-tags.ts","../../../ui/src/ui/format.ts","../../../ui/src/ui/chat/message-extract.ts","../../../ui/src/ui/uuid.ts","../../../ui/src/ui/controllers/chat.ts","../../../ui/src/ui/controllers/sessions.ts","../../../ui/src/ui/app-tool-stream.ts","../../../ui/src/ui/app-scroll.ts","../../../ui/src/ui/controllers/config/form-utils.ts","../../../ui/src/ui/controllers/config.ts","../../../ui/src/ui/controllers/cron.ts","../../../ui/src/ui/controllers/channels.ts","../../../ui/src/ui/controllers/debug.ts","../../../ui/src/ui/controllers/logs.ts","../../../node_modules/.pnpm/@noble+ed25519@3.0.0/node_modules/@noble/ed25519/index.js","../../../ui/src/ui/device-identity.ts","../../../ui/src/ui/device-auth.ts","../../../ui/src/ui/controllers/devices.ts","../../../ui/src/ui/controllers/nodes.ts","../../../ui/src/ui/controllers/exec-approvals.ts","../../../ui/src/ui/controllers/presence.ts","../../../ui/src/ui/controllers/skills.ts","../../../ui/src/ui/theme.ts","../../../ui/src/ui/theme-transition.ts","../../../ui/src/ui/app-polling.ts","../../../ui/src/ui/app-settings.ts","../../../ui/src/ui/app-chat.ts","../../../node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directive.js","../../../node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directive-helpers.js","../../../node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directives/repeat.js","../../../ui/src/ui/chat/message-normalizer.ts","../../../node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directives/unsafe-html.js","../../../node_modules/.pnpm/dompurify@3.3.1/node_modules/dompurify/dist/purify.es.mjs","../../../node_modules/.pnpm/marked@17.0.1/node_modules/marked/lib/marked.esm.js","../../../ui/src/ui/markdown.ts","../../../ui/src/ui/chat/copy-as-markdown.ts","../../../ui/src/ui/tool-display.ts","../../../ui/src/ui/chat/constants.ts","../../../ui/src/ui/chat/tool-helpers.ts","../../../ui/src/ui/chat/tool-cards.ts","../../../ui/src/ui/chat/grouped-render.ts","../../../ui/src/ui/views/markdown-sidebar.ts","../../../ui/src/ui/components/resizable-divider.ts","../../../ui/src/ui/views/chat.ts","../../../ui/src/ui/views/config-form.shared.ts","../../../ui/src/ui/views/config-form.node.ts","../../../ui/src/ui/views/config-form.render.ts","../../../ui/src/ui/views/config-form.analyze.ts","../../../ui/src/ui/views/config.ts","../../../ui/src/ui/views/channels.shared.ts","../../../ui/src/ui/views/channels.config.ts","../../../ui/src/ui/views/channels.discord.ts","../../../ui/src/ui/views/channels.googlechat.ts","../../../ui/src/ui/views/channels.imessage.ts","../../../ui/src/ui/views/channels.nostr-profile-form.ts","../../../ui/src/ui/views/channels.nostr.ts","../../../ui/src/ui/views/channels.signal.ts","../../../ui/src/ui/views/channels.slack.ts","../../../ui/src/ui/views/channels.telegram.ts","../../../ui/src/ui/views/channels.whatsapp.ts","../../../ui/src/ui/views/channels.ts","../../../ui/src/ui/presenter.ts","../../../ui/src/ui/views/cron.ts","../../../ui/src/ui/views/debug.ts","../../../ui/src/ui/views/instances.ts","../../../ui/src/ui/views/logs.ts","../../../ui/src/ui/views/nodes.ts","../../../ui/src/ui/views/overview.ts","../../../ui/src/ui/views/sessions.ts","../../../ui/src/ui/views/exec-approval.ts","../../../ui/src/ui/views/skills.ts","../../../ui/src/ui/app-render.helpers.ts","../../../ui/src/ui/app-render.ts","../../../ui/src/ui/app-defaults.ts","../../../ui/src/ui/controllers/agents.ts","../../../src/gateway/protocol/client-info.ts","../../../src/gateway/device-auth.ts","../../../ui/src/ui/gateway.ts","../../../ui/src/ui/controllers/exec-approval.ts","../../../ui/src/ui/controllers/assistant-identity.ts","../../../ui/src/ui/app-gateway.ts","../../../ui/src/ui/app-lifecycle.ts","../../../ui/src/ui/app-channels.ts","../../../ui/src/ui/app.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&\"adoptedStyleSheets\"in Document.prototype&&\"replace\"in CSSStyleSheet.prototype,s=Symbol(),o=new WeakMap;class n{constructor(t,e,o){if(this._$cssResult$=!0,o!==s)throw Error(\"CSSResult is not constructable. Use `unsafeCSS` or `css` instead.\");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const s=this.t;if(e&&void 0===t){const e=void 0!==s&&1===s.length;e&&(t=o.get(s)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&o.set(s,t))}return t}toString(){return this.cssText}}const r=t=>new n(\"string\"==typeof t?t:t+\"\",void 0,s),i=(t,...e)=>{const o=1===t.length?t[0]:e.reduce((e,s,o)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if(\"number\"==typeof t)return t;throw Error(\"Value passed to 'css' function must be a 'css' function result: \"+t+\". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.\")})(s)+t[o+1],t[0]);return new n(o,t,s)},S=(s,o)=>{if(e)s.adoptedStyleSheets=o.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of o){const o=document.createElement(\"style\"),n=t.litNonce;void 0!==n&&o.setAttribute(\"nonce\",n),o.textContent=e.cssText,s.appendChild(o)}},c=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e=\"\";for(const s of t.cssRules)e+=s.cssText;return r(e)})(t):t;export{n as CSSResult,S as adoptStyles,i as css,c as getCompatibleStyle,e as supportsAdoptingStyleSheets,r as unsafeCSS};\n//# sourceMappingURL=css-tag.js.map\n","import{getCompatibleStyle as t,adoptStyles as s}from\"./css-tag.js\";export{CSSResult,css,supportsAdoptingStyleSheets,unsafeCSS}from\"./css-tag.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const{is:i,defineProperty:e,getOwnPropertyDescriptor:h,getOwnPropertyNames:r,getOwnPropertySymbols:o,getPrototypeOf:n}=Object,a=globalThis,c=a.trustedTypes,l=c?c.emptyScript:\"\",p=a.reactiveElementPolyfillSupport,d=(t,s)=>t,u={toAttribute(t,s){switch(s){case Boolean:t=t?l:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,s){let i=t;switch(s){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},f=(t,s)=>!i(t,s),b={attribute:!0,type:String,converter:u,reflect:!1,useDefault:!1,hasChanged:f};Symbol.metadata??=Symbol(\"metadata\"),a.litPropertyMetadata??=new WeakMap;class y extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,s=b){if(s.state&&(s.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((s=Object.create(s)).wrapped=!0),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),h=this.getPropertyDescriptor(t,i,s);void 0!==h&&e(this.prototype,t,h)}}static getPropertyDescriptor(t,s,i){const{get:e,set:r}=h(this.prototype,t)??{get(){return this[s]},set(t){this[s]=t}};return{get:e,set(s){const h=e?.call(this);r?.call(this,s),this.requestUpdate(t,h,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(d(\"elementProperties\")))return;const t=n(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(d(\"finalized\")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(d(\"properties\"))){const t=this.properties,s=[...r(t),...o(t)];for(const i of s)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const s=litPropertyMetadata.get(t);if(void 0!==s)for(const[t,i]of s)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,s]of this.elementProperties){const i=this._$Eu(t,s);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(s){const i=[];if(Array.isArray(s)){const e=new Set(s.flat(1/0).reverse());for(const s of e)i.unshift(t(s))}else void 0!==s&&i.push(t(s));return i}static _$Eu(t,s){const i=s.attribute;return!1===i?void 0:\"string\"==typeof i?i:\"string\"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return s(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,s,i){this._$AK(t,i)}_$ET(t,s){const i=this.constructor.elementProperties.get(t),e=this.constructor._$Eu(t,i);if(void 0!==e&&!0===i.reflect){const h=(void 0!==i.converter?.toAttribute?i.converter:u).toAttribute(s,i.type);this._$Em=t,null==h?this.removeAttribute(e):this.setAttribute(e,h),this._$Em=null}}_$AK(t,s){const i=this.constructor,e=i._$Eh.get(t);if(void 0!==e&&this._$Em!==e){const t=i.getPropertyOptions(e),h=\"function\"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:u;this._$Em=e;const r=h.fromAttribute(s,t.type);this[e]=r??this._$Ej?.get(e)??r,this._$Em=null}}requestUpdate(t,s,i,e=!1,h){if(void 0!==t){const r=this.constructor;if(!1===e&&(h=this[t]),i??=r.getPropertyOptions(t),!((i.hasChanged??f)(h,s)||i.useDefault&&i.reflect&&h===this._$Ej?.get(t)&&!this.hasAttribute(r._$Eu(t,i))))return;this.C(t,s,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,s,{useDefault:i,reflect:e,wrapped:h},r){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??s??this[t]),!0!==h||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||i||(s=void 0),this._$AL.set(t,s)),!0===e&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,s]of this._$Ep)this[t]=s;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[s,i]of t){const{wrapped:t}=i,e=this[s];!0!==t||this._$AL.has(s)||void 0===e||this.C(s,void 0,i,e)}}let t=!1;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(s)):this._$EM()}catch(s){throw t=!1,this._$EM(),s}t&&this._$AE(s)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}}y.elementStyles=[],y.shadowRootOptions={mode:\"open\"},y[d(\"elementProperties\")]=new Map,y[d(\"finalized\")]=new Map,p?.({ReactiveElement:y}),(a.reactiveElementVersions??=[]).push(\"2.1.2\");export{y as ReactiveElement,s as adoptStyles,u as defaultConverter,t as getCompatibleStyle,f as notEqual};\n//# sourceMappingURL=reactive-element.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=globalThis,i=t=>t,s=t.trustedTypes,e=s?s.createPolicy(\"lit-html\",{createHTML:t=>t}):void 0,h=\"$lit$\",o=`lit$${Math.random().toFixed(9).slice(2)}$`,n=\"?\"+o,r=`<${n}>`,l=document,c=()=>l.createComment(\"\"),a=t=>null===t||\"object\"!=typeof t&&\"function\"!=typeof t,u=Array.isArray,d=t=>u(t)||\"function\"==typeof t?.[Symbol.iterator],f=\"[ \\t\\n\\f\\r]\",v=/<(?:(!--|\\/[^a-zA-Z])|(\\/?[a-zA-Z][^>\\s]*)|(\\/?$))/g,_=/-->/g,m=/>/g,p=RegExp(`>|${f}(?:([^\\\\s\"'>=/]+)(${f}*=${f}*(?:[^ \\t\\n\\f\\r\"'\\`<>=]|(\"|')|))|$)`,\"g\"),g=/'/g,$=/\"/g,y=/^(?:script|style|textarea|title)$/i,x=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),b=x(1),w=x(2),T=x(3),E=Symbol.for(\"lit-noChange\"),A=Symbol.for(\"lit-nothing\"),C=new WeakMap,P=l.createTreeWalker(l,129);function V(t,i){if(!u(t)||!t.hasOwnProperty(\"raw\"))throw Error(\"invalid template strings array\");return void 0!==e?e.createHTML(i):i}const N=(t,i)=>{const s=t.length-1,e=[];let n,l=2===i?\"\":3===i?\"\":\"\",c=v;for(let i=0;i\"===u[0]?(c=n??v,d=-1):void 0===u[1]?d=-2:(d=c.lastIndex-u[2].length,a=u[1],c=void 0===u[3]?p:'\"'===u[3]?$:g):c===$||c===g?c=p:c===_||c===m?c=v:(c=p,n=void 0);const x=c===p&&t[i+1].startsWith(\"/>\")?\" \":\"\";l+=c===v?s+r:d>=0?(e.push(a),s.slice(0,d)+h+s.slice(d)+o+x):s+o+(-2===d?i:x)}return[V(t,l+(t[s]||\"\")+(2===i?\"\":3===i?\"\":\"\")),e]};class S{constructor({strings:t,_$litType$:i},e){let r;this.parts=[];let l=0,a=0;const u=t.length-1,d=this.parts,[f,v]=N(t,i);if(this.el=S.createElement(f,e),P.currentNode=this.el.content,2===i||3===i){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(r=P.nextNode())&&d.length0){r.textContent=s?s.emptyScript:\"\";for(let s=0;s2||\"\"!==s[0]||\"\"!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=A}_$AI(t,i=this,s,e){const h=this.strings;let o=!1;if(void 0===h)t=M(this,t,i,0),o=!a(t)||t!==this._$AH&&t!==E,o&&(this._$AH=t);else{const e=t;let n,r;for(t=h[0],n=0;n{const e=s?.renderBefore??i;let h=e._$litPart$;if(void 0===h){const t=s?.renderBefore??null;e._$litPart$=h=new k(i.insertBefore(c(),t),t,void 0,s??{})}return h._$AI(t),h};export{j as _$LH,b as html,T as mathml,E as noChange,A as nothing,D as render,w as svg};\n//# sourceMappingURL=lit-html.js.map\n","import{ReactiveElement as t}from\"@lit/reactive-element\";export*from\"@lit/reactive-element\";import{render as e,noChange as r}from\"lit-html\";export*from\"lit-html\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const s=globalThis;class i extends t{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const r=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=e(r,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return r}}i._$litElement$=!0,i[\"finalized\"]=!0,s.litElementHydrateSupport?.({LitElement:i});const o=s.litElementPolyfillSupport;o?.({LitElement:i});const n={_$AK:(t,e,r)=>{t._$AK(e,r)},_$AL:t=>t._$AL};(s.litElementVersions??=[]).push(\"4.2.2\");export{i as LitElement,n as _$LE};\n//# sourceMappingURL=lit-element.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=t=>(e,o)=>{void 0!==o?o.addInitializer(()=>{customElements.define(t,e)}):customElements.define(t,e)};export{t as customElement};\n//# sourceMappingURL=custom-element.js.map\n","import{notEqual as t,defaultConverter as e}from\"../reactive-element.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const o={attribute:!0,type:String,converter:e,reflect:!1,hasChanged:t},r=(t=o,e,r)=>{const{kind:n,metadata:i}=r;let s=globalThis.litPropertyMetadata.get(i);if(void 0===s&&globalThis.litPropertyMetadata.set(i,s=new Map),\"setter\"===n&&((t=Object.create(t)).wrapped=!0),s.set(r.name,t),\"accessor\"===n){const{name:o}=r;return{set(r){const n=e.get.call(this);e.set.call(this,r),this.requestUpdate(o,n,t,!0,r)},init(e){return void 0!==e&&this.C(o,void 0,t,e),e}}}if(\"setter\"===n){const{name:o}=r;return function(r){const n=this[o];e.call(this,r),this.requestUpdate(o,n,t,!0,r)}}throw Error(\"Unsupported decorator location: \"+n)};function n(t){return(e,o)=>\"object\"==typeof o?r(t,e,o):((t,e,o)=>{const r=e.hasOwnProperty(o);return e.constructor.createProperty(o,t),r?Object.getOwnPropertyDescriptor(e,o):void 0})(t,e,o)}export{n as property,r as standardProperty};\n//# sourceMappingURL=property.js.map\n","import{property as t}from\"./property.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */function r(r){return t({...r,state:!0,attribute:!1})}export{r as state};\n//# sourceMappingURL=state.js.map\n","const MAX_ASSISTANT_NAME = 50;\nconst MAX_ASSISTANT_AVATAR = 200;\n\nexport const DEFAULT_ASSISTANT_NAME = \"Assistant\";\nexport const DEFAULT_ASSISTANT_AVATAR = \"A\";\n\nexport type AssistantIdentity = {\n agentId?: string | null;\n name: string;\n avatar: string | null;\n};\n\ndeclare global {\n interface Window {\n __CLAWDBOT_ASSISTANT_NAME__?: string;\n __CLAWDBOT_ASSISTANT_AVATAR__?: string;\n }\n}\n\nfunction coerceIdentityValue(value: string | undefined, maxLength: number): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n if (trimmed.length <= maxLength) return trimmed;\n return trimmed.slice(0, maxLength);\n}\n\nexport function normalizeAssistantIdentity(\n input?: Partial | null,\n): AssistantIdentity {\n const name =\n coerceIdentityValue(input?.name, MAX_ASSISTANT_NAME) ?? DEFAULT_ASSISTANT_NAME;\n const avatar = coerceIdentityValue(input?.avatar ?? undefined, MAX_ASSISTANT_AVATAR) ?? null;\n const agentId =\n typeof input?.agentId === \"string\" && input.agentId.trim()\n ? input.agentId.trim()\n : null;\n return { agentId, name, avatar };\n}\n\nexport function resolveInjectedAssistantIdentity(): AssistantIdentity {\n if (typeof window === \"undefined\") {\n return normalizeAssistantIdentity({});\n }\n return normalizeAssistantIdentity({\n name: window.__CLAWDBOT_ASSISTANT_NAME__,\n avatar: window.__CLAWDBOT_ASSISTANT_AVATAR__,\n });\n}\n","const KEY = \"clawdbot.control.settings.v1\";\n\nimport type { ThemeMode } from \"./theme\";\n\nexport type UiSettings = {\n gatewayUrl: string;\n token: string;\n sessionKey: string;\n lastActiveSessionKey: string;\n theme: ThemeMode;\n chatFocusMode: boolean;\n chatShowThinking: boolean;\n splitRatio: number; // Sidebar split ratio (0.4 to 0.7, default 0.6)\n navCollapsed: boolean; // Collapsible sidebar state\n navGroupsCollapsed: Record; // Which nav groups are collapsed\n};\n\nexport function loadSettings(): UiSettings {\n const defaultUrl = (() => {\n const proto = location.protocol === \"https:\" ? \"wss\" : \"ws\";\n return `${proto}://${location.host}`;\n })();\n\n const defaults: UiSettings = {\n gatewayUrl: defaultUrl,\n token: \"\",\n sessionKey: \"main\",\n lastActiveSessionKey: \"main\",\n theme: \"system\",\n chatFocusMode: false,\n chatShowThinking: true,\n splitRatio: 0.6,\n navCollapsed: false,\n navGroupsCollapsed: {},\n };\n\n try {\n const raw = localStorage.getItem(KEY);\n if (!raw) return defaults;\n const parsed = JSON.parse(raw) as Partial;\n return {\n gatewayUrl:\n typeof parsed.gatewayUrl === \"string\" && parsed.gatewayUrl.trim()\n ? parsed.gatewayUrl.trim()\n : defaults.gatewayUrl,\n token: typeof parsed.token === \"string\" ? parsed.token : defaults.token,\n sessionKey:\n typeof parsed.sessionKey === \"string\" && parsed.sessionKey.trim()\n ? parsed.sessionKey.trim()\n : defaults.sessionKey,\n lastActiveSessionKey:\n typeof parsed.lastActiveSessionKey === \"string\" &&\n parsed.lastActiveSessionKey.trim()\n ? parsed.lastActiveSessionKey.trim()\n : (typeof parsed.sessionKey === \"string\" &&\n parsed.sessionKey.trim()) ||\n defaults.lastActiveSessionKey,\n theme:\n parsed.theme === \"light\" ||\n parsed.theme === \"dark\" ||\n parsed.theme === \"system\"\n ? parsed.theme\n : defaults.theme,\n chatFocusMode:\n typeof parsed.chatFocusMode === \"boolean\"\n ? parsed.chatFocusMode\n : defaults.chatFocusMode,\n chatShowThinking:\n typeof parsed.chatShowThinking === \"boolean\"\n ? parsed.chatShowThinking\n : defaults.chatShowThinking,\n splitRatio:\n typeof parsed.splitRatio === \"number\" &&\n parsed.splitRatio >= 0.4 &&\n parsed.splitRatio <= 0.7\n ? parsed.splitRatio\n : defaults.splitRatio,\n navCollapsed:\n typeof parsed.navCollapsed === \"boolean\"\n ? parsed.navCollapsed\n : defaults.navCollapsed,\n navGroupsCollapsed:\n typeof parsed.navGroupsCollapsed === \"object\" &&\n parsed.navGroupsCollapsed !== null\n ? parsed.navGroupsCollapsed\n : defaults.navGroupsCollapsed,\n };\n } catch {\n return defaults;\n }\n}\n\nexport function saveSettings(next: UiSettings) {\n localStorage.setItem(KEY, JSON.stringify(next));\n}\n","export type ParsedAgentSessionKey = {\n agentId: string;\n rest: string;\n};\n\nexport function parseAgentSessionKey(\n sessionKey: string | undefined | null,\n): ParsedAgentSessionKey | null {\n const raw = (sessionKey ?? \"\").trim();\n if (!raw) return null;\n const parts = raw.split(\":\").filter(Boolean);\n if (parts.length < 3) return null;\n if (parts[0] !== \"agent\") return null;\n const agentId = parts[1]?.trim();\n const rest = parts.slice(2).join(\":\");\n if (!agentId || !rest) return null;\n return { agentId, rest };\n}\n\nexport function isSubagentSessionKey(sessionKey: string | undefined | null): boolean {\n const raw = (sessionKey ?? \"\").trim();\n if (!raw) return false;\n if (raw.toLowerCase().startsWith(\"subagent:\")) return true;\n const parsed = parseAgentSessionKey(raw);\n return Boolean((parsed?.rest ?? \"\").toLowerCase().startsWith(\"subagent:\"));\n}\n\nexport function isAcpSessionKey(sessionKey: string | undefined | null): boolean {\n const raw = (sessionKey ?? \"\").trim();\n if (!raw) return false;\n const normalized = raw.toLowerCase();\n if (normalized.startsWith(\"acp:\")) return true;\n const parsed = parseAgentSessionKey(raw);\n return Boolean((parsed?.rest ?? \"\").toLowerCase().startsWith(\"acp:\"));\n}\n\nconst THREAD_SESSION_MARKERS = [\":thread:\", \":topic:\"];\n\nexport function resolveThreadParentSessionKey(\n sessionKey: string | undefined | null,\n): string | null {\n const raw = (sessionKey ?? \"\").trim();\n if (!raw) return null;\n const normalized = raw.toLowerCase();\n let idx = -1;\n for (const marker of THREAD_SESSION_MARKERS) {\n const candidate = normalized.lastIndexOf(marker);\n if (candidate > idx) idx = candidate;\n }\n if (idx <= 0) return null;\n const parent = raw.slice(0, idx).trim();\n return parent ? parent : null;\n}\n","import type { IconName } from \"./icons.js\";\n\nexport const TAB_GROUPS = [\n { label: \"Chat\", tabs: [\"chat\"] },\n {\n label: \"Control\",\n tabs: [\"overview\", \"channels\", \"instances\", \"sessions\", \"cron\"],\n },\n { label: \"Agent\", tabs: [\"skills\", \"nodes\"] },\n { label: \"Settings\", tabs: [\"config\", \"debug\", \"logs\"] },\n] as const;\n\nexport type Tab =\n | \"overview\"\n | \"channels\"\n | \"instances\"\n | \"sessions\"\n | \"cron\"\n | \"skills\"\n | \"nodes\"\n | \"chat\"\n | \"config\"\n | \"debug\"\n | \"logs\";\n\nconst TAB_PATHS: Record = {\n overview: \"/overview\",\n channels: \"/channels\",\n instances: \"/instances\",\n sessions: \"/sessions\",\n cron: \"/cron\",\n skills: \"/skills\",\n nodes: \"/nodes\",\n chat: \"/chat\",\n config: \"/config\",\n debug: \"/debug\",\n logs: \"/logs\",\n};\n\nconst PATH_TO_TAB = new Map(\n Object.entries(TAB_PATHS).map(([tab, path]) => [path, tab as Tab]),\n);\n\nexport function normalizeBasePath(basePath: string): string {\n if (!basePath) return \"\";\n let base = basePath.trim();\n if (!base.startsWith(\"/\")) base = `/${base}`;\n if (base === \"/\") return \"\";\n if (base.endsWith(\"/\")) base = base.slice(0, -1);\n return base;\n}\n\nexport function normalizePath(path: string): string {\n if (!path) return \"/\";\n let normalized = path.trim();\n if (!normalized.startsWith(\"/\")) normalized = `/${normalized}`;\n if (normalized.length > 1 && normalized.endsWith(\"/\")) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\n\nexport function pathForTab(tab: Tab, basePath = \"\"): string {\n const base = normalizeBasePath(basePath);\n const path = TAB_PATHS[tab];\n return base ? `${base}${path}` : path;\n}\n\nexport function tabFromPath(pathname: string, basePath = \"\"): Tab | null {\n const base = normalizeBasePath(basePath);\n let path = pathname || \"/\";\n if (base) {\n if (path === base) {\n path = \"/\";\n } else if (path.startsWith(`${base}/`)) {\n path = path.slice(base.length);\n }\n }\n let normalized = normalizePath(path).toLowerCase();\n if (normalized.endsWith(\"/index.html\")) normalized = \"/\";\n if (normalized === \"/\") return \"chat\";\n return PATH_TO_TAB.get(normalized) ?? null;\n}\n\nexport function inferBasePathFromPathname(pathname: string): string {\n let normalized = normalizePath(pathname);\n if (normalized.endsWith(\"/index.html\")) {\n normalized = normalizePath(normalized.slice(0, -\"/index.html\".length));\n }\n if (normalized === \"/\") return \"\";\n const segments = normalized.split(\"/\").filter(Boolean);\n if (segments.length === 0) return \"\";\n for (let i = 0; i < segments.length; i++) {\n const candidate = `/${segments.slice(i).join(\"/\")}`.toLowerCase();\n if (PATH_TO_TAB.has(candidate)) {\n const prefix = segments.slice(0, i);\n return prefix.length ? `/${prefix.join(\"/\")}` : \"\";\n }\n }\n return `/${segments.join(\"/\")}`;\n}\n\nexport function iconForTab(tab: Tab): IconName {\n switch (tab) {\n case \"chat\":\n return \"messageSquare\";\n case \"overview\":\n return \"barChart\";\n case \"channels\":\n return \"link\";\n case \"instances\":\n return \"radio\";\n case \"sessions\":\n return \"fileText\";\n case \"cron\":\n return \"loader\";\n case \"skills\":\n return \"zap\";\n case \"nodes\":\n return \"monitor\";\n case \"config\":\n return \"settings\";\n case \"debug\":\n return \"bug\";\n case \"logs\":\n return \"scrollText\";\n default:\n return \"folder\";\n }\n}\n\nexport function titleForTab(tab: Tab) {\n switch (tab) {\n case \"overview\":\n return \"Overview\";\n case \"channels\":\n return \"Channels\";\n case \"instances\":\n return \"Instances\";\n case \"sessions\":\n return \"Sessions\";\n case \"cron\":\n return \"Cron Jobs\";\n case \"skills\":\n return \"Skills\";\n case \"nodes\":\n return \"Nodes\";\n case \"chat\":\n return \"Chat\";\n case \"config\":\n return \"Config\";\n case \"debug\":\n return \"Debug\";\n case \"logs\":\n return \"Logs\";\n default:\n return \"Control\";\n }\n}\n\nexport function subtitleForTab(tab: Tab) {\n switch (tab) {\n case \"overview\":\n return \"Gateway status, entry points, and a fast health read.\";\n case \"channels\":\n return \"Manage channels and settings.\";\n case \"instances\":\n return \"Presence beacons from connected clients and nodes.\";\n case \"sessions\":\n return \"Inspect active sessions and adjust per-session defaults.\";\n case \"cron\":\n return \"Schedule wakeups and recurring agent runs.\";\n case \"skills\":\n return \"Manage skill availability and API key injection.\";\n case \"nodes\":\n return \"Paired devices, capabilities, and command exposure.\";\n case \"chat\":\n return \"Direct gateway chat session for quick interventions.\";\n case \"config\":\n return \"Edit ~/.clawdbot/clawdbot.json safely.\";\n case \"debug\":\n return \"Gateway snapshots, events, and manual RPC calls.\";\n case \"logs\":\n return \"Live tail of the gateway file logs.\";\n default:\n return \"\";\n }\n}\n","import { html, type TemplateResult } from \"lit\";\n\n// Lucide-style SVG icons\n// All icons use currentColor for stroke\n\nexport const icons = {\n // Navigation icons\n messageSquare: html``,\n barChart: html``,\n link: html``,\n radio: html``,\n fileText: html``,\n zap: html``,\n monitor: html``,\n settings: html``,\n bug: html``,\n scrollText: html``,\n folder: html``,\n\n // UI icons\n menu: html``,\n x: html``,\n check: html``,\n copy: html``,\n search: html``,\n brain: html``,\n book: html``,\n loader: html``,\n\n // Tool icons\n wrench: html``,\n fileCode: html``,\n edit: html``,\n penLine: html``,\n paperclip: html``,\n globe: html``,\n image: html``,\n smartphone: html``,\n plug: html``,\n circle: html``,\n puzzle: html``,\n} as const;\n\nexport type IconName = keyof typeof icons;\n\nexport function icon(name: IconName): TemplateResult {\n return icons[name];\n}\n\nexport function renderIcon(name: IconName, className = \"nav-item__icon\"): TemplateResult {\n return html`${icons[name]}`;\n}\n\n// Legacy function for compatibility\nexport function renderEmojiIcon(iconContent: string | TemplateResult, className: string): TemplateResult {\n return html`${iconContent}`;\n}\n\nexport function setEmojiIcon(target: HTMLElement | null, icon: string): void {\n if (!target) return;\n target.textContent = icon;\n}\n","export type ReasoningTagMode = \"strict\" | \"preserve\";\nexport type ReasoningTagTrim = \"none\" | \"start\" | \"both\";\n\nconst QUICK_TAG_RE = /<\\s*\\/?\\s*(?:think(?:ing)?|thought|antthinking|final)\\b/i;\nconst FINAL_TAG_RE = /<\\s*\\/?\\s*final\\b[^>]*>/gi;\nconst THINKING_TAG_RE = /<\\s*(\\/?)\\s*(?:think(?:ing)?|thought|antthinking)\\b[^>]*>/gi;\n\nfunction applyTrim(value: string, mode: ReasoningTagTrim): string {\n if (mode === \"none\") return value;\n if (mode === \"start\") return value.trimStart();\n return value.trim();\n}\n\nexport function stripReasoningTagsFromText(\n text: string,\n options?: {\n mode?: ReasoningTagMode;\n trim?: ReasoningTagTrim;\n },\n): string {\n if (!text) return text;\n if (!QUICK_TAG_RE.test(text)) return text;\n\n const mode = options?.mode ?? \"strict\";\n const trimMode = options?.trim ?? \"both\";\n\n let cleaned = text;\n if (FINAL_TAG_RE.test(cleaned)) {\n FINAL_TAG_RE.lastIndex = 0;\n cleaned = cleaned.replace(FINAL_TAG_RE, \"\");\n } else {\n FINAL_TAG_RE.lastIndex = 0;\n }\n\n THINKING_TAG_RE.lastIndex = 0;\n let result = \"\";\n let lastIndex = 0;\n let inThinking = false;\n\n for (const match of cleaned.matchAll(THINKING_TAG_RE)) {\n const idx = match.index ?? 0;\n const isClose = match[1] === \"/\";\n\n if (!inThinking) {\n result += cleaned.slice(lastIndex, idx);\n if (!isClose) {\n inThinking = true;\n }\n } else if (isClose) {\n inThinking = false;\n }\n\n lastIndex = idx + match[0].length;\n }\n\n if (!inThinking || mode === \"preserve\") {\n result += cleaned.slice(lastIndex);\n }\n\n return applyTrim(result, trimMode);\n}\n","import { stripReasoningTagsFromText } from \"../../../src/shared/text/reasoning-tags.js\";\n\nexport function formatMs(ms?: number | null): string {\n if (!ms && ms !== 0) return \"n/a\";\n return new Date(ms).toLocaleString();\n}\n\nexport function formatAgo(ms?: number | null): string {\n if (!ms && ms !== 0) return \"n/a\";\n const diff = Date.now() - ms;\n if (diff < 0) return \"just now\";\n const sec = Math.round(diff / 1000);\n if (sec < 60) return `${sec}s ago`;\n const min = Math.round(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.round(min / 60);\n if (hr < 48) return `${hr}h ago`;\n const day = Math.round(hr / 24);\n return `${day}d ago`;\n}\n\nexport function formatDurationMs(ms?: number | null): string {\n if (!ms && ms !== 0) return \"n/a\";\n if (ms < 1000) return `${ms}ms`;\n const sec = Math.round(ms / 1000);\n if (sec < 60) return `${sec}s`;\n const min = Math.round(sec / 60);\n if (min < 60) return `${min}m`;\n const hr = Math.round(min / 60);\n if (hr < 48) return `${hr}h`;\n const day = Math.round(hr / 24);\n return `${day}d`;\n}\n\nexport function formatList(values?: Array): string {\n if (!values || values.length === 0) return \"none\";\n return values.filter((v): v is string => Boolean(v && v.trim())).join(\", \");\n}\n\nexport function clampText(value: string, max = 120): string {\n if (value.length <= max) return value;\n return `${value.slice(0, Math.max(0, max - 1))}…`;\n}\n\nexport function truncateText(value: string, max: number): {\n text: string;\n truncated: boolean;\n total: number;\n} {\n if (value.length <= max) {\n return { text: value, truncated: false, total: value.length };\n }\n return {\n text: value.slice(0, Math.max(0, max)),\n truncated: true,\n total: value.length,\n };\n}\n\nexport function toNumber(value: string, fallback: number): number {\n const n = Number(value);\n return Number.isFinite(n) ? n : fallback;\n}\n\nexport function parseList(input: string): string[] {\n return input\n .split(/[,\\n]/)\n .map((v) => v.trim())\n .filter((v) => v.length > 0);\n}\n\nexport function stripThinkingTags(value: string): string {\n return stripReasoningTagsFromText(value, { mode: \"preserve\", trim: \"start\" });\n}\n","import { stripThinkingTags } from \"../format\";\n\nconst ENVELOPE_PREFIX = /^\\[([^\\]]+)\\]\\s*/;\nconst ENVELOPE_CHANNELS = [\n \"WebChat\",\n \"WhatsApp\",\n \"Telegram\",\n \"Signal\",\n \"Slack\",\n \"Discord\",\n \"iMessage\",\n \"Teams\",\n \"Matrix\",\n \"Zalo\",\n \"Zalo Personal\",\n \"BlueBubbles\",\n];\n\nconst textCache = new WeakMap();\nconst thinkingCache = new WeakMap();\n\nfunction looksLikeEnvelopeHeader(header: string): boolean {\n if (/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}Z\\b/.test(header)) return true;\n if (/\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}\\b/.test(header)) return true;\n return ENVELOPE_CHANNELS.some((label) => header.startsWith(`${label} `));\n}\n\nexport function stripEnvelope(text: string): string {\n const match = text.match(ENVELOPE_PREFIX);\n if (!match) return text;\n const header = match[1] ?? \"\";\n if (!looksLikeEnvelopeHeader(header)) return text;\n return text.slice(match[0].length);\n}\n\nexport function extractText(message: unknown): string | null {\n const m = message as Record;\n const role = typeof m.role === \"string\" ? m.role : \"\";\n const content = m.content;\n if (typeof content === \"string\") {\n const processed = role === \"assistant\" ? stripThinkingTags(content) : stripEnvelope(content);\n return processed;\n }\n if (Array.isArray(content)) {\n const parts = content\n .map((p) => {\n const item = p as Record;\n if (item.type === \"text\" && typeof item.text === \"string\") return item.text;\n return null;\n })\n .filter((v): v is string => typeof v === \"string\");\n if (parts.length > 0) {\n const joined = parts.join(\"\\n\");\n const processed = role === \"assistant\" ? stripThinkingTags(joined) : stripEnvelope(joined);\n return processed;\n }\n }\n if (typeof m.text === \"string\") {\n const processed = role === \"assistant\" ? stripThinkingTags(m.text) : stripEnvelope(m.text);\n return processed;\n }\n return null;\n}\n\nexport function extractTextCached(message: unknown): string | null {\n if (!message || typeof message !== \"object\") return extractText(message);\n const obj = message as object;\n if (textCache.has(obj)) return textCache.get(obj) ?? null;\n const value = extractText(message);\n textCache.set(obj, value);\n return value;\n}\n\nexport function extractThinking(message: unknown): string | null {\n const m = message as Record;\n const content = m.content;\n const parts: string[] = [];\n if (Array.isArray(content)) {\n for (const p of content) {\n const item = p as Record;\n if (item.type === \"thinking\" && typeof item.thinking === \"string\") {\n const cleaned = item.thinking.trim();\n if (cleaned) parts.push(cleaned);\n }\n }\n }\n if (parts.length > 0) return parts.join(\"\\n\");\n\n // Back-compat: older logs may still have tags inside text blocks.\n const rawText = extractRawText(message);\n if (!rawText) return null;\n const matches = [\n ...rawText.matchAll(\n /<\\s*think(?:ing)?\\s*>([\\s\\S]*?)<\\s*\\/\\s*think(?:ing)?\\s*>/gi,\n ),\n ];\n const extracted = matches\n .map((m) => (m[1] ?? \"\").trim())\n .filter(Boolean);\n return extracted.length > 0 ? extracted.join(\"\\n\") : null;\n}\n\nexport function extractThinkingCached(message: unknown): string | null {\n if (!message || typeof message !== \"object\") return extractThinking(message);\n const obj = message as object;\n if (thinkingCache.has(obj)) return thinkingCache.get(obj) ?? null;\n const value = extractThinking(message);\n thinkingCache.set(obj, value);\n return value;\n}\n\nexport function extractRawText(message: unknown): string | null {\n const m = message as Record;\n const content = m.content;\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n const parts = content\n .map((p) => {\n const item = p as Record;\n if (item.type === \"text\" && typeof item.text === \"string\") return item.text;\n return null;\n })\n .filter((v): v is string => typeof v === \"string\");\n if (parts.length > 0) return parts.join(\"\\n\");\n }\n if (typeof m.text === \"string\") return m.text;\n return null;\n}\n\nexport function formatReasoningMarkdown(text: string): string {\n const trimmed = text.trim();\n if (!trimmed) return \"\";\n const lines = trimmed\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => `_${line}_`);\n return lines.length ? [\"_Reasoning:_\", ...lines].join(\"\\n\") : \"\";\n}\n","export type CryptoLike = {\n randomUUID?: (() => string) | undefined;\n getRandomValues?: ((array: Uint8Array) => Uint8Array) | undefined;\n};\n\nfunction uuidFromBytes(bytes: Uint8Array): string {\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 1\n\n let hex = \"\";\n for (let i = 0; i < bytes.length; i++) {\n hex += bytes[i]!.toString(16).padStart(2, \"0\");\n }\n\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(\n 16,\n 20,\n )}-${hex.slice(20)}`;\n}\n\nfunction weakRandomBytes(): Uint8Array {\n const bytes = new Uint8Array(16);\n const now = Date.now();\n for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);\n bytes[0] ^= now & 0xff;\n bytes[1] ^= (now >>> 8) & 0xff;\n bytes[2] ^= (now >>> 16) & 0xff;\n bytes[3] ^= (now >>> 24) & 0xff;\n return bytes;\n}\n\nexport function generateUUID(cryptoLike: CryptoLike | null = globalThis.crypto): string {\n if (cryptoLike && typeof cryptoLike.randomUUID === \"function\") return cryptoLike.randomUUID();\n\n if (cryptoLike && typeof cryptoLike.getRandomValues === \"function\") {\n const bytes = new Uint8Array(16);\n cryptoLike.getRandomValues(bytes);\n return uuidFromBytes(bytes);\n }\n\n return uuidFromBytes(weakRandomBytes());\n}\n\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport { extractText } from \"../chat/message-extract\";\nimport { generateUUID } from \"../uuid\";\n\nexport type ChatState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n sessionKey: string;\n chatLoading: boolean;\n chatMessages: unknown[];\n chatThinkingLevel: string | null;\n chatSending: boolean;\n chatMessage: string;\n chatRunId: string | null;\n chatStream: string | null;\n chatStreamStartedAt: number | null;\n lastError: string | null;\n};\n\nexport type ChatEventPayload = {\n runId: string;\n sessionKey: string;\n state: \"delta\" | \"final\" | \"aborted\" | \"error\";\n message?: unknown;\n errorMessage?: string;\n};\n\nexport async function loadChatHistory(state: ChatState) {\n if (!state.client || !state.connected) return;\n state.chatLoading = true;\n state.lastError = null;\n try {\n const res = (await state.client.request(\"chat.history\", {\n sessionKey: state.sessionKey,\n limit: 200,\n })) as { messages?: unknown[]; thinkingLevel?: string | null };\n state.chatMessages = Array.isArray(res.messages) ? res.messages : [];\n state.chatThinkingLevel = res.thinkingLevel ?? null;\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.chatLoading = false;\n }\n}\n\nexport async function sendChatMessage(state: ChatState, message: string): Promise {\n if (!state.client || !state.connected) return false;\n const msg = message.trim();\n if (!msg) return false;\n\n const now = Date.now();\n state.chatMessages = [\n ...state.chatMessages,\n {\n role: \"user\",\n content: [{ type: \"text\", text: msg }],\n timestamp: now,\n },\n ];\n\n state.chatSending = true;\n state.lastError = null;\n const runId = generateUUID();\n state.chatRunId = runId;\n state.chatStream = \"\";\n state.chatStreamStartedAt = now;\n try {\n await state.client.request(\"chat.send\", {\n sessionKey: state.sessionKey,\n message: msg,\n deliver: false,\n idempotencyKey: runId,\n });\n return true;\n } catch (err) {\n const error = String(err);\n state.chatRunId = null;\n state.chatStream = null;\n state.chatStreamStartedAt = null;\n state.lastError = error;\n state.chatMessages = [\n ...state.chatMessages,\n {\n role: \"assistant\",\n content: [{ type: \"text\", text: \"Error: \" + error }],\n timestamp: Date.now(),\n },\n ];\n return false;\n } finally {\n state.chatSending = false;\n }\n}\n\nexport async function abortChatRun(state: ChatState): Promise {\n if (!state.client || !state.connected) return false;\n const runId = state.chatRunId;\n try {\n await state.client.request(\n \"chat.abort\",\n runId\n ? { sessionKey: state.sessionKey, runId }\n : { sessionKey: state.sessionKey },\n );\n return true;\n } catch (err) {\n state.lastError = String(err);\n return false;\n }\n}\n\nexport function handleChatEvent(\n state: ChatState,\n payload?: ChatEventPayload,\n) {\n if (!payload) return null;\n if (payload.sessionKey !== state.sessionKey) return null;\n if (payload.runId && state.chatRunId && payload.runId !== state.chatRunId)\n return null;\n\n if (payload.state === \"delta\") {\n const next = extractText(payload.message);\n if (typeof next === \"string\") {\n const current = state.chatStream ?? \"\";\n if (!current || next.length >= current.length) {\n state.chatStream = next;\n }\n }\n } else if (payload.state === \"final\") {\n state.chatStream = null;\n state.chatRunId = null;\n state.chatStreamStartedAt = null;\n } else if (payload.state === \"aborted\") {\n state.chatStream = null;\n state.chatRunId = null;\n state.chatStreamStartedAt = null;\n } else if (payload.state === \"error\") {\n state.chatStream = null;\n state.chatRunId = null;\n state.chatStreamStartedAt = null;\n state.lastError = payload.errorMessage ?? \"chat error\";\n }\n return payload.state;\n}\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport { toNumber } from \"../format\";\nimport type { SessionsListResult } from \"../types\";\n\nexport type SessionsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n sessionsLoading: boolean;\n sessionsResult: SessionsListResult | null;\n sessionsError: string | null;\n sessionsFilterActive: string;\n sessionsFilterLimit: string;\n sessionsIncludeGlobal: boolean;\n sessionsIncludeUnknown: boolean;\n};\n\nexport async function loadSessions(state: SessionsState) {\n if (!state.client || !state.connected) return;\n if (state.sessionsLoading) return;\n state.sessionsLoading = true;\n state.sessionsError = null;\n try {\n const params: Record = {\n includeGlobal: state.sessionsIncludeGlobal,\n includeUnknown: state.sessionsIncludeUnknown,\n };\n const activeMinutes = toNumber(state.sessionsFilterActive, 0);\n const limit = toNumber(state.sessionsFilterLimit, 0);\n if (activeMinutes > 0) params.activeMinutes = activeMinutes;\n if (limit > 0) params.limit = limit;\n const res = (await state.client.request(\"sessions.list\", params)) as\n | SessionsListResult\n | undefined;\n if (res) state.sessionsResult = res;\n } catch (err) {\n state.sessionsError = String(err);\n } finally {\n state.sessionsLoading = false;\n }\n}\n\nexport async function patchSession(\n state: SessionsState,\n key: string,\n patch: {\n label?: string | null;\n thinkingLevel?: string | null;\n verboseLevel?: string | null;\n reasoningLevel?: string | null;\n },\n) {\n if (!state.client || !state.connected) return;\n const params: Record = { key };\n if (\"label\" in patch) params.label = patch.label;\n if (\"thinkingLevel\" in patch) params.thinkingLevel = patch.thinkingLevel;\n if (\"verboseLevel\" in patch) params.verboseLevel = patch.verboseLevel;\n if (\"reasoningLevel\" in patch) params.reasoningLevel = patch.reasoningLevel;\n try {\n await state.client.request(\"sessions.patch\", params);\n await loadSessions(state);\n } catch (err) {\n state.sessionsError = String(err);\n }\n}\n\nexport async function deleteSession(state: SessionsState, key: string) {\n if (!state.client || !state.connected) return;\n if (state.sessionsLoading) return;\n const confirmed = window.confirm(\n `Delete session \"${key}\"?\\n\\nDeletes the session entry and archives its transcript.`,\n );\n if (!confirmed) return;\n state.sessionsLoading = true;\n state.sessionsError = null;\n try {\n await state.client.request(\"sessions.delete\", { key, deleteTranscript: true });\n await loadSessions(state);\n } catch (err) {\n state.sessionsError = String(err);\n } finally {\n state.sessionsLoading = false;\n }\n}\n","import { truncateText } from \"./format\";\n\nconst TOOL_STREAM_LIMIT = 50;\nconst TOOL_STREAM_THROTTLE_MS = 80;\nconst TOOL_OUTPUT_CHAR_LIMIT = 120_000;\n\nexport type AgentEventPayload = {\n runId: string;\n seq: number;\n stream: string;\n ts: number;\n sessionKey?: string;\n data: Record;\n};\n\nexport type ToolStreamEntry = {\n toolCallId: string;\n runId: string;\n sessionKey?: string;\n name: string;\n args?: unknown;\n output?: string;\n startedAt: number;\n updatedAt: number;\n message: Record;\n};\n\ntype ToolStreamHost = {\n sessionKey: string;\n chatRunId: string | null;\n toolStreamById: Map;\n toolStreamOrder: string[];\n chatToolMessages: Record[];\n toolStreamSyncTimer: number | null;\n};\n\nfunction extractToolOutputText(value: unknown): string | null {\n if (!value || typeof value !== \"object\") return null;\n const record = value as Record;\n if (typeof record.text === \"string\") return record.text;\n const content = record.content;\n if (!Array.isArray(content)) return null;\n const parts = content\n .map((item) => {\n if (!item || typeof item !== \"object\") return null;\n const entry = item as Record;\n if (entry.type === \"text\" && typeof entry.text === \"string\") return entry.text;\n return null;\n })\n .filter((part): part is string => Boolean(part));\n if (parts.length === 0) return null;\n return parts.join(\"\\n\");\n}\n\nfunction formatToolOutput(value: unknown): string | null {\n if (value === null || value === undefined) return null;\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n const contentText = extractToolOutputText(value);\n let text: string;\n if (typeof value === \"string\") {\n text = value;\n } else if (contentText) {\n text = contentText;\n } else {\n try {\n text = JSON.stringify(value, null, 2);\n } catch {\n text = String(value);\n }\n }\n const truncated = truncateText(text, TOOL_OUTPUT_CHAR_LIMIT);\n if (!truncated.truncated) return truncated.text;\n return `${truncated.text}\\n\\n… truncated (${truncated.total} chars, showing first ${truncated.text.length}).`;\n}\n\nfunction buildToolStreamMessage(entry: ToolStreamEntry): Record {\n const content: Array> = [];\n content.push({\n type: \"toolcall\",\n name: entry.name,\n arguments: entry.args ?? {},\n });\n if (entry.output) {\n content.push({\n type: \"toolresult\",\n name: entry.name,\n text: entry.output,\n });\n }\n return {\n role: \"assistant\",\n toolCallId: entry.toolCallId,\n runId: entry.runId,\n content,\n timestamp: entry.startedAt,\n };\n}\n\nfunction trimToolStream(host: ToolStreamHost) {\n if (host.toolStreamOrder.length <= TOOL_STREAM_LIMIT) return;\n const overflow = host.toolStreamOrder.length - TOOL_STREAM_LIMIT;\n const removed = host.toolStreamOrder.splice(0, overflow);\n for (const id of removed) host.toolStreamById.delete(id);\n}\n\nfunction syncToolStreamMessages(host: ToolStreamHost) {\n host.chatToolMessages = host.toolStreamOrder\n .map((id) => host.toolStreamById.get(id)?.message)\n .filter((msg): msg is Record => Boolean(msg));\n}\n\nexport function flushToolStreamSync(host: ToolStreamHost) {\n if (host.toolStreamSyncTimer != null) {\n clearTimeout(host.toolStreamSyncTimer);\n host.toolStreamSyncTimer = null;\n }\n syncToolStreamMessages(host);\n}\n\nexport function scheduleToolStreamSync(host: ToolStreamHost, force = false) {\n if (force) {\n flushToolStreamSync(host);\n return;\n }\n if (host.toolStreamSyncTimer != null) return;\n host.toolStreamSyncTimer = window.setTimeout(\n () => flushToolStreamSync(host),\n TOOL_STREAM_THROTTLE_MS,\n );\n}\n\nexport function resetToolStream(host: ToolStreamHost) {\n host.toolStreamById.clear();\n host.toolStreamOrder = [];\n host.chatToolMessages = [];\n flushToolStreamSync(host);\n}\n\nexport type CompactionStatus = {\n active: boolean;\n startedAt: number | null;\n completedAt: number | null;\n};\n\ntype CompactionHost = ToolStreamHost & {\n compactionStatus?: CompactionStatus | null;\n compactionClearTimer?: number | null;\n};\n\nconst COMPACTION_TOAST_DURATION_MS = 5000;\n\nexport function handleCompactionEvent(host: CompactionHost, payload: AgentEventPayload) {\n const data = payload.data ?? {};\n const phase = typeof data.phase === \"string\" ? data.phase : \"\";\n \n // Clear any existing timer\n if (host.compactionClearTimer != null) {\n window.clearTimeout(host.compactionClearTimer);\n host.compactionClearTimer = null;\n }\n \n if (phase === \"start\") {\n host.compactionStatus = {\n active: true,\n startedAt: Date.now(),\n completedAt: null,\n };\n } else if (phase === \"end\") {\n host.compactionStatus = {\n active: false,\n startedAt: host.compactionStatus?.startedAt ?? null,\n completedAt: Date.now(),\n };\n // Auto-clear the toast after duration\n host.compactionClearTimer = window.setTimeout(() => {\n host.compactionStatus = null;\n host.compactionClearTimer = null;\n }, COMPACTION_TOAST_DURATION_MS);\n }\n}\n\nexport function handleAgentEvent(host: ToolStreamHost, payload?: AgentEventPayload) {\n if (!payload) return;\n \n // Handle compaction events\n if (payload.stream === \"compaction\") {\n handleCompactionEvent(host as CompactionHost, payload);\n return;\n }\n \n if (payload.stream !== \"tool\") return;\n const sessionKey =\n typeof payload.sessionKey === \"string\" ? payload.sessionKey : undefined;\n if (sessionKey && sessionKey !== host.sessionKey) return;\n // Fallback: only accept session-less events for the active run.\n if (!sessionKey && host.chatRunId && payload.runId !== host.chatRunId) return;\n if (host.chatRunId && payload.runId !== host.chatRunId) return;\n if (!host.chatRunId) return;\n\n const data = payload.data ?? {};\n const toolCallId = typeof data.toolCallId === \"string\" ? data.toolCallId : \"\";\n if (!toolCallId) return;\n const name = typeof data.name === \"string\" ? data.name : \"tool\";\n const phase = typeof data.phase === \"string\" ? data.phase : \"\";\n const args = phase === \"start\" ? data.args : undefined;\n const output =\n phase === \"update\"\n ? formatToolOutput(data.partialResult)\n : phase === \"result\"\n ? formatToolOutput(data.result)\n : undefined;\n\n const now = Date.now();\n let entry = host.toolStreamById.get(toolCallId);\n if (!entry) {\n entry = {\n toolCallId,\n runId: payload.runId,\n sessionKey,\n name,\n args,\n output,\n startedAt: typeof payload.ts === \"number\" ? payload.ts : now,\n updatedAt: now,\n message: {},\n };\n host.toolStreamById.set(toolCallId, entry);\n host.toolStreamOrder.push(toolCallId);\n } else {\n entry.name = name;\n if (args !== undefined) entry.args = args;\n if (output !== undefined) entry.output = output;\n entry.updatedAt = now;\n }\n\n entry.message = buildToolStreamMessage(entry);\n trimToolStream(host);\n scheduleToolStreamSync(host, phase === \"result\");\n}\n","type ScrollHost = {\n updateComplete: Promise;\n querySelector: (selectors: string) => Element | null;\n style: CSSStyleDeclaration;\n chatScrollFrame: number | null;\n chatScrollTimeout: number | null;\n chatHasAutoScrolled: boolean;\n chatUserNearBottom: boolean;\n logsScrollFrame: number | null;\n logsAtBottom: boolean;\n topbarObserver: ResizeObserver | null;\n};\n\nexport function scheduleChatScroll(host: ScrollHost, force = false) {\n if (host.chatScrollFrame) cancelAnimationFrame(host.chatScrollFrame);\n if (host.chatScrollTimeout != null) {\n clearTimeout(host.chatScrollTimeout);\n host.chatScrollTimeout = null;\n }\n const pickScrollTarget = () => {\n const container = host.querySelector(\".chat-thread\") as HTMLElement | null;\n if (container) {\n const overflowY = getComputedStyle(container).overflowY;\n const canScroll =\n overflowY === \"auto\" ||\n overflowY === \"scroll\" ||\n container.scrollHeight - container.clientHeight > 1;\n if (canScroll) return container;\n }\n return (document.scrollingElement ?? document.documentElement) as HTMLElement | null;\n };\n // Wait for Lit render to complete, then scroll\n void host.updateComplete.then(() => {\n host.chatScrollFrame = requestAnimationFrame(() => {\n host.chatScrollFrame = null;\n const target = pickScrollTarget();\n if (!target) return;\n const distanceFromBottom =\n target.scrollHeight - target.scrollTop - target.clientHeight;\n const shouldStick = force || host.chatUserNearBottom || distanceFromBottom < 200;\n if (!shouldStick) return;\n if (force) host.chatHasAutoScrolled = true;\n target.scrollTop = target.scrollHeight;\n host.chatUserNearBottom = true;\n const retryDelay = force ? 150 : 120;\n host.chatScrollTimeout = window.setTimeout(() => {\n host.chatScrollTimeout = null;\n const latest = pickScrollTarget();\n if (!latest) return;\n const latestDistanceFromBottom =\n latest.scrollHeight - latest.scrollTop - latest.clientHeight;\n const shouldStickRetry =\n force || host.chatUserNearBottom || latestDistanceFromBottom < 200;\n if (!shouldStickRetry) return;\n latest.scrollTop = latest.scrollHeight;\n host.chatUserNearBottom = true;\n }, retryDelay);\n });\n });\n}\n\nexport function scheduleLogsScroll(host: ScrollHost, force = false) {\n if (host.logsScrollFrame) cancelAnimationFrame(host.logsScrollFrame);\n void host.updateComplete.then(() => {\n host.logsScrollFrame = requestAnimationFrame(() => {\n host.logsScrollFrame = null;\n const container = host.querySelector(\".log-stream\") as HTMLElement | null;\n if (!container) return;\n const distanceFromBottom =\n container.scrollHeight - container.scrollTop - container.clientHeight;\n const shouldStick = force || distanceFromBottom < 80;\n if (!shouldStick) return;\n container.scrollTop = container.scrollHeight;\n });\n });\n}\n\nexport function handleChatScroll(host: ScrollHost, event: Event) {\n const container = event.currentTarget as HTMLElement | null;\n if (!container) return;\n const distanceFromBottom =\n container.scrollHeight - container.scrollTop - container.clientHeight;\n host.chatUserNearBottom = distanceFromBottom < 200;\n}\n\nexport function handleLogsScroll(host: ScrollHost, event: Event) {\n const container = event.currentTarget as HTMLElement | null;\n if (!container) return;\n const distanceFromBottom =\n container.scrollHeight - container.scrollTop - container.clientHeight;\n host.logsAtBottom = distanceFromBottom < 80;\n}\n\nexport function resetChatScroll(host: ScrollHost) {\n host.chatHasAutoScrolled = false;\n host.chatUserNearBottom = true;\n}\n\nexport function exportLogs(lines: string[], label: string) {\n if (lines.length === 0) return;\n const blob = new Blob([`${lines.join(\"\\n\")}\\n`], { type: \"text/plain\" });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n const stamp = new Date().toISOString().slice(0, 19).replace(/[:T]/g, \"-\");\n anchor.href = url;\n anchor.download = `clawdbot-logs-${label}-${stamp}.log`;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n\nexport function observeTopbar(host: ScrollHost) {\n if (typeof ResizeObserver === \"undefined\") return;\n const topbar = host.querySelector(\".topbar\");\n if (!topbar) return;\n const update = () => {\n const { height } = topbar.getBoundingClientRect();\n host.style.setProperty(\"--topbar-height\", `${height}px`);\n };\n update();\n host.topbarObserver = new ResizeObserver(() => update());\n host.topbarObserver.observe(topbar);\n}\n","export function cloneConfigObject(value: T): T {\n if (typeof structuredClone === \"function\") {\n return structuredClone(value);\n }\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nexport function serializeConfigForm(form: Record): string {\n return `${JSON.stringify(form, null, 2).trimEnd()}\\n`;\n}\n\nexport function setPathValue(\n obj: Record | unknown[],\n path: Array,\n value: unknown,\n) {\n if (path.length === 0) return;\n let current: Record | unknown[] = obj;\n for (let i = 0; i < path.length - 1; i += 1) {\n const key = path[i];\n const nextKey = path[i + 1];\n if (typeof key === \"number\") {\n if (!Array.isArray(current)) return;\n if (current[key] == null) {\n current[key] =\n typeof nextKey === \"number\" ? [] : ({} as Record);\n }\n current = current[key] as Record | unknown[];\n } else {\n if (typeof current !== \"object\" || current == null) return;\n const record = current as Record;\n if (record[key] == null) {\n record[key] =\n typeof nextKey === \"number\" ? [] : ({} as Record);\n }\n current = record[key] as Record | unknown[];\n }\n }\n const lastKey = path[path.length - 1];\n if (typeof lastKey === \"number\") {\n if (Array.isArray(current)) current[lastKey] = value;\n return;\n }\n if (typeof current === \"object\" && current != null) {\n (current as Record)[lastKey] = value;\n }\n}\n\nexport function removePathValue(\n obj: Record | unknown[],\n path: Array,\n) {\n if (path.length === 0) return;\n let current: Record | unknown[] = obj;\n for (let i = 0; i < path.length - 1; i += 1) {\n const key = path[i];\n if (typeof key === \"number\") {\n if (!Array.isArray(current)) return;\n current = current[key] as Record | unknown[];\n } else {\n if (typeof current !== \"object\" || current == null) return;\n current = (current as Record)[key] as\n | Record\n | unknown[];\n }\n if (current == null) return;\n }\n const lastKey = path[path.length - 1];\n if (typeof lastKey === \"number\") {\n if (Array.isArray(current)) current.splice(lastKey, 1);\n return;\n }\n if (typeof current === \"object\" && current != null) {\n delete (current as Record)[lastKey];\n }\n}\n\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport type {\n ConfigSchemaResponse,\n ConfigSnapshot,\n ConfigUiHints,\n} from \"../types\";\nimport {\n cloneConfigObject,\n removePathValue,\n serializeConfigForm,\n setPathValue,\n} from \"./config/form-utils\";\n\nexport type ConfigState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n applySessionKey: string;\n configLoading: boolean;\n configRaw: string;\n configRawOriginal: string;\n configValid: boolean | null;\n configIssues: unknown[];\n configSaving: boolean;\n configApplying: boolean;\n updateRunning: boolean;\n configSnapshot: ConfigSnapshot | null;\n configSchema: unknown | null;\n configSchemaVersion: string | null;\n configSchemaLoading: boolean;\n configUiHints: ConfigUiHints;\n configForm: Record | null;\n configFormOriginal: Record | null;\n configFormDirty: boolean;\n configFormMode: \"form\" | \"raw\";\n configSearchQuery: string;\n configActiveSection: string | null;\n configActiveSubsection: string | null;\n lastError: string | null;\n};\n\nexport async function loadConfig(state: ConfigState) {\n if (!state.client || !state.connected) return;\n state.configLoading = true;\n state.lastError = null;\n try {\n const res = (await state.client.request(\"config.get\", {})) as ConfigSnapshot;\n applyConfigSnapshot(state, res);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configLoading = false;\n }\n}\n\nexport async function loadConfigSchema(state: ConfigState) {\n if (!state.client || !state.connected) return;\n if (state.configSchemaLoading) return;\n state.configSchemaLoading = true;\n try {\n const res = (await state.client.request(\n \"config.schema\",\n {},\n )) as ConfigSchemaResponse;\n applyConfigSchema(state, res);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configSchemaLoading = false;\n }\n}\n\nexport function applyConfigSchema(\n state: ConfigState,\n res: ConfigSchemaResponse,\n) {\n state.configSchema = res.schema ?? null;\n state.configUiHints = res.uiHints ?? {};\n state.configSchemaVersion = res.version ?? null;\n}\n\nexport function applyConfigSnapshot(state: ConfigState, snapshot: ConfigSnapshot) {\n state.configSnapshot = snapshot;\n const rawFromSnapshot =\n typeof snapshot.raw === \"string\"\n ? snapshot.raw\n : snapshot.config && typeof snapshot.config === \"object\"\n ? serializeConfigForm(snapshot.config as Record)\n : state.configRaw;\n if (!state.configFormDirty || state.configFormMode === \"raw\") {\n state.configRaw = rawFromSnapshot;\n } else if (state.configForm) {\n state.configRaw = serializeConfigForm(state.configForm);\n } else {\n state.configRaw = rawFromSnapshot;\n }\n state.configValid = typeof snapshot.valid === \"boolean\" ? snapshot.valid : null;\n state.configIssues = Array.isArray(snapshot.issues) ? snapshot.issues : [];\n\n if (!state.configFormDirty) {\n state.configForm = cloneConfigObject(snapshot.config ?? {});\n state.configFormOriginal = cloneConfigObject(snapshot.config ?? {});\n state.configRawOriginal = rawFromSnapshot;\n }\n}\n\nexport async function saveConfig(state: ConfigState) {\n if (!state.client || !state.connected) return;\n state.configSaving = true;\n state.lastError = null;\n try {\n const raw =\n state.configFormMode === \"form\" && state.configForm\n ? serializeConfigForm(state.configForm)\n : state.configRaw;\n const baseHash = state.configSnapshot?.hash;\n if (!baseHash) {\n state.lastError = \"Config hash missing; reload and retry.\";\n return;\n }\n await state.client.request(\"config.set\", { raw, baseHash });\n state.configFormDirty = false;\n await loadConfig(state);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configSaving = false;\n }\n}\n\nexport async function applyConfig(state: ConfigState) {\n if (!state.client || !state.connected) return;\n state.configApplying = true;\n state.lastError = null;\n try {\n const raw =\n state.configFormMode === \"form\" && state.configForm\n ? serializeConfigForm(state.configForm)\n : state.configRaw;\n const baseHash = state.configSnapshot?.hash;\n if (!baseHash) {\n state.lastError = \"Config hash missing; reload and retry.\";\n return;\n }\n await state.client.request(\"config.apply\", {\n raw,\n baseHash,\n sessionKey: state.applySessionKey,\n });\n state.configFormDirty = false;\n await loadConfig(state);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configApplying = false;\n }\n}\n\nexport async function runUpdate(state: ConfigState) {\n if (!state.client || !state.connected) return;\n state.updateRunning = true;\n state.lastError = null;\n try {\n await state.client.request(\"update.run\", {\n sessionKey: state.applySessionKey,\n });\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.updateRunning = false;\n }\n}\n\nexport function updateConfigFormValue(\n state: ConfigState,\n path: Array,\n value: unknown,\n) {\n const base = cloneConfigObject(\n state.configForm ?? state.configSnapshot?.config ?? {},\n );\n setPathValue(base, path, value);\n state.configForm = base;\n state.configFormDirty = true;\n if (state.configFormMode === \"form\") {\n state.configRaw = serializeConfigForm(base);\n }\n}\n\nexport function removeConfigFormValue(\n state: ConfigState,\n path: Array,\n) {\n const base = cloneConfigObject(\n state.configForm ?? state.configSnapshot?.config ?? {},\n );\n removePathValue(base, path);\n state.configForm = base;\n state.configFormDirty = true;\n if (state.configFormMode === \"form\") {\n state.configRaw = serializeConfigForm(base);\n }\n}\n","import { toNumber } from \"../format\";\nimport type { GatewayBrowserClient } from \"../gateway\";\nimport type { CronJob, CronRunLogEntry, CronStatus } from \"../types\";\nimport type { CronFormState } from \"../ui-types\";\n\nexport type CronState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n cronLoading: boolean;\n cronJobs: CronJob[];\n cronStatus: CronStatus | null;\n cronError: string | null;\n cronForm: CronFormState;\n cronRunsJobId: string | null;\n cronRuns: CronRunLogEntry[];\n cronBusy: boolean;\n};\n\nexport async function loadCronStatus(state: CronState) {\n if (!state.client || !state.connected) return;\n try {\n const res = (await state.client.request(\"cron.status\", {})) as CronStatus;\n state.cronStatus = res;\n } catch (err) {\n state.cronError = String(err);\n }\n}\n\nexport async function loadCronJobs(state: CronState) {\n if (!state.client || !state.connected) return;\n if (state.cronLoading) return;\n state.cronLoading = true;\n state.cronError = null;\n try {\n const res = (await state.client.request(\"cron.list\", {\n includeDisabled: true,\n })) as { jobs?: CronJob[] };\n state.cronJobs = Array.isArray(res.jobs) ? res.jobs : [];\n } catch (err) {\n state.cronError = String(err);\n } finally {\n state.cronLoading = false;\n }\n}\n\nexport function buildCronSchedule(form: CronFormState) {\n if (form.scheduleKind === \"at\") {\n const ms = Date.parse(form.scheduleAt);\n if (!Number.isFinite(ms)) throw new Error(\"Invalid run time.\");\n return { kind: \"at\" as const, atMs: ms };\n }\n if (form.scheduleKind === \"every\") {\n const amount = toNumber(form.everyAmount, 0);\n if (amount <= 0) throw new Error(\"Invalid interval amount.\");\n const unit = form.everyUnit;\n const mult = unit === \"minutes\" ? 60_000 : unit === \"hours\" ? 3_600_000 : 86_400_000;\n return { kind: \"every\" as const, everyMs: amount * mult };\n }\n const expr = form.cronExpr.trim();\n if (!expr) throw new Error(\"Cron expression required.\");\n return { kind: \"cron\" as const, expr, tz: form.cronTz.trim() || undefined };\n}\n\nexport function buildCronPayload(form: CronFormState) {\n if (form.payloadKind === \"systemEvent\") {\n const text = form.payloadText.trim();\n if (!text) throw new Error(\"System event text required.\");\n return { kind: \"systemEvent\" as const, text };\n }\n const message = form.payloadText.trim();\n if (!message) throw new Error(\"Agent message required.\");\n const payload: {\n kind: \"agentTurn\";\n message: string;\n deliver?: boolean;\n channel?: string;\n to?: string;\n timeoutSeconds?: number;\n } = { kind: \"agentTurn\", message };\n if (form.deliver) payload.deliver = true;\n if (form.channel) payload.channel = form.channel;\n if (form.to.trim()) payload.to = form.to.trim();\n const timeoutSeconds = toNumber(form.timeoutSeconds, 0);\n if (timeoutSeconds > 0) payload.timeoutSeconds = timeoutSeconds;\n return payload;\n}\n\nexport async function addCronJob(state: CronState) {\n if (!state.client || !state.connected || state.cronBusy) return;\n state.cronBusy = true;\n state.cronError = null;\n try {\n const schedule = buildCronSchedule(state.cronForm);\n const payload = buildCronPayload(state.cronForm);\n const agentId = state.cronForm.agentId.trim();\n const job = {\n name: state.cronForm.name.trim(),\n description: state.cronForm.description.trim() || undefined,\n agentId: agentId || undefined,\n enabled: state.cronForm.enabled,\n schedule,\n sessionTarget: state.cronForm.sessionTarget,\n wakeMode: state.cronForm.wakeMode,\n payload,\n isolation:\n state.cronForm.postToMainPrefix.trim() &&\n state.cronForm.sessionTarget === \"isolated\"\n ? { postToMainPrefix: state.cronForm.postToMainPrefix.trim() }\n : undefined,\n };\n if (!job.name) throw new Error(\"Name required.\");\n await state.client.request(\"cron.add\", job);\n state.cronForm = {\n ...state.cronForm,\n name: \"\",\n description: \"\",\n payloadText: \"\",\n };\n await loadCronJobs(state);\n await loadCronStatus(state);\n } catch (err) {\n state.cronError = String(err);\n } finally {\n state.cronBusy = false;\n }\n}\n\nexport async function toggleCronJob(\n state: CronState,\n job: CronJob,\n enabled: boolean,\n) {\n if (!state.client || !state.connected || state.cronBusy) return;\n state.cronBusy = true;\n state.cronError = null;\n try {\n await state.client.request(\"cron.update\", { id: job.id, patch: { enabled } });\n await loadCronJobs(state);\n await loadCronStatus(state);\n } catch (err) {\n state.cronError = String(err);\n } finally {\n state.cronBusy = false;\n }\n}\n\nexport async function runCronJob(state: CronState, job: CronJob) {\n if (!state.client || !state.connected || state.cronBusy) return;\n state.cronBusy = true;\n state.cronError = null;\n try {\n await state.client.request(\"cron.run\", { id: job.id, mode: \"force\" });\n await loadCronRuns(state, job.id);\n } catch (err) {\n state.cronError = String(err);\n } finally {\n state.cronBusy = false;\n }\n}\n\nexport async function removeCronJob(state: CronState, job: CronJob) {\n if (!state.client || !state.connected || state.cronBusy) return;\n state.cronBusy = true;\n state.cronError = null;\n try {\n await state.client.request(\"cron.remove\", { id: job.id });\n if (state.cronRunsJobId === job.id) {\n state.cronRunsJobId = null;\n state.cronRuns = [];\n }\n await loadCronJobs(state);\n await loadCronStatus(state);\n } catch (err) {\n state.cronError = String(err);\n } finally {\n state.cronBusy = false;\n }\n}\n\nexport async function loadCronRuns(state: CronState, jobId: string) {\n if (!state.client || !state.connected) return;\n try {\n const res = (await state.client.request(\"cron.runs\", {\n id: jobId,\n limit: 50,\n })) as { entries?: CronRunLogEntry[] };\n state.cronRunsJobId = jobId;\n state.cronRuns = Array.isArray(res.entries) ? res.entries : [];\n } catch (err) {\n state.cronError = String(err);\n }\n}\n","import type { ChannelsStatusSnapshot } from \"../types\";\nimport type { ChannelsState } from \"./channels.types\";\n\nexport type { ChannelsState };\n\nexport async function loadChannels(state: ChannelsState, probe: boolean) {\n if (!state.client || !state.connected) return;\n if (state.channelsLoading) return;\n state.channelsLoading = true;\n state.channelsError = null;\n try {\n const res = (await state.client.request(\"channels.status\", {\n probe,\n timeoutMs: 8000,\n })) as ChannelsStatusSnapshot;\n state.channelsSnapshot = res;\n state.channelsLastSuccess = Date.now();\n } catch (err) {\n state.channelsError = String(err);\n } finally {\n state.channelsLoading = false;\n }\n}\n\nexport async function startWhatsAppLogin(state: ChannelsState, force: boolean) {\n if (!state.client || !state.connected || state.whatsappBusy) return;\n state.whatsappBusy = true;\n try {\n const res = (await state.client.request(\"web.login.start\", {\n force,\n timeoutMs: 30000,\n })) as { message?: string; qrDataUrl?: string };\n state.whatsappLoginMessage = res.message ?? null;\n state.whatsappLoginQrDataUrl = res.qrDataUrl ?? null;\n state.whatsappLoginConnected = null;\n } catch (err) {\n state.whatsappLoginMessage = String(err);\n state.whatsappLoginQrDataUrl = null;\n state.whatsappLoginConnected = null;\n } finally {\n state.whatsappBusy = false;\n }\n}\n\nexport async function waitWhatsAppLogin(state: ChannelsState) {\n if (!state.client || !state.connected || state.whatsappBusy) return;\n state.whatsappBusy = true;\n try {\n const res = (await state.client.request(\"web.login.wait\", {\n timeoutMs: 120000,\n })) as { connected?: boolean; message?: string };\n state.whatsappLoginMessage = res.message ?? null;\n state.whatsappLoginConnected = res.connected ?? null;\n if (res.connected) state.whatsappLoginQrDataUrl = null;\n } catch (err) {\n state.whatsappLoginMessage = String(err);\n state.whatsappLoginConnected = null;\n } finally {\n state.whatsappBusy = false;\n }\n}\n\nexport async function logoutWhatsApp(state: ChannelsState) {\n if (!state.client || !state.connected || state.whatsappBusy) return;\n state.whatsappBusy = true;\n try {\n await state.client.request(\"channels.logout\", { channel: \"whatsapp\" });\n state.whatsappLoginMessage = \"Logged out.\";\n state.whatsappLoginQrDataUrl = null;\n state.whatsappLoginConnected = null;\n } catch (err) {\n state.whatsappLoginMessage = String(err);\n } finally {\n state.whatsappBusy = false;\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport type { HealthSnapshot, StatusSummary } from \"../types\";\n\nexport type DebugState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n debugLoading: boolean;\n debugStatus: StatusSummary | null;\n debugHealth: HealthSnapshot | null;\n debugModels: unknown[];\n debugHeartbeat: unknown | null;\n debugCallMethod: string;\n debugCallParams: string;\n debugCallResult: string | null;\n debugCallError: string | null;\n};\n\nexport async function loadDebug(state: DebugState) {\n if (!state.client || !state.connected) return;\n if (state.debugLoading) return;\n state.debugLoading = true;\n try {\n const [status, health, models, heartbeat] = await Promise.all([\n state.client.request(\"status\", {}),\n state.client.request(\"health\", {}),\n state.client.request(\"models.list\", {}),\n state.client.request(\"last-heartbeat\", {}),\n ]);\n state.debugStatus = status as StatusSummary;\n state.debugHealth = health as HealthSnapshot;\n const modelPayload = models as { models?: unknown[] } | undefined;\n state.debugModels = Array.isArray(modelPayload?.models)\n ? modelPayload?.models\n : [];\n state.debugHeartbeat = heartbeat as unknown;\n } catch (err) {\n state.debugCallError = String(err);\n } finally {\n state.debugLoading = false;\n }\n}\n\nexport async function callDebugMethod(state: DebugState) {\n if (!state.client || !state.connected) return;\n state.debugCallError = null;\n state.debugCallResult = null;\n try {\n const params = state.debugCallParams.trim()\n ? (JSON.parse(state.debugCallParams) as unknown)\n : {};\n const res = await state.client.request(state.debugCallMethod.trim(), params);\n state.debugCallResult = JSON.stringify(res, null, 2);\n } catch (err) {\n state.debugCallError = String(err);\n }\n}\n\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport type { LogEntry, LogLevel } from \"../types\";\n\nexport type LogsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n logsLoading: boolean;\n logsError: string | null;\n logsCursor: number | null;\n logsFile: string | null;\n logsEntries: LogEntry[];\n logsTruncated: boolean;\n logsLastFetchAt: number | null;\n logsLimit: number;\n logsMaxBytes: number;\n};\n\nconst LOG_BUFFER_LIMIT = 2000;\nconst LEVELS = new Set([\n \"trace\",\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"fatal\",\n]);\n\nfunction parseMaybeJsonString(value: unknown) {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n if (!trimmed.startsWith(\"{\") || !trimmed.endsWith(\"}\")) return null;\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!parsed || typeof parsed !== \"object\") return null;\n return parsed as Record;\n } catch {\n return null;\n }\n}\n\nfunction normalizeLevel(value: unknown): LogLevel | null {\n if (typeof value !== \"string\") return null;\n const lowered = value.toLowerCase() as LogLevel;\n return LEVELS.has(lowered) ? lowered : null;\n}\n\nexport function parseLogLine(line: string): LogEntry {\n if (!line.trim()) return { raw: line, message: line };\n try {\n const obj = JSON.parse(line) as Record;\n const meta =\n obj && typeof obj._meta === \"object\" && obj._meta !== null\n ? (obj._meta as Record)\n : null;\n const time =\n typeof obj.time === \"string\"\n ? obj.time\n : typeof meta?.date === \"string\"\n ? meta?.date\n : null;\n const level = normalizeLevel(meta?.logLevelName ?? meta?.level);\n\n const contextCandidate =\n typeof obj[\"0\"] === \"string\"\n ? (obj[\"0\"] as string)\n : typeof meta?.name === \"string\"\n ? (meta?.name as string)\n : null;\n const contextObj = parseMaybeJsonString(contextCandidate);\n let subsystem: string | null = null;\n if (contextObj) {\n if (typeof contextObj.subsystem === \"string\") subsystem = contextObj.subsystem;\n else if (typeof contextObj.module === \"string\") subsystem = contextObj.module;\n }\n if (!subsystem && contextCandidate && contextCandidate.length < 120) {\n subsystem = contextCandidate;\n }\n\n let message: string | null = null;\n if (typeof obj[\"1\"] === \"string\") message = obj[\"1\"] as string;\n else if (!contextObj && typeof obj[\"0\"] === \"string\") message = obj[\"0\"] as string;\n else if (typeof obj.message === \"string\") message = obj.message as string;\n\n return {\n raw: line,\n time,\n level,\n subsystem,\n message: message ?? line,\n meta: meta ?? undefined,\n };\n } catch {\n return { raw: line, message: line };\n }\n}\n\nexport async function loadLogs(\n state: LogsState,\n opts?: { reset?: boolean; quiet?: boolean },\n) {\n if (!state.client || !state.connected) return;\n if (state.logsLoading && !opts?.quiet) return;\n if (!opts?.quiet) state.logsLoading = true;\n state.logsError = null;\n try {\n const res = await state.client.request(\"logs.tail\", {\n cursor: opts?.reset ? undefined : state.logsCursor ?? undefined,\n limit: state.logsLimit,\n maxBytes: state.logsMaxBytes,\n });\n const payload = res as {\n file?: string;\n cursor?: number;\n size?: number;\n lines?: unknown;\n truncated?: boolean;\n reset?: boolean;\n };\n const lines = Array.isArray(payload.lines)\n ? (payload.lines.filter((line) => typeof line === \"string\") as string[])\n : [];\n const entries = lines.map(parseLogLine);\n const shouldReset = Boolean(opts?.reset || payload.reset || state.logsCursor == null);\n state.logsEntries = shouldReset\n ? entries\n : [...state.logsEntries, ...entries].slice(-LOG_BUFFER_LIMIT);\n if (typeof payload.cursor === \"number\") state.logsCursor = payload.cursor;\n if (typeof payload.file === \"string\") state.logsFile = payload.file;\n state.logsTruncated = Boolean(payload.truncated);\n state.logsLastFetchAt = Date.now();\n } catch (err) {\n state.logsError = String(err);\n } finally {\n if (!opts?.quiet) state.logsLoading = false;\n }\n}\n","/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */\n/**\n * 5KB JS implementation of ed25519 EdDSA signatures.\n * Compliant with RFC8032, FIPS 186-5 & ZIP215.\n * @module\n * @example\n * ```js\nimport * as ed from '@noble/ed25519';\n(async () => {\n const secretKey = ed.utils.randomSecretKey();\n const message = Uint8Array.from([0xab, 0xbc, 0xcd, 0xde]);\n const pubKey = await ed.getPublicKeyAsync(secretKey); // Sync methods are also present\n const signature = await ed.signAsync(message, secretKey);\n const isValid = await ed.verifyAsync(signature, message, pubKey);\n})();\n```\n */\n/**\n * Curve params. ed25519 is twisted edwards curve. Equation is −x² + y² = -a + dx²y².\n * * P = `2n**255n - 19n` // field over which calculations are done\n * * N = `2n**252n + 27742317777372353535851937790883648493n` // group order, amount of curve points\n * * h = 8 // cofactor\n * * a = `Fp.create(BigInt(-1))` // equation param\n * * d = -121665/121666 a.k.a. `Fp.neg(121665 * Fp.inv(121666))` // equation param\n * * Gx, Gy are coordinates of Generator / base point\n */\nconst ed25519_CURVE = {\n p: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,\n n: 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn,\n h: 8n,\n a: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecn,\n d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n,\n Gx: 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an,\n Gy: 0x6666666666666666666666666666666666666666666666666666666666666658n,\n};\nconst { p: P, n: N, Gx, Gy, a: _a, d: _d, h } = ed25519_CURVE;\nconst L = 32; // field / group byte length\nconst L2 = 64;\n// Helpers and Precomputes sections are reused between libraries\n// ## Helpers\n// ----------\nconst captureTrace = (...args) => {\n if ('captureStackTrace' in Error && typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(...args);\n }\n};\nconst err = (message = '') => {\n const e = new Error(message);\n captureTrace(e, err);\n throw e;\n};\nconst isBig = (n) => typeof n === 'bigint'; // is big integer\nconst isStr = (s) => typeof s === 'string'; // is string\nconst isBytes = (a) => a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n/** Asserts something is Uint8Array. */\nconst abytes = (value, length, title = '') => {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n err(prefix + 'expected Uint8Array' + ofLen + ', got ' + got);\n }\n return value;\n};\n/** create Uint8Array */\nconst u8n = (len) => new Uint8Array(len);\nconst u8fr = (buf) => Uint8Array.from(buf);\nconst padh = (n, pad) => n.toString(16).padStart(pad, '0');\nconst bytesToHex = (b) => Array.from(abytes(b))\n .map((e) => padh(e, 2))\n .join('');\nconst C = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 }; // ASCII characters\nconst _ch = (ch) => {\n if (ch >= C._0 && ch <= C._9)\n return ch - C._0; // '2' => 50-48\n if (ch >= C.A && ch <= C.F)\n return ch - (C.A - 10); // 'B' => 66-(65-10)\n if (ch >= C.a && ch <= C.f)\n return ch - (C.a - 10); // 'b' => 98-(97-10)\n return;\n};\nconst hexToBytes = (hex) => {\n const e = 'hex invalid';\n if (!isStr(hex))\n return err(e);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2)\n return err(e);\n const array = u8n(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n // treat each char as ASCII\n const n1 = _ch(hex.charCodeAt(hi)); // parse first char, multiply it by 16\n const n2 = _ch(hex.charCodeAt(hi + 1)); // parse second char\n if (n1 === undefined || n2 === undefined)\n return err(e);\n array[ai] = n1 * 16 + n2; // example: 'A9' => 10*16 + 9\n }\n return array;\n};\nconst cr = () => globalThis?.crypto; // WebCrypto is available in all modern environments\nconst subtle = () => cr()?.subtle ?? err('crypto.subtle must be defined, consider polyfill');\n// prettier-ignore\nconst concatBytes = (...arrs) => {\n const r = u8n(arrs.reduce((sum, a) => sum + abytes(a).length, 0)); // create u8a of summed length\n let pad = 0; // walk through each array,\n arrs.forEach(a => { r.set(a, pad); pad += a.length; }); // ensure they have proper type\n return r;\n};\n/** WebCrypto OS-level CSPRNG (random number generator). Will throw when not available. */\nconst randomBytes = (len = L) => {\n const c = cr();\n return c.getRandomValues(u8n(len));\n};\nconst big = BigInt;\nconst assertRange = (n, min, max, msg = 'bad number: out of range') => (isBig(n) && min <= n && n < max ? n : err(msg));\n/** modular division */\nconst M = (a, b = P) => {\n const r = a % b;\n return r >= 0n ? r : b + r;\n};\nconst modN = (a) => M(a, N);\n/** Modular inversion using euclidean GCD (non-CT). No negative exponent for now. */\n// prettier-ignore\nconst invert = (num, md) => {\n if (num === 0n || md <= 0n)\n err('no inverse n=' + num + ' mod=' + md);\n let a = M(num, md), b = md, x = 0n, y = 1n, u = 1n, v = 0n;\n while (a !== 0n) {\n const q = b / a, r = b % a;\n const m = x - u * q, n = y - v * q;\n b = a, a = r, x = u, y = v, u = m, v = n;\n }\n return b === 1n ? M(x, md) : err('no inverse'); // b is gcd at this point\n};\nconst callHash = (name) => {\n // @ts-ignore\n const fn = hashes[name];\n if (typeof fn !== 'function')\n err('hashes.' + name + ' not set');\n return fn;\n};\nconst hash = (msg) => callHash('sha512')(msg);\nconst apoint = (p) => (p instanceof Point ? p : err('Point expected'));\n// ## End of Helpers\n// -----------------\nconst B256 = 2n ** 256n;\n/** Point in XYZT extended coordinates. */\nclass Point {\n static BASE;\n static ZERO;\n X;\n Y;\n Z;\n T;\n constructor(X, Y, Z, T) {\n const max = B256;\n this.X = assertRange(X, 0n, max);\n this.Y = assertRange(Y, 0n, max);\n this.Z = assertRange(Z, 1n, max);\n this.T = assertRange(T, 0n, max);\n Object.freeze(this);\n }\n static CURVE() {\n return ed25519_CURVE;\n }\n static fromAffine(p) {\n return new Point(p.x, p.y, 1n, M(p.x * p.y));\n }\n /** RFC8032 5.1.3: Uint8Array to Point. */\n static fromBytes(hex, zip215 = false) {\n const d = _d;\n // Copy array to not mess it up.\n const normed = u8fr(abytes(hex, L));\n // adjust first LE byte = last BE byte\n const lastByte = hex[31];\n normed[31] = lastByte & ~0x80;\n const y = bytesToNumLE(normed);\n // zip215=true: 0 <= y < 2^256\n // zip215=false, RFC8032: 0 <= y < 2^255-19\n const max = zip215 ? B256 : P;\n assertRange(y, 0n, max);\n const y2 = M(y * y); // y²\n const u = M(y2 - 1n); // u=y²-1\n const v = M(d * y2 + 1n); // v=dy²+1\n let { isValid, value: x } = uvRatio(u, v); // (uv³)(uv⁷)^(p-5)/8; square root\n if (!isValid)\n err('bad point: y not sqrt'); // not square root: bad point\n const isXOdd = (x & 1n) === 1n; // adjust sign of x coordinate\n const isLastByteOdd = (lastByte & 0x80) !== 0; // x_0, last bit\n if (!zip215 && x === 0n && isLastByteOdd)\n err('bad point: x==0, isLastByteOdd'); // x=0, x_0=1\n if (isLastByteOdd !== isXOdd)\n x = M(-x);\n return new Point(x, y, 1n, M(x * y)); // Z=1, T=xy\n }\n static fromHex(hex, zip215) {\n return Point.fromBytes(hexToBytes(hex), zip215);\n }\n get x() {\n return this.toAffine().x;\n }\n get y() {\n return this.toAffine().y;\n }\n /** Checks if the point is valid and on-curve. */\n assertValidity() {\n const a = _a;\n const d = _d;\n const p = this;\n if (p.is0())\n return err('bad point: ZERO'); // TODO: optimize, with vars below?\n // Equation in affine coordinates: ax² + y² = 1 + dx²y²\n // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²\n const { X, Y, Z, T } = p;\n const X2 = M(X * X); // X²\n const Y2 = M(Y * Y); // Y²\n const Z2 = M(Z * Z); // Z²\n const Z4 = M(Z2 * Z2); // Z⁴\n const aX2 = M(X2 * a); // aX²\n const left = M(Z2 * M(aX2 + Y2)); // (aX² + Y²)Z²\n const right = M(Z4 + M(d * M(X2 * Y2))); // Z⁴ + dX²Y²\n if (left !== right)\n return err('bad point: equation left != right (1)');\n // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T\n const XY = M(X * Y);\n const ZT = M(Z * T);\n if (XY !== ZT)\n return err('bad point: equation left != right (2)');\n return this;\n }\n /** Equality check: compare points P&Q. */\n equals(other) {\n const { X: X1, Y: Y1, Z: Z1 } = this;\n const { X: X2, Y: Y2, Z: Z2 } = apoint(other); // checks class equality\n const X1Z2 = M(X1 * Z2);\n const X2Z1 = M(X2 * Z1);\n const Y1Z2 = M(Y1 * Z2);\n const Y2Z1 = M(Y2 * Z1);\n return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;\n }\n is0() {\n return this.equals(I);\n }\n /** Flip point over y coordinate. */\n negate() {\n return new Point(M(-this.X), this.Y, this.Z, M(-this.T));\n }\n /** Point doubling. Complete formula. Cost: `4M + 4S + 1*a + 6add + 1*2`. */\n double() {\n const { X: X1, Y: Y1, Z: Z1 } = this;\n const a = _a;\n // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd\n const A = M(X1 * X1);\n const B = M(Y1 * Y1);\n const C = M(2n * M(Z1 * Z1));\n const D = M(a * A);\n const x1y1 = X1 + Y1;\n const E = M(M(x1y1 * x1y1) - A - B);\n const G = D + B;\n const F = G - C;\n const H = D - B;\n const X3 = M(E * F);\n const Y3 = M(G * H);\n const T3 = M(E * H);\n const Z3 = M(F * G);\n return new Point(X3, Y3, Z3, T3);\n }\n /** Point addition. Complete formula. Cost: `8M + 1*k + 8add + 1*2`. */\n add(other) {\n const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;\n const { X: X2, Y: Y2, Z: Z2, T: T2 } = apoint(other); // doesn't check if other on-curve\n const a = _a;\n const d = _d;\n // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3\n const A = M(X1 * X2);\n const B = M(Y1 * Y2);\n const C = M(T1 * d * T2);\n const D = M(Z1 * Z2);\n const E = M((X1 + Y1) * (X2 + Y2) - A - B);\n const F = M(D - C);\n const G = M(D + C);\n const H = M(B - a * A);\n const X3 = M(E * F);\n const Y3 = M(G * H);\n const T3 = M(E * H);\n const Z3 = M(F * G);\n return new Point(X3, Y3, Z3, T3);\n }\n subtract(other) {\n return this.add(apoint(other).negate());\n }\n /**\n * Point-by-scalar multiplication. Scalar must be in range 1 <= n < CURVE.n.\n * Uses {@link wNAF} for base point.\n * Uses fake point to mitigate side-channel leakage.\n * @param n scalar by which point is multiplied\n * @param safe safe mode guards against timing attacks; unsafe mode is faster\n */\n multiply(n, safe = true) {\n if (!safe && (n === 0n || this.is0()))\n return I;\n assertRange(n, 1n, N);\n if (n === 1n)\n return this;\n if (this.equals(G))\n return wNAF(n).p;\n // init result point & fake point\n let p = I;\n let f = G;\n for (let d = this; n > 0n; d = d.double(), n >>= 1n) {\n // if bit is present, add to point\n // if not present, add to fake, for timing safety\n if (n & 1n)\n p = p.add(d);\n else if (safe)\n f = f.add(d);\n }\n return p;\n }\n multiplyUnsafe(scalar) {\n return this.multiply(scalar, false);\n }\n /** Convert point to 2d xy affine point. (X, Y, Z) ∋ (x=X/Z, y=Y/Z) */\n toAffine() {\n const { X, Y, Z } = this;\n // fast-paths for ZERO point OR Z=1\n if (this.equals(I))\n return { x: 0n, y: 1n };\n const iz = invert(Z, P);\n // (Z * Z^-1) must be 1, otherwise bad math\n if (M(Z * iz) !== 1n)\n err('invalid inverse');\n // x = X*Z^-1; y = Y*Z^-1\n const x = M(X * iz);\n const y = M(Y * iz);\n return { x, y };\n }\n toBytes() {\n const { x, y } = this.assertValidity().toAffine();\n const b = numTo32bLE(y);\n // store sign in first LE byte\n b[31] |= x & 1n ? 0x80 : 0;\n return b;\n }\n toHex() {\n return bytesToHex(this.toBytes());\n }\n clearCofactor() {\n return this.multiply(big(h), false);\n }\n isSmallOrder() {\n return this.clearCofactor().is0();\n }\n isTorsionFree() {\n // Multiply by big number N. We can't `mul(N)` because of checks. Instead, we `mul(N/2)*2+1`\n let p = this.multiply(N / 2n, false).double();\n if (N % 2n)\n p = p.add(this);\n return p.is0();\n }\n}\n/** Generator / base point */\nconst G = new Point(Gx, Gy, 1n, M(Gx * Gy));\n/** Identity / zero point */\nconst I = new Point(0n, 1n, 1n, 0n);\n// Static aliases\nPoint.BASE = G;\nPoint.ZERO = I;\nconst numTo32bLE = (num) => hexToBytes(padh(assertRange(num, 0n, B256), L2)).reverse();\nconst bytesToNumLE = (b) => big('0x' + bytesToHex(u8fr(abytes(b)).reverse()));\nconst pow2 = (x, power) => {\n // pow2(x, 4) == x^(2^4)\n let r = x;\n while (power-- > 0n) {\n r *= r;\n r %= P;\n }\n return r;\n};\n// prettier-ignore\nconst pow_2_252_3 = (x) => {\n const x2 = (x * x) % P; // x^2, bits 1\n const b2 = (x2 * x) % P; // x^3, bits 11\n const b4 = (pow2(b2, 2n) * b2) % P; // x^(2^4-1), bits 1111\n const b5 = (pow2(b4, 1n) * x) % P; // x^(2^5-1), bits 11111\n const b10 = (pow2(b5, 5n) * b5) % P; // x^(2^10)\n const b20 = (pow2(b10, 10n) * b10) % P; // x^(2^20)\n const b40 = (pow2(b20, 20n) * b20) % P; // x^(2^40)\n const b80 = (pow2(b40, 40n) * b40) % P; // x^(2^80)\n const b160 = (pow2(b80, 80n) * b80) % P; // x^(2^160)\n const b240 = (pow2(b160, 80n) * b80) % P; // x^(2^240)\n const b250 = (pow2(b240, 10n) * b10) % P; // x^(2^250)\n const pow_p_5_8 = (pow2(b250, 2n) * x) % P; // < To pow to (p+3)/8, multiply it by x.\n return { pow_p_5_8, b2 };\n};\nconst RM1 = 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0n; // √-1\n// for sqrt comp\n// prettier-ignore\nconst uvRatio = (u, v) => {\n const v3 = M(v * v * v); // v³\n const v7 = M(v3 * v3 * v); // v⁷\n const pow = pow_2_252_3(u * v7).pow_p_5_8; // (uv⁷)^(p-5)/8\n let x = M(u * v3 * pow); // (uv³)(uv⁷)^(p-5)/8\n const vx2 = M(v * x * x); // vx²\n const root1 = x; // First root candidate\n const root2 = M(x * RM1); // Second root candidate; RM1 is √-1\n const useRoot1 = vx2 === u; // If vx² = u (mod p), x is a square root\n const useRoot2 = vx2 === M(-u); // If vx² = -u, set x <-- x * 2^((p-1)/4)\n const noRoot = vx2 === M(-u * RM1); // There is no valid root, vx² = -u√-1\n if (useRoot1)\n x = root1;\n if (useRoot2 || noRoot)\n x = root2; // We return root2 anyway, for const-time\n if ((M(x) & 1n) === 1n)\n x = M(-x); // edIsNegative\n return { isValid: useRoot1 || useRoot2, value: x };\n};\n// N == L, just weird naming\nconst modL_LE = (hash) => modN(bytesToNumLE(hash)); // modulo L; but little-endian\n/** hashes.sha512 should conform to the interface. */\n// TODO: rename\nconst sha512a = (...m) => hashes.sha512Async(concatBytes(...m)); // Async SHA512\nconst sha512s = (...m) => callHash('sha512')(concatBytes(...m));\n// RFC8032 5.1.5\nconst hash2extK = (hashed) => {\n // slice creates a copy, unlike subarray\n const head = hashed.slice(0, L);\n head[0] &= 248; // Clamp bits: 0b1111_1000\n head[31] &= 127; // 0b0111_1111\n head[31] |= 64; // 0b0100_0000\n const prefix = hashed.slice(L, L2); // secret key \"prefix\"\n const scalar = modL_LE(head); // modular division over curve order\n const point = G.multiply(scalar); // public key point\n const pointBytes = point.toBytes(); // point serialized to Uint8Array\n return { head, prefix, scalar, point, pointBytes };\n};\n// RFC8032 5.1.5; getPublicKey async, sync. Hash priv key and extract point.\nconst getExtendedPublicKeyAsync = (secretKey) => sha512a(abytes(secretKey, L)).then(hash2extK);\nconst getExtendedPublicKey = (secretKey) => hash2extK(sha512s(abytes(secretKey, L)));\n/** Creates 32-byte ed25519 public key from 32-byte secret key. Async. */\nconst getPublicKeyAsync = (secretKey) => getExtendedPublicKeyAsync(secretKey).then((p) => p.pointBytes);\n/** Creates 32-byte ed25519 public key from 32-byte secret key. To use, set `hashes.sha512` first. */\nconst getPublicKey = (priv) => getExtendedPublicKey(priv).pointBytes;\nconst hashFinishA = (res) => sha512a(res.hashable).then(res.finish);\nconst hashFinishS = (res) => res.finish(sha512s(res.hashable));\n// Code, shared between sync & async sign\nconst _sign = (e, rBytes, msg) => {\n const { pointBytes: P, scalar: s } = e;\n const r = modL_LE(rBytes); // r was created outside, reduce it modulo L\n const R = G.multiply(r).toBytes(); // R = [r]B\n const hashable = concatBytes(R, P, msg); // dom2(F, C) || R || A || PH(M)\n const finish = (hashed) => {\n // k = SHA512(dom2(F, C) || R || A || PH(M))\n const S = modN(r + modL_LE(hashed) * s); // S = (r + k * s) mod L; 0 <= s < l\n return abytes(concatBytes(R, numTo32bLE(S)), L2); // 64-byte sig: 32b R.x + 32b LE(S)\n };\n return { hashable, finish };\n};\n/**\n * Signs message using secret key. Async.\n * Follows RFC8032 5.1.6.\n */\nconst signAsync = async (message, secretKey) => {\n const m = abytes(message);\n const e = await getExtendedPublicKeyAsync(secretKey);\n const rBytes = await sha512a(e.prefix, m); // r = SHA512(dom2(F, C) || prefix || PH(M))\n return hashFinishA(_sign(e, rBytes, m)); // gen R, k, S, then 64-byte signature\n};\n/**\n * Signs message using secret key. To use, set `hashes.sha512` first.\n * Follows RFC8032 5.1.6.\n */\nconst sign = (message, secretKey) => {\n const m = abytes(message);\n const e = getExtendedPublicKey(secretKey);\n const rBytes = sha512s(e.prefix, m); // r = SHA512(dom2(F, C) || prefix || PH(M))\n return hashFinishS(_sign(e, rBytes, m)); // gen R, k, S, then 64-byte signature\n};\nconst defaultVerifyOpts = { zip215: true };\nconst _verify = (sig, msg, pub, opts = defaultVerifyOpts) => {\n sig = abytes(sig, L2); // Signature hex str/Bytes, must be 64 bytes\n msg = abytes(msg); // Message hex str/Bytes\n pub = abytes(pub, L);\n const { zip215 } = opts; // switch between zip215 and rfc8032 verif\n let A;\n let R;\n let s;\n let SB;\n let hashable = Uint8Array.of();\n try {\n A = Point.fromBytes(pub, zip215); // public key A decoded\n R = Point.fromBytes(sig.slice(0, L), zip215); // 0 <= R < 2^256: ZIP215 R can be >= P\n s = bytesToNumLE(sig.slice(L, L2)); // Decode second half as an integer S\n SB = G.multiply(s, false); // in the range 0 <= s < L\n hashable = concatBytes(R.toBytes(), A.toBytes(), msg); // dom2(F, C) || R || A || PH(M)\n }\n catch (error) { }\n const finish = (hashed) => {\n // k = SHA512(dom2(F, C) || R || A || PH(M))\n if (SB == null)\n return false; // false if try-catch catched an error\n if (!zip215 && A.isSmallOrder())\n return false; // false for SBS: Strongly Binding Signature\n const k = modL_LE(hashed); // decode in little-endian, modulo L\n const RkA = R.add(A.multiply(k, false)); // [8]R + [8][k]A'\n return RkA.add(SB.negate()).clearCofactor().is0(); // [8][S]B = [8]R + [8][k]A'\n };\n return { hashable, finish };\n};\n/** Verifies signature on message and public key. Async. Follows RFC8032 5.1.7. */\nconst verifyAsync = async (signature, message, publicKey, opts = defaultVerifyOpts) => hashFinishA(_verify(signature, message, publicKey, opts));\n/** Verifies signature on message and public key. To use, set `hashes.sha512` first. Follows RFC8032 5.1.7. */\nconst verify = (signature, message, publicKey, opts = defaultVerifyOpts) => hashFinishS(_verify(signature, message, publicKey, opts));\n/** Math, hex, byte helpers. Not in `utils` because utils share API with noble-curves. */\nconst etc = {\n bytesToHex: bytesToHex,\n hexToBytes: hexToBytes,\n concatBytes: concatBytes,\n mod: M,\n invert: invert,\n randomBytes: randomBytes,\n};\nconst hashes = {\n sha512Async: async (message) => {\n const s = subtle();\n const m = concatBytes(message);\n return u8n(await s.digest('SHA-512', m.buffer));\n },\n sha512: undefined,\n};\n// FIPS 186 B.4.1 compliant key generation produces private keys\n// with modulo bias being neglible. takes >N+16 bytes, returns (hash mod n-1)+1\nconst randomSecretKey = (seed = randomBytes(L)) => seed;\nconst keygen = (seed) => {\n const secretKey = randomSecretKey(seed);\n const publicKey = getPublicKey(secretKey);\n return { secretKey, publicKey };\n};\nconst keygenAsync = async (seed) => {\n const secretKey = randomSecretKey(seed);\n const publicKey = await getPublicKeyAsync(secretKey);\n return { secretKey, publicKey };\n};\n/** ed25519-specific key utilities. */\nconst utils = {\n getExtendedPublicKeyAsync: getExtendedPublicKeyAsync,\n getExtendedPublicKey: getExtendedPublicKey,\n randomSecretKey: randomSecretKey,\n};\n// ## Precomputes\n// --------------\nconst W = 8; // W is window size\nconst scalarBits = 256;\nconst pwindows = Math.ceil(scalarBits / W) + 1; // 33 for W=8, NOT 32 - see wNAF loop\nconst pwindowSize = 2 ** (W - 1); // 128 for W=8\nconst precompute = () => {\n const points = [];\n let p = G;\n let b = p;\n for (let w = 0; w < pwindows; w++) {\n b = p;\n points.push(b);\n for (let i = 1; i < pwindowSize; i++) {\n b = b.add(p);\n points.push(b);\n } // i=1, bc we skip 0\n p = b.double();\n }\n return points;\n};\nlet Gpows = undefined; // precomputes for base point G\n// const-time negate\nconst ctneg = (cnd, p) => {\n const n = p.negate();\n return cnd ? n : p;\n};\n/**\n * Precomputes give 12x faster getPublicKey(), 10x sign(), 2x verify() by\n * caching multiples of G (base point). Cache is stored in 32MB of RAM.\n * Any time `G.multiply` is done, precomputes are used.\n * Not used for getSharedSecret, which instead multiplies random pubkey `P.multiply`.\n *\n * w-ary non-adjacent form (wNAF) precomputation method is 10% slower than windowed method,\n * but takes 2x less RAM. RAM reduction is possible by utilizing `.subtract`.\n *\n * !! Precomputes can be disabled by commenting-out call of the wNAF() inside Point#multiply().\n */\nconst wNAF = (n) => {\n const comp = Gpows || (Gpows = precompute());\n let p = I;\n let f = G; // f must be G, or could become I in the end\n const pow_2_w = 2 ** W; // 256 for W=8\n const maxNum = pow_2_w; // 256 for W=8\n const mask = big(pow_2_w - 1); // 255 for W=8 == mask 0b11111111\n const shiftBy = big(W); // 8 for W=8\n for (let w = 0; w < pwindows; w++) {\n let wbits = Number(n & mask); // extract W bits.\n n >>= shiftBy; // shift number by W bits.\n // We use negative indexes to reduce size of precomputed table by 2x.\n // Instead of needing precomputes 0..256, we only calculate them for 0..128.\n // If an index > 128 is found, we do (256-index) - where 256 is next window.\n // Naive: index +127 => 127, +224 => 224\n // Optimized: index +127 => 127, +224 => 256-32\n if (wbits > pwindowSize) {\n wbits -= maxNum;\n n += 1n;\n }\n const off = w * pwindowSize;\n const offF = off; // offsets, evaluate both\n const offP = off + Math.abs(wbits) - 1;\n const isEven = w % 2 !== 0; // conditions, evaluate both\n const isNeg = wbits < 0;\n if (wbits === 0) {\n // off == I: can't add it. Adding random offF instead.\n f = f.add(ctneg(isEven, comp[offF])); // bits are 0: add garbage to fake point\n }\n else {\n p = p.add(ctneg(isNeg, comp[offP])); // bits are 1: add to result point\n }\n }\n if (n !== 0n)\n err('invalid wnaf');\n return { p, f }; // return both real and fake points for JIT\n};\n// !! Remove the export to easily use in REPL / browser console\nexport { etc, getPublicKey, getPublicKeyAsync, hash, hashes, keygen, keygenAsync, Point, sign, signAsync, utils, verify, verifyAsync, };\n","import { getPublicKeyAsync, signAsync, utils } from \"@noble/ed25519\";\n\ntype StoredIdentity = {\n version: 1;\n deviceId: string;\n publicKey: string;\n privateKey: string;\n createdAtMs: number;\n};\n\nexport type DeviceIdentity = {\n deviceId: string;\n publicKey: string;\n privateKey: string;\n};\n\nconst STORAGE_KEY = \"clawdbot-device-identity-v1\";\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/g, \"\");\n}\n\nfunction base64UrlDecode(input: string): Uint8Array {\n const normalized = input.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n const padded = normalized + \"=\".repeat((4 - (normalized.length % 4)) % 4);\n const binary = atob(padded);\n const out = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);\n return out;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nasync function fingerprintPublicKey(publicKey: Uint8Array): Promise {\n const hash = await crypto.subtle.digest(\"SHA-256\", publicKey);\n return bytesToHex(new Uint8Array(hash));\n}\n\nasync function generateIdentity(): Promise {\n const privateKey = utils.randomSecretKey();\n const publicKey = await getPublicKeyAsync(privateKey);\n const deviceId = await fingerprintPublicKey(publicKey);\n return {\n deviceId,\n publicKey: base64UrlEncode(publicKey),\n privateKey: base64UrlEncode(privateKey),\n };\n}\n\nexport async function loadOrCreateDeviceIdentity(): Promise {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (raw) {\n const parsed = JSON.parse(raw) as StoredIdentity;\n if (\n parsed?.version === 1 &&\n typeof parsed.deviceId === \"string\" &&\n typeof parsed.publicKey === \"string\" &&\n typeof parsed.privateKey === \"string\"\n ) {\n const derivedId = await fingerprintPublicKey(base64UrlDecode(parsed.publicKey));\n if (derivedId !== parsed.deviceId) {\n const updated: StoredIdentity = {\n ...parsed,\n deviceId: derivedId,\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(updated));\n return {\n deviceId: derivedId,\n publicKey: parsed.publicKey,\n privateKey: parsed.privateKey,\n };\n }\n return {\n deviceId: parsed.deviceId,\n publicKey: parsed.publicKey,\n privateKey: parsed.privateKey,\n };\n }\n }\n } catch {\n // fall through to regenerate\n }\n\n const identity = await generateIdentity();\n const stored: StoredIdentity = {\n version: 1,\n deviceId: identity.deviceId,\n publicKey: identity.publicKey,\n privateKey: identity.privateKey,\n createdAtMs: Date.now(),\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(stored));\n return identity;\n}\n\nexport async function signDevicePayload(privateKeyBase64Url: string, payload: string) {\n const key = base64UrlDecode(privateKeyBase64Url);\n const data = new TextEncoder().encode(payload);\n const sig = await signAsync(data, key);\n return base64UrlEncode(sig);\n}\n","export type DeviceAuthEntry = {\n token: string;\n role: string;\n scopes: string[];\n updatedAtMs: number;\n};\n\ntype DeviceAuthStore = {\n version: 1;\n deviceId: string;\n tokens: Record;\n};\n\nconst STORAGE_KEY = \"clawdbot.device.auth.v1\";\n\nfunction normalizeRole(role: string): string {\n return role.trim();\n}\n\nfunction normalizeScopes(scopes: string[] | undefined): string[] {\n if (!Array.isArray(scopes)) return [];\n const out = new Set();\n for (const scope of scopes) {\n const trimmed = scope.trim();\n if (trimmed) out.add(trimmed);\n }\n return [...out].sort();\n}\n\nfunction readStore(): DeviceAuthStore | null {\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as DeviceAuthStore;\n if (!parsed || parsed.version !== 1) return null;\n if (!parsed.deviceId || typeof parsed.deviceId !== \"string\") return null;\n if (!parsed.tokens || typeof parsed.tokens !== \"object\") return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction writeStore(store: DeviceAuthStore) {\n try {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(store));\n } catch {\n // best-effort\n }\n}\n\nexport function loadDeviceAuthToken(params: {\n deviceId: string;\n role: string;\n}): DeviceAuthEntry | null {\n const store = readStore();\n if (!store || store.deviceId !== params.deviceId) return null;\n const role = normalizeRole(params.role);\n const entry = store.tokens[role];\n if (!entry || typeof entry.token !== \"string\") return null;\n return entry;\n}\n\nexport function storeDeviceAuthToken(params: {\n deviceId: string;\n role: string;\n token: string;\n scopes?: string[];\n}): DeviceAuthEntry {\n const role = normalizeRole(params.role);\n const next: DeviceAuthStore = {\n version: 1,\n deviceId: params.deviceId,\n tokens: {},\n };\n const existing = readStore();\n if (existing && existing.deviceId === params.deviceId) {\n next.tokens = { ...existing.tokens };\n }\n const entry: DeviceAuthEntry = {\n token: params.token,\n role,\n scopes: normalizeScopes(params.scopes),\n updatedAtMs: Date.now(),\n };\n next.tokens[role] = entry;\n writeStore(next);\n return entry;\n}\n\nexport function clearDeviceAuthToken(params: { deviceId: string; role: string }) {\n const store = readStore();\n if (!store || store.deviceId !== params.deviceId) return;\n const role = normalizeRole(params.role);\n if (!store.tokens[role]) return;\n const next = { ...store, tokens: { ...store.tokens } };\n delete next.tokens[role];\n writeStore(next);\n}\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport { loadOrCreateDeviceIdentity } from \"../device-identity\";\nimport { clearDeviceAuthToken, storeDeviceAuthToken } from \"../device-auth\";\n\nexport type DeviceTokenSummary = {\n role: string;\n scopes?: string[];\n createdAtMs?: number;\n rotatedAtMs?: number;\n revokedAtMs?: number;\n lastUsedAtMs?: number;\n};\n\nexport type PendingDevice = {\n requestId: string;\n deviceId: string;\n displayName?: string;\n role?: string;\n remoteIp?: string;\n isRepair?: boolean;\n ts?: number;\n};\n\nexport type PairedDevice = {\n deviceId: string;\n displayName?: string;\n roles?: string[];\n scopes?: string[];\n remoteIp?: string;\n tokens?: DeviceTokenSummary[];\n createdAtMs?: number;\n approvedAtMs?: number;\n};\n\nexport type DevicePairingList = {\n pending: PendingDevice[];\n paired: PairedDevice[];\n};\n\nexport type DevicesState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n devicesLoading: boolean;\n devicesError: string | null;\n devicesList: DevicePairingList | null;\n};\n\nexport async function loadDevices(state: DevicesState, opts?: { quiet?: boolean }) {\n if (!state.client || !state.connected) return;\n if (state.devicesLoading) return;\n state.devicesLoading = true;\n if (!opts?.quiet) state.devicesError = null;\n try {\n const res = (await state.client.request(\"device.pair.list\", {})) as DevicePairingList | null;\n state.devicesList = {\n pending: Array.isArray(res?.pending) ? res!.pending : [],\n paired: Array.isArray(res?.paired) ? res!.paired : [],\n };\n } catch (err) {\n if (!opts?.quiet) state.devicesError = String(err);\n } finally {\n state.devicesLoading = false;\n }\n}\n\nexport async function approveDevicePairing(state: DevicesState, requestId: string) {\n if (!state.client || !state.connected) return;\n try {\n await state.client.request(\"device.pair.approve\", { requestId });\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n\nexport async function rejectDevicePairing(state: DevicesState, requestId: string) {\n if (!state.client || !state.connected) return;\n const confirmed = window.confirm(\"Reject this device pairing request?\");\n if (!confirmed) return;\n try {\n await state.client.request(\"device.pair.reject\", { requestId });\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n\nexport async function rotateDeviceToken(\n state: DevicesState,\n params: { deviceId: string; role: string; scopes?: string[] },\n) {\n if (!state.client || !state.connected) return;\n try {\n const res = (await state.client.request(\"device.token.rotate\", params)) as\n | { token?: string; role?: string; deviceId?: string; scopes?: string[] }\n | undefined;\n if (res?.token) {\n const identity = await loadOrCreateDeviceIdentity();\n const role = res.role ?? params.role;\n if (res.deviceId === identity.deviceId || params.deviceId === identity.deviceId) {\n storeDeviceAuthToken({\n deviceId: identity.deviceId,\n role,\n token: res.token,\n scopes: res.scopes ?? params.scopes ?? [],\n });\n }\n window.prompt(\"New device token (copy and store securely):\", res.token);\n }\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n\nexport async function revokeDeviceToken(\n state: DevicesState,\n params: { deviceId: string; role: string },\n) {\n if (!state.client || !state.connected) return;\n const confirmed = window.confirm(\n `Revoke token for ${params.deviceId} (${params.role})?`,\n );\n if (!confirmed) return;\n try {\n await state.client.request(\"device.token.revoke\", params);\n const identity = await loadOrCreateDeviceIdentity();\n if (params.deviceId === identity.deviceId) {\n clearDeviceAuthToken({ deviceId: identity.deviceId, role: params.role });\n }\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway\";\n\nexport type NodesState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n nodesLoading: boolean;\n nodes: Array>;\n lastError: string | null;\n};\n\nexport async function loadNodes(\n state: NodesState,\n opts?: { quiet?: boolean },\n) {\n if (!state.client || !state.connected) return;\n if (state.nodesLoading) return;\n state.nodesLoading = true;\n if (!opts?.quiet) state.lastError = null;\n try {\n const res = (await state.client.request(\"node.list\", {})) as {\n nodes?: Array>;\n };\n state.nodes = Array.isArray(res.nodes) ? res.nodes : [];\n } catch (err) {\n if (!opts?.quiet) state.lastError = String(err);\n } finally {\n state.nodesLoading = false;\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport { cloneConfigObject, removePathValue, setPathValue } from \"./config/form-utils\";\n\nexport type ExecApprovalsDefaults = {\n security?: string;\n ask?: string;\n askFallback?: string;\n autoAllowSkills?: boolean;\n};\n\nexport type ExecApprovalsAllowlistEntry = {\n id?: string;\n pattern: string;\n lastUsedAt?: number;\n lastUsedCommand?: string;\n lastResolvedPath?: string;\n};\n\nexport type ExecApprovalsAgent = ExecApprovalsDefaults & {\n allowlist?: ExecApprovalsAllowlistEntry[];\n};\n\nexport type ExecApprovalsFile = {\n version?: number;\n socket?: { path?: string };\n defaults?: ExecApprovalsDefaults;\n agents?: Record;\n};\n\nexport type ExecApprovalsSnapshot = {\n path: string;\n exists: boolean;\n hash: string;\n file: ExecApprovalsFile;\n};\n\nexport type ExecApprovalsTarget =\n | { kind: \"gateway\" }\n | { kind: \"node\"; nodeId: string };\n\nexport type ExecApprovalsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n execApprovalsLoading: boolean;\n execApprovalsSaving: boolean;\n execApprovalsDirty: boolean;\n execApprovalsSnapshot: ExecApprovalsSnapshot | null;\n execApprovalsForm: ExecApprovalsFile | null;\n execApprovalsSelectedAgent: string | null;\n lastError: string | null;\n};\n\nfunction resolveExecApprovalsRpc(target?: ExecApprovalsTarget | null): {\n method: string;\n params: Record;\n} | null {\n if (!target || target.kind === \"gateway\") {\n return { method: \"exec.approvals.get\", params: {} };\n }\n const nodeId = target.nodeId.trim();\n if (!nodeId) return null;\n return { method: \"exec.approvals.node.get\", params: { nodeId } };\n}\n\nfunction resolveExecApprovalsSaveRpc(\n target: ExecApprovalsTarget | null | undefined,\n params: { file: ExecApprovalsFile; baseHash: string },\n): { method: string; params: Record } | null {\n if (!target || target.kind === \"gateway\") {\n return { method: \"exec.approvals.set\", params };\n }\n const nodeId = target.nodeId.trim();\n if (!nodeId) return null;\n return { method: \"exec.approvals.node.set\", params: { ...params, nodeId } };\n}\n\nexport async function loadExecApprovals(\n state: ExecApprovalsState,\n target?: ExecApprovalsTarget | null,\n) {\n if (!state.client || !state.connected) return;\n if (state.execApprovalsLoading) return;\n state.execApprovalsLoading = true;\n state.lastError = null;\n try {\n const rpc = resolveExecApprovalsRpc(target);\n if (!rpc) {\n state.lastError = \"Select a node before loading exec approvals.\";\n return;\n }\n const res = (await state.client.request(rpc.method, rpc.params)) as ExecApprovalsSnapshot;\n applyExecApprovalsSnapshot(state, res);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.execApprovalsLoading = false;\n }\n}\n\nexport function applyExecApprovalsSnapshot(\n state: ExecApprovalsState,\n snapshot: ExecApprovalsSnapshot,\n) {\n state.execApprovalsSnapshot = snapshot;\n if (!state.execApprovalsDirty) {\n state.execApprovalsForm = cloneConfigObject(snapshot.file ?? {});\n }\n}\n\nexport async function saveExecApprovals(\n state: ExecApprovalsState,\n target?: ExecApprovalsTarget | null,\n) {\n if (!state.client || !state.connected) return;\n state.execApprovalsSaving = true;\n state.lastError = null;\n try {\n const baseHash = state.execApprovalsSnapshot?.hash;\n if (!baseHash) {\n state.lastError = \"Exec approvals hash missing; reload and retry.\";\n return;\n }\n const file =\n state.execApprovalsForm ??\n state.execApprovalsSnapshot?.file ??\n {};\n const rpc = resolveExecApprovalsSaveRpc(target, { file, baseHash });\n if (!rpc) {\n state.lastError = \"Select a node before saving exec approvals.\";\n return;\n }\n await state.client.request(rpc.method, rpc.params);\n state.execApprovalsDirty = false;\n await loadExecApprovals(state, target);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.execApprovalsSaving = false;\n }\n}\n\nexport function updateExecApprovalsFormValue(\n state: ExecApprovalsState,\n path: Array,\n value: unknown,\n) {\n const base = cloneConfigObject(\n state.execApprovalsForm ?? state.execApprovalsSnapshot?.file ?? {},\n );\n setPathValue(base, path, value);\n state.execApprovalsForm = base;\n state.execApprovalsDirty = true;\n}\n\nexport function removeExecApprovalsFormValue(\n state: ExecApprovalsState,\n path: Array,\n) {\n const base = cloneConfigObject(\n state.execApprovalsForm ?? state.execApprovalsSnapshot?.file ?? {},\n );\n removePathValue(base, path);\n state.execApprovalsForm = base;\n state.execApprovalsDirty = true;\n}\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport type { PresenceEntry } from \"../types\";\n\nexport type PresenceState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n presenceLoading: boolean;\n presenceEntries: PresenceEntry[];\n presenceError: string | null;\n presenceStatus: string | null;\n};\n\nexport async function loadPresence(state: PresenceState) {\n if (!state.client || !state.connected) return;\n if (state.presenceLoading) return;\n state.presenceLoading = true;\n state.presenceError = null;\n state.presenceStatus = null;\n try {\n const res = (await state.client.request(\"system-presence\", {})) as\n | PresenceEntry[]\n | undefined;\n if (Array.isArray(res)) {\n state.presenceEntries = res;\n state.presenceStatus = res.length === 0 ? \"No instances yet.\" : null;\n } else {\n state.presenceEntries = [];\n state.presenceStatus = \"No presence payload.\";\n }\n } catch (err) {\n state.presenceError = String(err);\n } finally {\n state.presenceLoading = false;\n }\n}\n\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport type { SkillStatusReport } from \"../types\";\n\nexport type SkillsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n skillsLoading: boolean;\n skillsReport: SkillStatusReport | null;\n skillsError: string | null;\n skillsBusyKey: string | null;\n skillEdits: Record;\n skillMessages: SkillMessageMap;\n};\n\nexport type SkillMessage = {\n kind: \"success\" | \"error\";\n message: string;\n};\n\nexport type SkillMessageMap = Record;\n\ntype LoadSkillsOptions = {\n clearMessages?: boolean;\n};\n\nfunction setSkillMessage(state: SkillsState, key: string, message?: SkillMessage) {\n if (!key.trim()) return;\n const next = { ...state.skillMessages };\n if (message) next[key] = message;\n else delete next[key];\n state.skillMessages = next;\n}\n\nfunction getErrorMessage(err: unknown) {\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nexport async function loadSkills(state: SkillsState, options?: LoadSkillsOptions) {\n if (options?.clearMessages && Object.keys(state.skillMessages).length > 0) {\n state.skillMessages = {};\n }\n if (!state.client || !state.connected) return;\n if (state.skillsLoading) return;\n state.skillsLoading = true;\n state.skillsError = null;\n try {\n const res = (await state.client.request(\"skills.status\", {})) as\n | SkillStatusReport\n | undefined;\n if (res) state.skillsReport = res;\n } catch (err) {\n state.skillsError = getErrorMessage(err);\n } finally {\n state.skillsLoading = false;\n }\n}\n\nexport function updateSkillEdit(\n state: SkillsState,\n skillKey: string,\n value: string,\n) {\n state.skillEdits = { ...state.skillEdits, [skillKey]: value };\n}\n\nexport async function updateSkillEnabled(\n state: SkillsState,\n skillKey: string,\n enabled: boolean,\n) {\n if (!state.client || !state.connected) return;\n state.skillsBusyKey = skillKey;\n state.skillsError = null;\n try {\n await state.client.request(\"skills.update\", { skillKey, enabled });\n await loadSkills(state);\n setSkillMessage(state, skillKey, {\n kind: \"success\",\n message: enabled ? \"Skill enabled\" : \"Skill disabled\",\n });\n } catch (err) {\n const message = getErrorMessage(err);\n state.skillsError = message;\n setSkillMessage(state, skillKey, {\n kind: \"error\",\n message,\n });\n } finally {\n state.skillsBusyKey = null;\n }\n}\n\nexport async function saveSkillApiKey(state: SkillsState, skillKey: string) {\n if (!state.client || !state.connected) return;\n state.skillsBusyKey = skillKey;\n state.skillsError = null;\n try {\n const apiKey = state.skillEdits[skillKey] ?? \"\";\n await state.client.request(\"skills.update\", { skillKey, apiKey });\n await loadSkills(state);\n setSkillMessage(state, skillKey, {\n kind: \"success\",\n message: \"API key saved\",\n });\n } catch (err) {\n const message = getErrorMessage(err);\n state.skillsError = message;\n setSkillMessage(state, skillKey, {\n kind: \"error\",\n message,\n });\n } finally {\n state.skillsBusyKey = null;\n }\n}\n\nexport async function installSkill(\n state: SkillsState,\n skillKey: string,\n name: string,\n installId: string,\n) {\n if (!state.client || !state.connected) return;\n state.skillsBusyKey = skillKey;\n state.skillsError = null;\n try {\n const result = (await state.client.request(\"skills.install\", {\n name,\n installId,\n timeoutMs: 120000,\n })) as { ok?: boolean; message?: string };\n await loadSkills(state);\n setSkillMessage(state, skillKey, {\n kind: \"success\",\n message: result?.message ?? \"Installed\",\n });\n } catch (err) {\n const message = getErrorMessage(err);\n state.skillsError = message;\n setSkillMessage(state, skillKey, {\n kind: \"error\",\n message,\n });\n } finally {\n state.skillsBusyKey = null;\n }\n}\n","export type ThemeMode = \"system\" | \"light\" | \"dark\";\nexport type ResolvedTheme = \"light\" | \"dark\";\n\nexport function getSystemTheme(): ResolvedTheme {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return \"dark\";\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n}\n\nexport function resolveTheme(mode: ThemeMode): ResolvedTheme {\n if (mode === \"system\") return getSystemTheme();\n return mode;\n}\n","import type { ThemeMode } from \"./theme\";\n\nexport type ThemeTransitionContext = {\n element?: HTMLElement | null;\n pointerClientX?: number;\n pointerClientY?: number;\n};\n\nexport type ThemeTransitionOptions = {\n nextTheme: ThemeMode;\n applyTheme: () => void;\n context?: ThemeTransitionContext;\n currentTheme?: ThemeMode | null;\n};\n\ntype DocumentWithViewTransition = Document & {\n startViewTransition?: (callback: () => void) => { finished: Promise };\n};\n\nconst clamp01 = (value: number) => {\n if (Number.isNaN(value)) return 0.5;\n if (value <= 0) return 0;\n if (value >= 1) return 1;\n return value;\n};\n\nconst hasReducedMotionPreference = () => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches ?? false;\n};\n\nconst cleanupThemeTransition = (root: HTMLElement) => {\n root.classList.remove(\"theme-transition\");\n root.style.removeProperty(\"--theme-switch-x\");\n root.style.removeProperty(\"--theme-switch-y\");\n};\n\nexport const startThemeTransition = ({\n nextTheme,\n applyTheme,\n context,\n currentTheme,\n}: ThemeTransitionOptions) => {\n if (currentTheme === nextTheme) return;\n\n const documentReference = globalThis.document ?? null;\n if (!documentReference) {\n applyTheme();\n return;\n }\n\n const root = documentReference.documentElement;\n const document_ = documentReference as DocumentWithViewTransition;\n const prefersReducedMotion = hasReducedMotionPreference();\n\n const canUseViewTransition =\n Boolean(document_.startViewTransition) && !prefersReducedMotion;\n\n if (canUseViewTransition) {\n let xPercent = 0.5;\n let yPercent = 0.5;\n\n if (\n context?.pointerClientX !== undefined &&\n context?.pointerClientY !== undefined &&\n typeof window !== \"undefined\"\n ) {\n xPercent = clamp01(context.pointerClientX / window.innerWidth);\n yPercent = clamp01(context.pointerClientY / window.innerHeight);\n } else if (context?.element) {\n const rect = context.element.getBoundingClientRect();\n if (\n rect.width > 0 &&\n rect.height > 0 &&\n typeof window !== \"undefined\"\n ) {\n xPercent = clamp01((rect.left + rect.width / 2) / window.innerWidth);\n yPercent = clamp01((rect.top + rect.height / 2) / window.innerHeight);\n }\n }\n\n root.style.setProperty(\"--theme-switch-x\", `${xPercent * 100}%`);\n root.style.setProperty(\"--theme-switch-y\", `${yPercent * 100}%`);\n root.classList.add(\"theme-transition\");\n\n try {\n const transition = document_.startViewTransition?.(() => {\n applyTheme();\n });\n if (transition?.finished) {\n void transition.finished.finally(() => cleanupThemeTransition(root));\n } else {\n cleanupThemeTransition(root);\n }\n } catch {\n cleanupThemeTransition(root);\n applyTheme();\n }\n return;\n }\n\n applyTheme();\n cleanupThemeTransition(root);\n};\n","import { loadLogs } from \"./controllers/logs\";\nimport { loadNodes } from \"./controllers/nodes\";\nimport { loadDebug } from \"./controllers/debug\";\nimport type { ClawdbotApp } from \"./app\";\n\ntype PollingHost = {\n nodesPollInterval: number | null;\n logsPollInterval: number | null;\n debugPollInterval: number | null;\n tab: string;\n};\n\nexport function startNodesPolling(host: PollingHost) {\n if (host.nodesPollInterval != null) return;\n host.nodesPollInterval = window.setInterval(\n () => void loadNodes(host as unknown as ClawdbotApp, { quiet: true }),\n 5000,\n );\n}\n\nexport function stopNodesPolling(host: PollingHost) {\n if (host.nodesPollInterval == null) return;\n clearInterval(host.nodesPollInterval);\n host.nodesPollInterval = null;\n}\n\nexport function startLogsPolling(host: PollingHost) {\n if (host.logsPollInterval != null) return;\n host.logsPollInterval = window.setInterval(() => {\n if (host.tab !== \"logs\") return;\n void loadLogs(host as unknown as ClawdbotApp, { quiet: true });\n }, 2000);\n}\n\nexport function stopLogsPolling(host: PollingHost) {\n if (host.logsPollInterval == null) return;\n clearInterval(host.logsPollInterval);\n host.logsPollInterval = null;\n}\n\nexport function startDebugPolling(host: PollingHost) {\n if (host.debugPollInterval != null) return;\n host.debugPollInterval = window.setInterval(() => {\n if (host.tab !== \"debug\") return;\n void loadDebug(host as unknown as ClawdbotApp);\n }, 3000);\n}\n\nexport function stopDebugPolling(host: PollingHost) {\n if (host.debugPollInterval == null) return;\n clearInterval(host.debugPollInterval);\n host.debugPollInterval = null;\n}\n","import { loadConfig, loadConfigSchema } from \"./controllers/config\";\nimport { loadCronJobs, loadCronStatus } from \"./controllers/cron\";\nimport { loadChannels } from \"./controllers/channels\";\nimport { loadDebug } from \"./controllers/debug\";\nimport { loadLogs } from \"./controllers/logs\";\nimport { loadDevices } from \"./controllers/devices\";\nimport { loadNodes } from \"./controllers/nodes\";\nimport { loadExecApprovals } from \"./controllers/exec-approvals\";\nimport { loadPresence } from \"./controllers/presence\";\nimport { loadSessions } from \"./controllers/sessions\";\nimport { loadSkills } from \"./controllers/skills\";\nimport { inferBasePathFromPathname, normalizeBasePath, normalizePath, pathForTab, tabFromPath, type Tab } from \"./navigation\";\nimport { saveSettings, type UiSettings } from \"./storage\";\nimport { resolveTheme, type ResolvedTheme, type ThemeMode } from \"./theme\";\nimport { startThemeTransition, type ThemeTransitionContext } from \"./theme-transition\";\nimport { scheduleChatScroll, scheduleLogsScroll } from \"./app-scroll\";\nimport { startLogsPolling, stopLogsPolling, startDebugPolling, stopDebugPolling } from \"./app-polling\";\nimport { refreshChat } from \"./app-chat\";\nimport type { ClawdbotApp } from \"./app\";\n\ntype SettingsHost = {\n settings: UiSettings;\n theme: ThemeMode;\n themeResolved: ResolvedTheme;\n applySessionKey: string;\n sessionKey: string;\n tab: Tab;\n connected: boolean;\n chatHasAutoScrolled: boolean;\n logsAtBottom: boolean;\n eventLog: unknown[];\n eventLogBuffer: unknown[];\n basePath: string;\n themeMedia: MediaQueryList | null;\n themeMediaHandler: ((event: MediaQueryListEvent) => void) | null;\n};\n\nexport function applySettings(host: SettingsHost, next: UiSettings) {\n const normalized = {\n ...next,\n lastActiveSessionKey: next.lastActiveSessionKey?.trim() || next.sessionKey.trim() || \"main\",\n };\n host.settings = normalized;\n saveSettings(normalized);\n if (next.theme !== host.theme) {\n host.theme = next.theme;\n applyResolvedTheme(host, resolveTheme(next.theme));\n }\n host.applySessionKey = host.settings.lastActiveSessionKey;\n}\n\nexport function setLastActiveSessionKey(host: SettingsHost, next: string) {\n const trimmed = next.trim();\n if (!trimmed) return;\n if (host.settings.lastActiveSessionKey === trimmed) return;\n applySettings(host, { ...host.settings, lastActiveSessionKey: trimmed });\n}\n\nexport function applySettingsFromUrl(host: SettingsHost) {\n if (!window.location.search) return;\n const params = new URLSearchParams(window.location.search);\n const tokenRaw = params.get(\"token\");\n const passwordRaw = params.get(\"password\");\n const sessionRaw = params.get(\"session\");\n const gatewayUrlRaw = params.get(\"gatewayUrl\");\n let shouldCleanUrl = false;\n\n if (tokenRaw != null) {\n const token = tokenRaw.trim();\n if (token && token !== host.settings.token) {\n applySettings(host, { ...host.settings, token });\n }\n params.delete(\"token\");\n shouldCleanUrl = true;\n }\n\n if (passwordRaw != null) {\n const password = passwordRaw.trim();\n if (password) {\n (host as { password: string }).password = password;\n }\n params.delete(\"password\");\n shouldCleanUrl = true;\n }\n\n if (sessionRaw != null) {\n const session = sessionRaw.trim();\n if (session) {\n host.sessionKey = session;\n applySettings(host, {\n ...host.settings,\n sessionKey: session,\n lastActiveSessionKey: session,\n });\n }\n }\n\n if (gatewayUrlRaw != null) {\n const gatewayUrl = gatewayUrlRaw.trim();\n if (gatewayUrl && gatewayUrl !== host.settings.gatewayUrl) {\n applySettings(host, { ...host.settings, gatewayUrl });\n }\n params.delete(\"gatewayUrl\");\n shouldCleanUrl = true;\n }\n\n if (!shouldCleanUrl) return;\n const url = new URL(window.location.href);\n url.search = params.toString();\n window.history.replaceState({}, \"\", url.toString());\n}\n\nexport function setTab(host: SettingsHost, next: Tab) {\n if (host.tab !== next) host.tab = next;\n if (next === \"chat\") host.chatHasAutoScrolled = false;\n if (next === \"logs\")\n startLogsPolling(host as unknown as Parameters[0]);\n else stopLogsPolling(host as unknown as Parameters[0]);\n if (next === \"debug\")\n startDebugPolling(host as unknown as Parameters[0]);\n else stopDebugPolling(host as unknown as Parameters[0]);\n void refreshActiveTab(host);\n syncUrlWithTab(host, next, false);\n}\n\nexport function setTheme(\n host: SettingsHost,\n next: ThemeMode,\n context?: ThemeTransitionContext,\n) {\n const applyTheme = () => {\n host.theme = next;\n applySettings(host, { ...host.settings, theme: next });\n applyResolvedTheme(host, resolveTheme(next));\n };\n startThemeTransition({\n nextTheme: next,\n applyTheme,\n context,\n currentTheme: host.theme,\n });\n}\n\nexport async function refreshActiveTab(host: SettingsHost) {\n if (host.tab === \"overview\") await loadOverview(host);\n if (host.tab === \"channels\") await loadChannelsTab(host);\n if (host.tab === \"instances\") await loadPresence(host as unknown as ClawdbotApp);\n if (host.tab === \"sessions\") await loadSessions(host as unknown as ClawdbotApp);\n if (host.tab === \"cron\") await loadCron(host);\n if (host.tab === \"skills\") await loadSkills(host as unknown as ClawdbotApp);\n if (host.tab === \"nodes\") {\n await loadNodes(host as unknown as ClawdbotApp);\n await loadDevices(host as unknown as ClawdbotApp);\n await loadConfig(host as unknown as ClawdbotApp);\n await loadExecApprovals(host as unknown as ClawdbotApp);\n }\n if (host.tab === \"chat\") {\n await refreshChat(host as unknown as Parameters[0]);\n scheduleChatScroll(\n host as unknown as Parameters[0],\n !host.chatHasAutoScrolled,\n );\n }\n if (host.tab === \"config\") {\n await loadConfigSchema(host as unknown as ClawdbotApp);\n await loadConfig(host as unknown as ClawdbotApp);\n }\n if (host.tab === \"debug\") {\n await loadDebug(host as unknown as ClawdbotApp);\n host.eventLog = host.eventLogBuffer;\n }\n if (host.tab === \"logs\") {\n host.logsAtBottom = true;\n await loadLogs(host as unknown as ClawdbotApp, { reset: true });\n scheduleLogsScroll(\n host as unknown as Parameters[0],\n true,\n );\n }\n}\n\nexport function inferBasePath() {\n if (typeof window === \"undefined\") return \"\";\n const configured = window.__CLAWDBOT_CONTROL_UI_BASE_PATH__;\n if (typeof configured === \"string\" && configured.trim()) {\n return normalizeBasePath(configured);\n }\n return inferBasePathFromPathname(window.location.pathname);\n}\n\nexport function syncThemeWithSettings(host: SettingsHost) {\n host.theme = host.settings.theme ?? \"system\";\n applyResolvedTheme(host, resolveTheme(host.theme));\n}\n\nexport function applyResolvedTheme(host: SettingsHost, resolved: ResolvedTheme) {\n host.themeResolved = resolved;\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n root.dataset.theme = resolved;\n root.style.colorScheme = resolved;\n}\n\nexport function attachThemeListener(host: SettingsHost) {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\n host.themeMedia = window.matchMedia(\"(prefers-color-scheme: dark)\");\n host.themeMediaHandler = (event) => {\n if (host.theme !== \"system\") return;\n applyResolvedTheme(host, event.matches ? \"dark\" : \"light\");\n };\n if (typeof host.themeMedia.addEventListener === \"function\") {\n host.themeMedia.addEventListener(\"change\", host.themeMediaHandler);\n return;\n }\n const legacy = host.themeMedia as MediaQueryList & {\n addListener: (cb: (event: MediaQueryListEvent) => void) => void;\n };\n legacy.addListener(host.themeMediaHandler);\n}\n\nexport function detachThemeListener(host: SettingsHost) {\n if (!host.themeMedia || !host.themeMediaHandler) return;\n if (typeof host.themeMedia.removeEventListener === \"function\") {\n host.themeMedia.removeEventListener(\"change\", host.themeMediaHandler);\n return;\n }\n const legacy = host.themeMedia as MediaQueryList & {\n removeListener: (cb: (event: MediaQueryListEvent) => void) => void;\n };\n legacy.removeListener(host.themeMediaHandler);\n host.themeMedia = null;\n host.themeMediaHandler = null;\n}\n\nexport function syncTabWithLocation(host: SettingsHost, replace: boolean) {\n if (typeof window === \"undefined\") return;\n const resolved = tabFromPath(window.location.pathname, host.basePath) ?? \"chat\";\n setTabFromRoute(host, resolved);\n syncUrlWithTab(host, resolved, replace);\n}\n\nexport function onPopState(host: SettingsHost) {\n if (typeof window === \"undefined\") return;\n const resolved = tabFromPath(window.location.pathname, host.basePath);\n if (!resolved) return;\n\n const url = new URL(window.location.href);\n const session = url.searchParams.get(\"session\")?.trim();\n if (session) {\n host.sessionKey = session;\n applySettings(host, {\n ...host.settings,\n sessionKey: session,\n lastActiveSessionKey: session,\n });\n }\n\n setTabFromRoute(host, resolved);\n}\n\nexport function setTabFromRoute(host: SettingsHost, next: Tab) {\n if (host.tab !== next) host.tab = next;\n if (next === \"chat\") host.chatHasAutoScrolled = false;\n if (next === \"logs\")\n startLogsPolling(host as unknown as Parameters[0]);\n else stopLogsPolling(host as unknown as Parameters[0]);\n if (next === \"debug\")\n startDebugPolling(host as unknown as Parameters[0]);\n else stopDebugPolling(host as unknown as Parameters[0]);\n if (host.connected) void refreshActiveTab(host);\n}\n\nexport function syncUrlWithTab(host: SettingsHost, tab: Tab, replace: boolean) {\n if (typeof window === \"undefined\") return;\n const targetPath = normalizePath(pathForTab(tab, host.basePath));\n const currentPath = normalizePath(window.location.pathname);\n const url = new URL(window.location.href);\n\n if (tab === \"chat\" && host.sessionKey) {\n url.searchParams.set(\"session\", host.sessionKey);\n } else {\n url.searchParams.delete(\"session\");\n }\n\n if (currentPath !== targetPath) {\n url.pathname = targetPath;\n }\n\n if (replace) {\n window.history.replaceState({}, \"\", url.toString());\n } else {\n window.history.pushState({}, \"\", url.toString());\n }\n}\n\nexport function syncUrlWithSessionKey(\n host: SettingsHost,\n sessionKey: string,\n replace: boolean,\n) {\n if (typeof window === \"undefined\") return;\n const url = new URL(window.location.href);\n url.searchParams.set(\"session\", sessionKey);\n if (replace) window.history.replaceState({}, \"\", url.toString());\n else window.history.pushState({}, \"\", url.toString());\n}\n\nexport async function loadOverview(host: SettingsHost) {\n await Promise.all([\n loadChannels(host as unknown as ClawdbotApp, false),\n loadPresence(host as unknown as ClawdbotApp),\n loadSessions(host as unknown as ClawdbotApp),\n loadCronStatus(host as unknown as ClawdbotApp),\n loadDebug(host as unknown as ClawdbotApp),\n ]);\n}\n\nexport async function loadChannelsTab(host: SettingsHost) {\n await Promise.all([\n loadChannels(host as unknown as ClawdbotApp, true),\n loadConfigSchema(host as unknown as ClawdbotApp),\n loadConfig(host as unknown as ClawdbotApp),\n ]);\n}\n\nexport async function loadCron(host: SettingsHost) {\n await Promise.all([\n loadChannels(host as unknown as ClawdbotApp, false),\n loadCronStatus(host as unknown as ClawdbotApp),\n loadCronJobs(host as unknown as ClawdbotApp),\n ]);\n}\n","import { abortChatRun, loadChatHistory, sendChatMessage } from \"./controllers/chat\";\nimport { loadSessions } from \"./controllers/sessions\";\nimport { generateUUID } from \"./uuid\";\nimport { resetToolStream } from \"./app-tool-stream\";\nimport { scheduleChatScroll } from \"./app-scroll\";\nimport { setLastActiveSessionKey } from \"./app-settings\";\nimport { normalizeBasePath } from \"./navigation\";\nimport type { GatewayHelloOk } from \"./gateway\";\nimport { parseAgentSessionKey } from \"../../../src/sessions/session-key-utils.js\";\nimport type { ClawdbotApp } from \"./app\";\n\ntype ChatHost = {\n connected: boolean;\n chatMessage: string;\n chatQueue: Array<{ id: string; text: string; createdAt: number }>;\n chatRunId: string | null;\n chatSending: boolean;\n sessionKey: string;\n basePath: string;\n hello: GatewayHelloOk | null;\n chatAvatarUrl: string | null;\n};\n\nexport function isChatBusy(host: ChatHost) {\n return host.chatSending || Boolean(host.chatRunId);\n}\n\nexport function isChatStopCommand(text: string) {\n const trimmed = text.trim();\n if (!trimmed) return false;\n const normalized = trimmed.toLowerCase();\n if (normalized === \"/stop\") return true;\n return (\n normalized === \"stop\" ||\n normalized === \"esc\" ||\n normalized === \"abort\" ||\n normalized === \"wait\" ||\n normalized === \"exit\"\n );\n}\n\nexport async function handleAbortChat(host: ChatHost) {\n if (!host.connected) return;\n host.chatMessage = \"\";\n await abortChatRun(host as unknown as ClawdbotApp);\n}\n\nfunction enqueueChatMessage(host: ChatHost, text: string) {\n const trimmed = text.trim();\n if (!trimmed) return;\n host.chatQueue = [\n ...host.chatQueue,\n {\n id: generateUUID(),\n text: trimmed,\n createdAt: Date.now(),\n },\n ];\n}\n\nasync function sendChatMessageNow(\n host: ChatHost,\n message: string,\n opts?: { previousDraft?: string; restoreDraft?: boolean },\n) {\n resetToolStream(host as unknown as Parameters[0]);\n const ok = await sendChatMessage(host as unknown as ClawdbotApp, message);\n if (!ok && opts?.previousDraft != null) {\n host.chatMessage = opts.previousDraft;\n }\n if (ok) {\n setLastActiveSessionKey(host as unknown as Parameters[0], host.sessionKey);\n }\n if (ok && opts?.restoreDraft && opts.previousDraft?.trim()) {\n host.chatMessage = opts.previousDraft;\n }\n scheduleChatScroll(host as unknown as Parameters[0]);\n if (ok && !host.chatRunId) {\n void flushChatQueue(host);\n }\n return ok;\n}\n\nasync function flushChatQueue(host: ChatHost) {\n if (!host.connected || isChatBusy(host)) return;\n const [next, ...rest] = host.chatQueue;\n if (!next) return;\n host.chatQueue = rest;\n const ok = await sendChatMessageNow(host, next.text);\n if (!ok) {\n host.chatQueue = [next, ...host.chatQueue];\n }\n}\n\nexport function removeQueuedMessage(host: ChatHost, id: string) {\n host.chatQueue = host.chatQueue.filter((item) => item.id !== id);\n}\n\nexport async function handleSendChat(\n host: ChatHost,\n messageOverride?: string,\n opts?: { restoreDraft?: boolean },\n) {\n if (!host.connected) return;\n const previousDraft = host.chatMessage;\n const message = (messageOverride ?? host.chatMessage).trim();\n if (!message) return;\n\n if (isChatStopCommand(message)) {\n await handleAbortChat(host);\n return;\n }\n\n if (messageOverride == null) {\n host.chatMessage = \"\";\n }\n\n if (isChatBusy(host)) {\n enqueueChatMessage(host, message);\n return;\n }\n\n await sendChatMessageNow(host, message, {\n previousDraft: messageOverride == null ? previousDraft : undefined,\n restoreDraft: Boolean(messageOverride && opts?.restoreDraft),\n });\n}\n\nexport async function refreshChat(host: ChatHost) {\n await Promise.all([\n loadChatHistory(host as unknown as ClawdbotApp),\n loadSessions(host as unknown as ClawdbotApp),\n refreshChatAvatar(host),\n ]);\n scheduleChatScroll(host as unknown as Parameters[0], true);\n}\n\nexport const flushChatQueueForEvent = flushChatQueue;\n\ntype SessionDefaultsSnapshot = {\n defaultAgentId?: string;\n};\n\nfunction resolveAgentIdForSession(host: ChatHost): string | null {\n const parsed = parseAgentSessionKey(host.sessionKey);\n if (parsed?.agentId) return parsed.agentId;\n const snapshot = host.hello?.snapshot as { sessionDefaults?: SessionDefaultsSnapshot } | undefined;\n const fallback = snapshot?.sessionDefaults?.defaultAgentId?.trim();\n return fallback || \"main\";\n}\n\nfunction buildAvatarMetaUrl(basePath: string, agentId: string): string {\n const base = normalizeBasePath(basePath);\n const encoded = encodeURIComponent(agentId);\n return base ? `${base}/avatar/${encoded}?meta=1` : `/avatar/${encoded}?meta=1`;\n}\n\nexport async function refreshChatAvatar(host: ChatHost) {\n if (!host.connected) {\n host.chatAvatarUrl = null;\n return;\n }\n const agentId = resolveAgentIdForSession(host);\n if (!agentId) {\n host.chatAvatarUrl = null;\n return;\n }\n host.chatAvatarUrl = null;\n const url = buildAvatarMetaUrl(host.basePath, agentId);\n try {\n const res = await fetch(url, { method: \"GET\" });\n if (!res.ok) {\n host.chatAvatarUrl = null;\n return;\n }\n const data = (await res.json()) as { avatarUrl?: unknown };\n const avatarUrl = typeof data.avatarUrl === \"string\" ? data.avatarUrl.trim() : \"\";\n host.chatAvatarUrl = avatarUrl || null;\n } catch {\n host.chatAvatarUrl = null;\n }\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e=t=>(...e)=>({_$litDirective$:t,values:e});class i{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}export{i as Directive,t as PartType,e as directive};\n//# sourceMappingURL=directive.js.map\n","import{_$LH as o}from\"./lit-html.js\";\n/**\n * @license\n * Copyright 2020 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const{I:t}=o,i=o=>o,n=o=>null===o||\"object\"!=typeof o&&\"function\"!=typeof o,e={HTML:1,SVG:2,MATHML:3},l=(o,t)=>void 0===t?void 0!==o?._$litType$:o?._$litType$===t,d=o=>null!=o?._$litType$?.h,c=o=>void 0!==o?._$litDirective$,f=o=>o?._$litDirective$,r=o=>void 0===o.strings,s=()=>document.createComment(\"\"),v=(o,n,e)=>{const l=o._$AA.parentNode,d=void 0===n?o._$AB:n._$AA;if(void 0===e){const i=l.insertBefore(s(),d),n=l.insertBefore(s(),d);e=new t(i,n,o,o.options)}else{const t=e._$AB.nextSibling,n=e._$AM,c=n!==o;if(c){let t;e._$AQ?.(o),e._$AM=o,void 0!==e._$AP&&(t=o._$AU)!==n._$AU&&e._$AP(t)}if(t!==d||c){let o=e._$AA;for(;o!==t;){const t=i(o).nextSibling;i(l).insertBefore(o,d),o=t}}}return e},u=(o,t,i=o)=>(o._$AI(t,i),o),m={},p=(o,t=m)=>o._$AH=t,M=o=>o._$AH,h=o=>{o._$AR(),o._$AA.remove()},j=o=>{o._$AR()};export{e as TemplateResultType,j as clearPart,M as getCommittedValue,f as getDirectiveClass,v as insertPart,d as isCompiledTemplateResult,c as isDirectiveResult,n as isPrimitive,r as isSingleExpression,l as isTemplateResult,h as removePart,u as setChildPartValue,p as setCommittedValue};\n//# sourceMappingURL=directive-helpers.js.map\n","import{noChange as e}from\"../lit-html.js\";import{directive as s,Directive as t,PartType as r}from\"../directive.js\";import{getCommittedValue as l,setChildPartValue as o,insertPart as i,removePart as n,setCommittedValue as f}from\"../directive-helpers.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst u=(e,s,t)=>{const r=new Map;for(let l=s;l<=t;l++)r.set(e[l],l);return r},c=s(class extends t{constructor(e){if(super(e),e.type!==r.CHILD)throw Error(\"repeat() can only be used in text expressions\")}dt(e,s,t){let r;void 0===t?t=s:void 0!==s&&(r=s);const l=[],o=[];let i=0;for(const s of e)l[i]=r?r(s,i):i,o[i]=t(s,i),i++;return{values:o,keys:l}}render(e,s,t){return this.dt(e,s,t).values}update(s,[t,r,c]){const d=l(s),{values:p,keys:a}=this.dt(t,r,c);if(!Array.isArray(d))return this.ut=a,p;const h=this.ut??=[],v=[];let m,y,x=0,j=d.length-1,k=0,w=p.length-1;for(;x<=j&&k<=w;)if(null===d[x])x++;else if(null===d[j])j--;else if(h[x]===a[k])v[k]=o(d[x],p[k]),x++,k++;else if(h[j]===a[w])v[w]=o(d[j],p[w]),j--,w--;else if(h[x]===a[w])v[w]=o(d[x],p[w]),i(s,v[w+1],d[x]),x++,w--;else if(h[j]===a[k])v[k]=o(d[j],p[k]),i(s,d[x],d[j]),j--,k++;else if(void 0===m&&(m=u(a,k,w),y=u(h,x,j)),m.has(h[x]))if(m.has(h[j])){const e=y.get(a[k]),t=void 0!==e?d[e]:null;if(null===t){const e=i(s,d[x]);o(e,p[k]),v[k]=e}else v[k]=o(t,p[k]),i(s,d[x],t),d[e]=null;k++}else n(d[j]),j--;else n(d[x]),x++;for(;k<=w;){const e=i(s,v[w+1]);o(e,p[k]),v[k++]=e}for(;x<=j;){const e=d[x++];null!==e&&n(e)}return this.ut=a,f(s,v),e}});export{c as repeat};\n//# sourceMappingURL=repeat.js.map\n","/**\n * Message normalization utilities for chat rendering.\n */\n\nimport type {\n NormalizedMessage,\n MessageContentItem,\n} from \"../types/chat-types\";\n\n/**\n * Normalize a raw message object into a consistent structure.\n */\nexport function normalizeMessage(message: unknown): NormalizedMessage {\n const m = message as Record;\n let role = typeof m.role === \"string\" ? m.role : \"unknown\";\n\n // Detect tool messages by common gateway shapes.\n // Some tool events come through as assistant role with tool_* items in the content array.\n const hasToolId =\n typeof m.toolCallId === \"string\" || typeof m.tool_call_id === \"string\";\n\n const contentRaw = m.content;\n const contentItems = Array.isArray(contentRaw) ? contentRaw : null;\n const hasToolContent =\n Array.isArray(contentItems) &&\n contentItems.some((item) => {\n const x = item as Record;\n const t = String(x.type ?? \"\").toLowerCase();\n return t === \"toolresult\" || t === \"tool_result\";\n });\n\n const hasToolName =\n typeof (m as Record).toolName === \"string\" ||\n typeof (m as Record).tool_name === \"string\";\n\n if (hasToolId || hasToolContent || hasToolName) {\n role = \"toolResult\";\n }\n\n // Extract content\n let content: MessageContentItem[] = [];\n\n if (typeof m.content === \"string\") {\n content = [{ type: \"text\", text: m.content }];\n } else if (Array.isArray(m.content)) {\n content = m.content.map((item: Record) => ({\n type: (item.type as MessageContentItem[\"type\"]) || \"text\",\n text: item.text as string | undefined,\n name: item.name as string | undefined,\n args: item.args || item.arguments,\n }));\n } else if (typeof m.text === \"string\") {\n content = [{ type: \"text\", text: m.text }];\n }\n\n const timestamp = typeof m.timestamp === \"number\" ? m.timestamp : Date.now();\n const id = typeof m.id === \"string\" ? m.id : undefined;\n\n return { role, content, timestamp, id };\n}\n\n/**\n * Normalize role for grouping purposes.\n */\nexport function normalizeRoleForGrouping(role: string): string {\n const lower = role.toLowerCase();\n // Preserve original casing when it's already a core role.\n if (role === \"user\" || role === \"User\") return role;\n if (role === \"assistant\") return \"assistant\";\n if (role === \"system\") return \"system\";\n // Keep tool-related roles distinct so the UI can style/toggle them.\n if (\n lower === \"toolresult\" ||\n lower === \"tool_result\" ||\n lower === \"tool\" ||\n lower === \"function\"\n ) {\n return \"tool\";\n }\n return role;\n}\n\n/**\n * Check if a message is a tool result message based on its role.\n */\nexport function isToolResultMessage(message: unknown): boolean {\n const m = message as Record;\n const role = typeof m.role === \"string\" ? m.role.toLowerCase() : \"\";\n return role === \"toolresult\" || role === \"tool_result\";\n}\n","import{nothing as t,noChange as i}from\"../lit-html.js\";import{directive as r,Directive as s,PartType as n}from\"../directive.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */class e extends s{constructor(i){if(super(i),this.it=t,i.type!==n.CHILD)throw Error(this.constructor.directiveName+\"() can only be used in child bindings\")}render(r){if(r===t||null==r)return this._t=void 0,this.it=r;if(r===i)return r;if(\"string\"!=typeof r)throw Error(this.constructor.directiveName+\"() called with a non-string value\");if(r===this.it)return this._t;this.it=r;const s=[r];return s.raw=s,this._t={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName=\"unsafeHTML\",e.resultType=1;const o=r(e);export{e as UnsafeHTMLDirective,o as unsafeHTML};\n//# sourceMappingURL=unsafe-html.js.map\n","/*! @license DOMPurify 3.3.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.1/LICENSE */\n\nconst {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor\n} = Object;\nlet {\n freeze,\n seal,\n create\n} = Object; // eslint-disable-line import/no-mutable-exports\nlet {\n apply,\n construct\n} = typeof Reflect !== 'undefined' && Reflect;\nif (!freeze) {\n freeze = function freeze(x) {\n return x;\n };\n}\nif (!seal) {\n seal = function seal(x) {\n return x;\n };\n}\nif (!apply) {\n apply = function apply(func, thisArg) {\n for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n args[_key - 2] = arguments[_key];\n }\n return func.apply(thisArg, args);\n };\n}\nif (!construct) {\n construct = function construct(Func) {\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n return new Func(...args);\n };\n}\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySplice = unapply(Array.prototype.splice);\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\nconst regExpTest = unapply(RegExp.prototype.test);\nconst typeErrorCreate = unconstruct(TypeError);\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param func - The function to be wrapped and called.\n * @returns A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply(func) {\n return function (thisArg) {\n if (thisArg instanceof RegExp) {\n thisArg.lastIndex = 0;\n }\n for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n args[_key3 - 1] = arguments[_key3];\n }\n return apply(func, thisArg, args);\n };\n}\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param func - The constructor function to be wrapped and called.\n * @returns A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct(Func) {\n return function () {\n for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n args[_key4] = arguments[_key4];\n }\n return construct(Func, args);\n };\n}\n/**\n * Add properties to a lookup table\n *\n * @param set - The set to which elements will be added.\n * @param array - The array containing elements to be added to the set.\n * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns The modified set with added elements.\n */\nfunction addToSet(set, array) {\n let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n element = lcElement;\n }\n }\n set[element] = true;\n }\n return set;\n}\n/**\n * Clean up an array to harden against CSPP\n *\n * @param array - The array to be cleaned.\n * @returns The cleaned version of the array\n */\nfunction cleanArray(array) {\n for (let index = 0; index < array.length; index++) {\n const isPropertyExist = objectHasOwnProperty(array, index);\n if (!isPropertyExist) {\n array[index] = null;\n }\n }\n return array;\n}\n/**\n * Shallow clone an object\n *\n * @param object - The object to be cloned.\n * @returns A new object that copies the original.\n */\nfunction clone(object) {\n const newObject = create(null);\n for (const [property, value] of entries(object)) {\n const isPropertyExist = objectHasOwnProperty(object, property);\n if (isPropertyExist) {\n if (Array.isArray(value)) {\n newObject[property] = cleanArray(value);\n } else if (value && typeof value === 'object' && value.constructor === Object) {\n newObject[property] = clone(value);\n } else {\n newObject[property] = value;\n }\n }\n }\n return newObject;\n}\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param object - The object to look up the getter function in its prototype chain.\n * @param prop - The property name for which to find the getter function.\n * @returns The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n object = getPrototypeOf(object);\n }\n function fallbackValue() {\n return null;\n }\n return fallbackValue;\n}\n\nconst html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);\nconst svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);\nconst svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nconst svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);\nconst mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nconst mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);\nconst text = freeze(['#text']);\n\nconst html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);\nconst svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'mask-type', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);\nconst mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);\nconst xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);\n\n// eslint-disable-next-line unicorn/better-regex\nconst MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nconst ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nconst TMPLIT_EXPR = seal(/\\$\\{[\\w\\W]*/gm); // eslint-disable-line unicorn/better-regex\nconst DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]+$/); // eslint-disable-line no-useless-escape\nconst ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nconst IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nconst IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nconst ATTR_WHITESPACE = seal(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nconst DOCTYPE_NAME = seal(/^html$/i);\nconst CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n\nvar EXPRESSIONS = /*#__PURE__*/Object.freeze({\n __proto__: null,\n ARIA_ATTR: ARIA_ATTR,\n ATTR_WHITESPACE: ATTR_WHITESPACE,\n CUSTOM_ELEMENT: CUSTOM_ELEMENT,\n DATA_ATTR: DATA_ATTR,\n DOCTYPE_NAME: DOCTYPE_NAME,\n ERB_EXPR: ERB_EXPR,\n IS_ALLOWED_URI: IS_ALLOWED_URI,\n IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,\n MUSTACHE_EXPR: MUSTACHE_EXPR,\n TMPLIT_EXPR: TMPLIT_EXPR\n});\n\n/* eslint-disable @typescript-eslint/indent */\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n element: 1,\n attribute: 2,\n text: 3,\n cdataSection: 4,\n entityReference: 5,\n // Deprecated\n entityNode: 6,\n // Deprecated\n progressingInstruction: 7,\n comment: 8,\n document: 9,\n documentType: 10,\n documentFragment: 11,\n notation: 12 // Deprecated\n};\nconst getGlobal = function getGlobal() {\n return typeof window === 'undefined' ? null : window;\n};\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param trustedTypes The policy factory.\n * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {\n if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {\n return null;\n }\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n createScriptURL(scriptUrl) {\n return scriptUrl;\n }\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn('TrustedTypes policy ' + policyName + ' could not be created.');\n return null;\n }\n};\nconst _createHooksMap = function _createHooksMap() {\n return {\n afterSanitizeAttributes: [],\n afterSanitizeElements: [],\n afterSanitizeShadowDOM: [],\n beforeSanitizeAttributes: [],\n beforeSanitizeElements: [],\n beforeSanitizeShadowDOM: [],\n uponSanitizeAttribute: [],\n uponSanitizeElement: [],\n uponSanitizeShadowNode: []\n };\n};\nfunction createDOMPurify() {\n let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();\n const DOMPurify = root => createDOMPurify(root);\n DOMPurify.version = '3.3.1';\n DOMPurify.removed = [];\n if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n return DOMPurify;\n }\n let {\n document\n } = window;\n const originalDocument = document;\n const currentScript = originalDocument.currentScript;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes\n } = window;\n const ElementPrototype = Element.prototype;\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const remove = lookupGetter(ElementPrototype, 'remove');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n let trustedTypesPolicy;\n let emptyHTML = '';\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName\n } = document;\n const {\n importNode\n } = originalDocument;\n let hooks = _createHooksMap();\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n CUSTOM_ELEMENT\n } = EXPRESSIONS;\n let {\n IS_ALLOWED_URI: IS_ALLOWED_URI$1\n } = EXPRESSIONS;\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);\n /*\n * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false\n }\n }));\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n /* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */\n const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {\n tagCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n attributeCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n }\n }));\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n /* Output should be safe even for XML used within HTML and alike.\n * This means, DOMPurify removes comments when containing risky content.\n */\n let SAFE_FOR_XML = true;\n /* Decide if document with ... should be returned */\n let WHOLE_DOCUMENT = false;\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n let SANITIZE_DOM = true;\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (§7.3.3)\n * - DOM Tree Accessors (§3.1.5)\n * - Form Element Parent-Child Relations (§4.10.3)\n * - Iframe srcdoc / Nested WindowProxies (§4.8.5)\n * - HTMLCollection (§4.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n /* Allowed XHTML+XML namespaces */\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);\n let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);\n let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE = null;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc = null;\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n const formElement = document.createElement('form');\n const isRegexOrFunction = function isRegexOrFunction(testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n /**\n * _parseConfig\n *\n * @param cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function _parseConfig() {\n let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;\n /* Set configuration parameters */\n ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;\n ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;\n URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});\n FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});\n USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;\n HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;\n CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, text);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, html$1);\n addToSet(ALLOWED_ATTR, html);\n }\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, svg$1);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, svgFilters);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, mathMl$1);\n addToSet(ALLOWED_ATTR, mathMl);\n addToSet(ALLOWED_ATTR, xml);\n }\n }\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (typeof cfg.ADD_TAGS === 'function') {\n EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;\n } else {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n }\n if (cfg.ADD_ATTR) {\n if (typeof cfg.ADD_ATTR === 'function') {\n EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;\n } else {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n }\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n if (cfg.ADD_FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);\n }\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.');\n }\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.');\n }\n // Overwrite existing TrustedTypes policy.\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n // Sign local variables required by `sanitize`.\n emptyHTML = trustedTypesPolicy.createHTML('');\n } else {\n // Uninitialized policy, attempt to initialize the internal dompurify policy.\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);\n }\n // If creating the internal policy succeeded sign internal variables.\n if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {\n emptyHTML = trustedTypesPolicy.createHTML('');\n }\n }\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n CONFIG = cfg;\n };\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);\n const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);\n /**\n * @param element a DOM element whose namespace is being checked\n * @returns Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function _checkValidNamespace(element) {\n let parent = getParentNode(element);\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template'\n };\n }\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n // The only way to switch from MathML to SVG is via`\n // svg if parent is either or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);\n }\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n // The only way to switch from SVG to MathML is via\n // and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);\n }\n // For XHTML and XML documents that support custom namespaces\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {\n return true;\n }\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n return false;\n };\n /**\n * _forceRemove\n *\n * @param node a DOM node\n */\n const _forceRemove = function _forceRemove(node) {\n arrayPush(DOMPurify.removed, {\n element: node\n });\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n getParentNode(node).removeChild(node);\n } catch (_) {\n remove(node);\n }\n };\n /**\n * _removeAttribute\n *\n * @param name an Attribute name\n * @param element a DOM node\n */\n const _removeAttribute = function _removeAttribute(name, element) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: element.getAttributeNode(name),\n from: element\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: element\n });\n }\n element.removeAttribute(name);\n // We void attribute values for unremovable \"is\" attributes\n if (name === 'is') {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(element);\n } catch (_) {}\n } else {\n try {\n element.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n /**\n * _initDocument\n *\n * @param dirty - a string of dirty markup\n * @return a DOM, filled with the dirty markup\n */\n const _initDocument = function _initDocument(dirty) {\n /* Create a HTML document */\n let doc = null;\n let leadingWhitespace = null;\n if (FORCE_BODY) {\n dirty = '' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty = '' + dirty + '';\n }\n const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n const body = doc.body || doc.documentElement;\n if (dirty && leadingWhitespace) {\n body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);\n }\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\n }\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n /**\n * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n *\n * @param root The root element or node to start traversing on.\n * @return The created NodeIterator\n */\n const _createNodeIterator = function _createNodeIterator(root) {\n return createNodeIterator.call(root.ownerDocument || root, root,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);\n };\n /**\n * _isClobbered\n *\n * @param element element to check for clobbering attacks\n * @return true if clobbered, false if safe\n */\n const _isClobbered = function _isClobbered(element) {\n return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function');\n };\n /**\n * Checks whether the given object is a DOM node.\n *\n * @param value object to check whether it's a DOM node\n * @return true is object is a DOM node\n */\n const _isNode = function _isNode(value) {\n return typeof Node === 'function' && value instanceof Node;\n };\n function _executeHooks(hooks, currentNode, data) {\n arrayForEach(hooks, hook => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n }\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n * @param currentNode to check for permission to exist\n * @return true if node was killed, false if left alive\n */\n const _sanitizeElements = function _sanitizeElements(currentNode) {\n let content = null;\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeElements, currentNode, null);\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(currentNode.nodeName);\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeElement, currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS\n });\n /* Detect mXSS attempts abusing namespace confusion */\n if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\\w!]/g, currentNode.textContent)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove any occurrence of processing instructions */\n if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove any kind of possibly harmful comments */\n if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\\w]/g, currentNode.data)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove element if anything forbids its presence */\n if (!(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName])) {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {\n return false;\n }\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {\n return false;\n }\n }\n /* Keep content except for bad-listed elements */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode) || currentNode.parentNode;\n const childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n for (let i = childCount - 1; i >= 0; --i) {\n const childClone = cloneNode(childNodes[i], true);\n childClone.__removalCount = (currentNode.__removalCount || 0) + 1;\n parentNode.insertBefore(childClone, getNextSibling(currentNode));\n }\n }\n }\n _forceRemove(currentNode);\n return true;\n }\n /* Check whether element has a valid namespace */\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Make sure that older browsers don't get fallback-tag mXSS */\n if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\\/no(script|embed|frames)/i, currentNode.innerHTML)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {\n /* Get the element's text content */\n content = currentNode.textContent;\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n content = stringReplace(content, expr, ' ');\n });\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, {\n element: currentNode.cloneNode()\n });\n currentNode.textContent = content;\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeElements, currentNode, null);\n return false;\n };\n /**\n * _isValidAttribute\n *\n * @param lcTag Lowercase tag name of containing element.\n * @param lcName Lowercase attribute name.\n * @param value Attribute value.\n * @return Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {\n return false;\n }\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n if (\n // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) ||\n // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {\n return false;\n } else ;\n return true;\n };\n /**\n * _isBasicCustomElement\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n *\n * @param tagName name of the tag of the node to sanitize\n * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n */\n const _isBasicCustomElement = function _isBasicCustomElement(tagName) {\n return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);\n };\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param currentNode to sanitize\n */\n const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);\n const {\n attributes\n } = currentNode;\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes || _isClobbered(currentNode)) {\n return;\n }\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n forceKeepAttr: undefined\n };\n let l = attributes.length;\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n const attr = attributes[l];\n const {\n name,\n namespaceURI,\n value: attrValue\n } = attr;\n const lcName = transformCaseFunc(name);\n const initValue = attrValue;\n let value = name === 'value' ? initValue : stringTrim(initValue);\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);\n value = hookEvent.attrValue;\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode);\n // Prefix the value and later re-create the attribute with the sanitized value\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n /* Work around a security issue with comments inside attributes */\n if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\\/(style|title|textarea)/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Make sure we cannot easily use animated hrefs, even if animations are allowed */\n if (lcName === 'attributename' && stringMatch(value, 'href')) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Work around a security issue in jQuery 3.0 */\n if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n value = stringReplace(value, expr, ' ');\n });\n }\n /* Is `value` valid for this attribute? */\n const lcTag = transformCaseFunc(currentNode.nodeName);\n if (!_isValidAttribute(lcTag, lcName, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Handle attributes that require Trusted Types */\n if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {\n if (namespaceURI) ; else {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML':\n {\n value = trustedTypesPolicy.createHTML(value);\n break;\n }\n case 'TrustedScriptURL':\n {\n value = trustedTypesPolicy.createScriptURL(value);\n break;\n }\n }\n }\n }\n /* Handle invalid data-* attribute set by try-catching it */\n if (value !== initValue) {\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n } else {\n arrayPop(DOMPurify.removed);\n }\n } catch (_) {\n _removeAttribute(name, currentNode);\n }\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);\n };\n /**\n * _sanitizeShadowDOM\n *\n * @param fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {\n let shadowNode = null;\n const shadowIterator = _createNodeIterator(fragment);\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);\n while (shadowNode = shadowIterator.nextNode()) {\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);\n /* Sanitize tags and elements */\n _sanitizeElements(shadowNode);\n /* Check attributes next */\n _sanitizeAttributes(shadowNode);\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);\n };\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty) {\n let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let body = null;\n let importedNode = null;\n let currentNode = null;\n let returnNode = null;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '';\n }\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n if (typeof dirty.toString === 'function') {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n } else {\n throw typeErrorCreate('toString is not a function');\n }\n }\n /* Return dirty HTML if DOMPurify cannot run */\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n /* Clean up removed elements */\n DOMPurify.removed = [];\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n if (IN_PLACE) {\n /* Do some early pre-sanitization to avoid unsafe root nodes */\n if (dirty.nodeName) {\n const tagName = transformCaseFunc(dirty.nodeName);\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');\n }\n }\n } else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;\n }\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n /* Get node iterator */\n const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);\n /* Now start iterating over the created document */\n while (currentNode = nodeIterator.nextNode()) {\n /* Sanitize tags and elements */\n _sanitizeElements(currentNode);\n /* Check attributes next */\n _sanitizeAttributes(currentNode);\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n }\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n return returnNode;\n }\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n /* Serialize doctype if allowed */\n if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {\n serializedHTML = '\\n' + serializedHTML;\n }\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n serializedHTML = stringReplace(serializedHTML, expr, ' ');\n });\n }\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;\n };\n DOMPurify.setConfig = function () {\n let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n arrayPush(hooks[entryPoint], hookFunction);\n };\n DOMPurify.removeHook = function (entryPoint, hookFunction) {\n if (hookFunction !== undefined) {\n const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);\n return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0];\n }\n return arrayPop(hooks[entryPoint]);\n };\n DOMPurify.removeHooks = function (entryPoint) {\n hooks[entryPoint] = [];\n };\n DOMPurify.removeAllHooks = function () {\n hooks = _createHooksMap();\n };\n return DOMPurify;\n}\nvar purify = createDOMPurify();\n\nexport { purify as default };\n//# sourceMappingURL=purify.es.mjs.map\n","/**\n * marked v17.0.1 - a markdown parser\n * Copyright (c) 2018-2025, MarkedJS. (MIT License)\n * Copyright (c) 2011-2018, Christopher Jeffrey. (MIT License)\n * https://github.com/markedjs/marked\n */\n\n/**\n * DO NOT EDIT THIS FILE\n * The code in this file is generated from files in ./src/\n */\n\nfunction L(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var T=L();function Z(u){T=u}var C={exec:()=>null};function k(u,e=\"\"){let t=typeof u==\"string\"?u:u.source,n={replace:(r,i)=>{let s=typeof i==\"string\"?i:i.source;return s=s.replace(m.caret,\"$1\"),t=t.replace(r,s),n},getRegex:()=>new RegExp(t,e)};return n}var me=(()=>{try{return!!new RegExp(\"(?<=1)(?/,blockquoteSetextReplace:/\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \\t]?/gm,listReplaceTabs:/^\\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\\[[ xX]\\] +\\S/,listReplaceTask:/^\\[[ xX]\\] +/,listTaskCheckbox:/\\[[ xX]\\]/,anyLine:/\\n.*\\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\\||\\| *$/g,tableRowBlankLine:/\\n[ \\t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^/i,startPreScriptTag:/^<(pre|code|kbd|script)(\\s|>)/i,endPreScriptTag:/^<\\/(pre|code|kbd|script)(\\s|>)/i,startAngleBracket:/^$/,pedanticHrefTitle:/^([^'\"]*[^\\s])\\s+(['\"])(.*)\\2/,unicodeAlphaNumeric:/[\\p{L}\\p{N}]/u,escapeTest:/[&<>\"']/,escapeReplace:/[&<>\"']/g,escapeTestNoEncode:/[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,escapeReplaceNoEncode:/[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,unescapeTest:/&(#(?:\\d+)|(?:#x[0-9A-Fa-f]+)|(?:\\w+));?/ig,caret:/(^|[^\\[])\\^/g,percentDecode:/%25/g,findPipe:/\\|/g,splitPipe:/ \\|/,slashPipe:/\\\\\\|/g,carriageReturn:/\\r\\n|\\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\\S*/,endingNewline:/\\n$/,listItemRegex:u=>new RegExp(`^( {0,3}${u})((?:[\t ][^\\\\n]*)?(?:\\\\n|$))`),nextBulletRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ \t][^\\\\n]*)?(?:\\\\n|$))`),hrRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`),fencesBeginRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}(?:\\`\\`\\`|~~~)`),headingBeginRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}#`),htmlBeginRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}<(?:[a-z].*>|!--)`,\"i\")},xe=/^(?:[ \\t]*(?:\\n|$))+/,be=/^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/,Re=/^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,I=/^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,Te=/^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,N=/(?:[*+-]|\\d{1,9}[.)])/,re=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,se=k(re).replace(/bull/g,N).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/\\|table/g,\"\").getRegex(),Oe=k(re).replace(/bull/g,N).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/table/g,/ {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n/).getRegex(),Q=/^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\\n)[^\\n]+)*)/,we=/^[^\\n]+/,F=/(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/,ye=k(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/).replace(\"label\",F).replace(\"title\",/(?:\"(?:\\\\\"?|[^\"\\\\])*\"|'[^'\\n]*(?:\\n[^'\\n]+)*\\n?'|\\([^()]*\\))/).getRegex(),Pe=k(/^( {0,3}bull)([ \\t][^\\n]+?)?(?:\\n|$)/).replace(/bull/g,N).getRegex(),v=\"address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul\",j=/|$))/,Se=k(\"^ {0,3}(?:<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:[^\\\\n]*\\\\n+|$)|comment[^\\\\n]*(\\\\n+|$)|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>\\\\n*|$)|\\\\n*|$)|\\\\n*|$)|)[\\\\s\\\\S]*?(?:(?:\\\\n[ \t]*)+\\\\n|$)|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \t]*)+\\\\n|$)|(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \t]*)+\\\\n|$))\",\"i\").replace(\"comment\",j).replace(\"tag\",v).replace(\"attribute\",/ +[a-zA-Z:_][\\w.:-]*(?: *= *\"[^\"\\n]*\"| *= *'[^'\\n]*'| *= *[^\\s\"'=<>`]+)?/).getRegex(),ie=k(Q).replace(\"hr\",I).replace(\"heading\",\" {0,3}#{1,6}(?:\\\\s|$)\").replace(\"|lheading\",\"\").replace(\"|table\",\"\").replace(\"blockquote\",\" {0,3}>\").replace(\"fences\",\" {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n\").replace(\"list\",\" {0,3}(?:[*+-]|1[.)]) \").replace(\"html\",\")|<(?:script|pre|style|textarea|!--)\").replace(\"tag\",v).getRegex(),$e=k(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/).replace(\"paragraph\",ie).getRegex(),U={blockquote:$e,code:be,def:ye,fences:Re,heading:Te,hr:I,html:Se,lheading:se,list:Pe,newline:xe,paragraph:ie,table:C,text:we},te=k(\"^ *([^\\\\n ].*)\\\\n {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)\").replace(\"hr\",I).replace(\"heading\",\" {0,3}#{1,6}(?:\\\\s|$)\").replace(\"blockquote\",\" {0,3}>\").replace(\"code\",\"(?: {4}| {0,3}\t)[^\\\\n]\").replace(\"fences\",\" {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n\").replace(\"list\",\" {0,3}(?:[*+-]|1[.)]) \").replace(\"html\",\")|<(?:script|pre|style|textarea|!--)\").replace(\"tag\",v).getRegex(),_e={...U,lheading:Oe,table:te,paragraph:k(Q).replace(\"hr\",I).replace(\"heading\",\" {0,3}#{1,6}(?:\\\\s|$)\").replace(\"|lheading\",\"\").replace(\"table\",te).replace(\"blockquote\",\" {0,3}>\").replace(\"fences\",\" {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n\").replace(\"list\",\" {0,3}(?:[*+-]|1[.)]) \").replace(\"html\",\")|<(?:script|pre|style|textarea|!--)\").replace(\"tag\",v).getRegex()},Le={...U,html:k(`^ *(?:comment *(?:\\\\n|\\\\s*$)|<(tag)[\\\\s\\\\S]+? *(?:\\\\n{2,}|\\\\s*$)|\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))`).replace(\"comment\",j).replace(/tag/g,\"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b\").getRegex(),def:/^ *\\[([^\\]]+)\\]: *]+)>?(?: +([\"(][^\\n]+[\")]))? *(?:\\n+|$)/,heading:/^(#{1,6})(.*)(?:\\n+|$)/,fences:C,lheading:/^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,paragraph:k(Q).replace(\"hr\",I).replace(\"heading\",` *#{1,6} *[^\n]`).replace(\"lheading\",se).replace(\"|table\",\"\").replace(\"blockquote\",\" {0,3}>\").replace(\"|fences\",\"\").replace(\"|list\",\"\").replace(\"|html\",\"\").replace(\"|tag\",\"\").getRegex()},Me=/^\\\\([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,ze=/^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,oe=/^( {2,}|\\\\)\\n(?!\\s*$)/,Ae=/^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\`+)[^`]+\\k(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/).replace(\"precode-\",me?\"(?`+)[^`]+\\k(?!`)/).replace(\"html\",/<(?! )[^<>]*?>/).getRegex(),ue=/^(?:\\*+(?:((?!\\*)punct)|[^\\s*]))|^_+(?:((?!_)punct)|([^\\s_]))/,qe=k(ue,\"u\").replace(/punct/g,D).getRegex(),ve=k(ue,\"u\").replace(/punct/g,le).getRegex(),pe=\"^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)|notPunctSpace(\\\\*+)(?=notPunctSpace)\",De=k(pe,\"gu\").replace(/notPunctSpace/g,ae).replace(/punctSpace/g,K).replace(/punct/g,D).getRegex(),He=k(pe,\"gu\").replace(/notPunctSpace/g,Ee).replace(/punctSpace/g,Ie).replace(/punct/g,le).getRegex(),Ze=k(\"^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)\",\"gu\").replace(/notPunctSpace/g,ae).replace(/punctSpace/g,K).replace(/punct/g,D).getRegex(),Ge=k(/\\\\(punct)/,\"gu\").replace(/punct/g,D).getRegex(),Ne=k(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/).replace(\"scheme\",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace(\"email\",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),Qe=k(j).replace(\"(?:-->|$)\",\"-->\").getRegex(),Fe=k(\"^comment|^|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>|^<\\\\?[\\\\s\\\\S]*?\\\\?>|^|^\").replace(\"comment\",Qe).replace(\"attribute\",/\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*\"[^\"]*\"|\\s*=\\s*'[^']*'|\\s*=\\s*[^\\s\"'=<>`]+)?/).getRegex(),q=/(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+[^`]*?`+(?!`)|[^\\[\\]\\\\`])*?/,je=k(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]*(?:\\n[ \\t]*)?)(title))?\\s*\\)/).replace(\"label\",q).replace(\"href\",/<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]*/).replace(\"title\",/\"(?:\\\\\"?|[^\"\\\\])*\"|'(?:\\\\'?|[^'\\\\])*'|\\((?:\\\\\\)?|[^)\\\\])*\\)/).getRegex(),ce=k(/^!?\\[(label)\\]\\[(ref)\\]/).replace(\"label\",q).replace(\"ref\",F).getRegex(),he=k(/^!?\\[(ref)\\](?:\\[\\])?/).replace(\"ref\",F).getRegex(),Ue=k(\"reflink|nolink(?!\\\\()\",\"g\").replace(\"reflink\",ce).replace(\"nolink\",he).getRegex(),ne=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,W={_backpedal:C,anyPunctuation:Ge,autolink:Ne,blockSkip:Be,br:oe,code:ze,del:C,emStrongLDelim:qe,emStrongRDelimAst:De,emStrongRDelimUnd:Ze,escape:Me,link:je,nolink:he,punctuation:Ce,reflink:ce,reflinkSearch:Ue,tag:Fe,text:Ae,url:C},Ke={...W,link:k(/^!?\\[(label)\\]\\((.*?)\\)/).replace(\"label\",q).getRegex(),reflink:k(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/).replace(\"label\",q).getRegex()},G={...W,emStrongRDelimAst:He,emStrongLDelim:ve,url:k(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/).replace(\"protocol\",ne).replace(\"email\",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'\"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'\"~)]+(?!$))+/,del:/^(~~?)(?=[^\\s~])((?:\\\\[\\s\\S]|[^\\\\])*?(?:\\\\[\\s\\S]|[^\\s~\\\\]))\\1(?=[^~]|$)/,text:k(/^([`~]+|[^`~])(?:(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\\":\">\",'\"':\""\",\"'\":\"'\"},ke=u=>Xe[u];function w(u,e){if(e){if(m.escapeTest.test(u))return u.replace(m.escapeReplace,ke)}else if(m.escapeTestNoEncode.test(u))return u.replace(m.escapeReplaceNoEncode,ke);return u}function X(u){try{u=encodeURI(u).replace(m.percentDecode,\"%\")}catch{return null}return u}function J(u,e){let t=u.replace(m.findPipe,(i,s,a)=>{let o=!1,l=s;for(;--l>=0&&a[l]===\"\\\\\";)o=!o;return o?\"|\":\" |\"}),n=t.split(m.splitPipe),r=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length0?-2:-1}function ge(u,e,t,n,r){let i=e.href,s=e.title||null,a=u[1].replace(r.other.outputLinkReplace,\"$1\");n.state.inLink=!0;let o={type:u[0].charAt(0)===\"!\"?\"image\":\"link\",raw:t,href:i,title:s,text:a,tokens:n.inlineTokens(a)};return n.state.inLink=!1,o}function Je(u,e,t){let n=u.match(t.other.indentCodeCompensation);if(n===null)return e;let r=n[1];return e.split(`\n`).map(i=>{let s=i.match(t.other.beginningSpace);if(s===null)return i;let[a]=s;return a.length>=r.length?i.slice(r.length):i}).join(`\n`)}var y=class{options;rules;lexer;constructor(e){this.options=e||T}space(e){let t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:\"space\",raw:t[0]}}code(e){let t=this.rules.block.code.exec(e);if(t){let n=t[0].replace(this.rules.other.codeRemoveIndent,\"\");return{type:\"code\",raw:t[0],codeBlockStyle:\"indented\",text:this.options.pedantic?n:z(n,`\n`)}}}fences(e){let t=this.rules.block.fences.exec(e);if(t){let n=t[0],r=Je(n,t[3]||\"\",this.rules);return{type:\"code\",raw:n,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,\"$1\"):t[2],text:r}}}heading(e){let t=this.rules.block.heading.exec(e);if(t){let n=t[2].trim();if(this.rules.other.endingHash.test(n)){let r=z(n,\"#\");(this.options.pedantic||!r||this.rules.other.endingSpaceChar.test(r))&&(n=r.trim())}return{type:\"heading\",raw:t[0],depth:t[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(e){let t=this.rules.block.hr.exec(e);if(t)return{type:\"hr\",raw:z(t[0],`\n`)}}blockquote(e){let t=this.rules.block.blockquote.exec(e);if(t){let n=z(t[0],`\n`).split(`\n`),r=\"\",i=\"\",s=[];for(;n.length>0;){let a=!1,o=[],l;for(l=0;l1,i={type:\"list\",raw:\"\",ordered:r,start:r?+n.slice(0,-1):\"\",loose:!1,items:[]};n=r?`\\\\d{1,9}\\\\${n.slice(-1)}`:`\\\\${n}`,this.options.pedantic&&(n=r?n:\"[*+-]\");let s=this.rules.other.listItemRegex(n),a=!1;for(;e;){let l=!1,p=\"\",c=\"\";if(!(t=s.exec(e))||this.rules.block.hr.test(e))break;p=t[0],e=e.substring(p.length);let g=t[2].split(`\n`,1)[0].replace(this.rules.other.listReplaceTabs,O=>\" \".repeat(3*O.length)),h=e.split(`\n`,1)[0],R=!g.trim(),f=0;if(this.options.pedantic?(f=2,c=g.trimStart()):R?f=t[1].length+1:(f=t[2].search(this.rules.other.nonSpaceChar),f=f>4?1:f,c=g.slice(f),f+=t[1].length),R&&this.rules.other.blankLine.test(h)&&(p+=h+`\n`,e=e.substring(h.length+1),l=!0),!l){let O=this.rules.other.nextBulletRegex(f),V=this.rules.other.hrRegex(f),Y=this.rules.other.fencesBeginRegex(f),ee=this.rules.other.headingBeginRegex(f),fe=this.rules.other.htmlBeginRegex(f);for(;e;){let H=e.split(`\n`,1)[0],A;if(h=H,this.options.pedantic?(h=h.replace(this.rules.other.listReplaceNesting,\" \"),A=h):A=h.replace(this.rules.other.tabCharGlobal,\" \"),Y.test(h)||ee.test(h)||fe.test(h)||O.test(h)||V.test(h))break;if(A.search(this.rules.other.nonSpaceChar)>=f||!h.trim())c+=`\n`+A.slice(f);else{if(R||g.replace(this.rules.other.tabCharGlobal,\" \").search(this.rules.other.nonSpaceChar)>=4||Y.test(g)||ee.test(g)||V.test(g))break;c+=`\n`+h}!R&&!h.trim()&&(R=!0),p+=H+`\n`,e=e.substring(H.length+1),g=A.slice(f)}}i.loose||(a?i.loose=!0:this.rules.other.doubleBlankLine.test(p)&&(a=!0)),i.items.push({type:\"list_item\",raw:p,task:!!this.options.gfm&&this.rules.other.listIsTask.test(c),loose:!1,text:c,tokens:[]}),i.raw+=p}let o=i.items.at(-1);if(o)o.raw=o.raw.trimEnd(),o.text=o.text.trimEnd();else return;i.raw=i.raw.trimEnd();for(let l of i.items){if(this.lexer.state.top=!1,l.tokens=this.lexer.blockTokens(l.text,[]),l.task){if(l.text=l.text.replace(this.rules.other.listReplaceTask,\"\"),l.tokens[0]?.type===\"text\"||l.tokens[0]?.type===\"paragraph\"){l.tokens[0].raw=l.tokens[0].raw.replace(this.rules.other.listReplaceTask,\"\"),l.tokens[0].text=l.tokens[0].text.replace(this.rules.other.listReplaceTask,\"\");for(let c=this.lexer.inlineQueue.length-1;c>=0;c--)if(this.rules.other.listIsTask.test(this.lexer.inlineQueue[c].src)){this.lexer.inlineQueue[c].src=this.lexer.inlineQueue[c].src.replace(this.rules.other.listReplaceTask,\"\");break}}let p=this.rules.other.listTaskCheckbox.exec(l.raw);if(p){let c={type:\"checkbox\",raw:p[0]+\" \",checked:p[0]!==\"[ ]\"};l.checked=c.checked,i.loose?l.tokens[0]&&[\"paragraph\",\"text\"].includes(l.tokens[0].type)&&\"tokens\"in l.tokens[0]&&l.tokens[0].tokens?(l.tokens[0].raw=c.raw+l.tokens[0].raw,l.tokens[0].text=c.raw+l.tokens[0].text,l.tokens[0].tokens.unshift(c)):l.tokens.unshift({type:\"paragraph\",raw:c.raw,text:c.raw,tokens:[c]}):l.tokens.unshift(c)}}if(!i.loose){let p=l.tokens.filter(g=>g.type===\"space\"),c=p.length>0&&p.some(g=>this.rules.other.anyLine.test(g.raw));i.loose=c}}if(i.loose)for(let l of i.items){l.loose=!0;for(let p of l.tokens)p.type===\"text\"&&(p.type=\"paragraph\")}return i}}html(e){let t=this.rules.block.html.exec(e);if(t)return{type:\"html\",block:!0,raw:t[0],pre:t[1]===\"pre\"||t[1]===\"script\"||t[1]===\"style\",text:t[0]}}def(e){let t=this.rules.block.def.exec(e);if(t){let n=t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal,\" \"),r=t[2]?t[2].replace(this.rules.other.hrefBrackets,\"$1\").replace(this.rules.inline.anyPunctuation,\"$1\"):\"\",i=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,\"$1\"):t[3];return{type:\"def\",tag:n,raw:t[0],href:r,title:i}}}table(e){let t=this.rules.block.table.exec(e);if(!t||!this.rules.other.tableDelimiter.test(t[2]))return;let n=J(t[1]),r=t[2].replace(this.rules.other.tableAlignChars,\"\").split(\"|\"),i=t[3]?.trim()?t[3].replace(this.rules.other.tableRowBlankLine,\"\").split(`\n`):[],s={type:\"table\",raw:t[0],header:[],align:[],rows:[]};if(n.length===r.length){for(let a of r)this.rules.other.tableAlignRight.test(a)?s.align.push(\"right\"):this.rules.other.tableAlignCenter.test(a)?s.align.push(\"center\"):this.rules.other.tableAlignLeft.test(a)?s.align.push(\"left\"):s.align.push(null);for(let a=0;a({text:o,tokens:this.lexer.inline(o),header:!1,align:s.align[l]})));return s}}lheading(e){let t=this.rules.block.lheading.exec(e);if(t)return{type:\"heading\",raw:t[0],depth:t[2].charAt(0)===\"=\"?1:2,text:t[1],tokens:this.lexer.inline(t[1])}}paragraph(e){let t=this.rules.block.paragraph.exec(e);if(t){let n=t[1].charAt(t[1].length-1)===`\n`?t[1].slice(0,-1):t[1];return{type:\"paragraph\",raw:t[0],text:n,tokens:this.lexer.inline(n)}}}text(e){let t=this.rules.block.text.exec(e);if(t)return{type:\"text\",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){let t=this.rules.inline.escape.exec(e);if(t)return{type:\"escape\",raw:t[0],text:t[1]}}tag(e){let t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&this.rules.other.startATag.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:\"html\",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){let t=this.rules.inline.link.exec(e);if(t){let n=t[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let s=z(n.slice(0,-1),\"\\\\\");if((n.length-s.length)%2===0)return}else{let s=de(t[2],\"()\");if(s===-2)return;if(s>-1){let o=(t[0].indexOf(\"!\")===0?5:4)+t[1].length+s;t[2]=t[2].substring(0,s),t[0]=t[0].substring(0,o).trim(),t[3]=\"\"}}let r=t[2],i=\"\";if(this.options.pedantic){let s=this.rules.other.pedanticHrefTitle.exec(r);s&&(r=s[1],i=s[3])}else i=t[3]?t[3].slice(1,-1):\"\";return r=r.trim(),this.rules.other.startAngleBracket.test(r)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(n)?r=r.slice(1):r=r.slice(1,-1)),ge(t,{href:r&&r.replace(this.rules.inline.anyPunctuation,\"$1\"),title:i&&i.replace(this.rules.inline.anyPunctuation,\"$1\")},t[0],this.lexer,this.rules)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){let r=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal,\" \"),i=t[r.toLowerCase()];if(!i){let s=n[0].charAt(0);return{type:\"text\",raw:s,text:s}}return ge(n,i,n[0],this.lexer,this.rules)}}emStrong(e,t,n=\"\"){let r=this.rules.inline.emStrongLDelim.exec(e);if(!r||r[3]&&n.match(this.rules.other.unicodeAlphaNumeric))return;if(!(r[1]||r[2]||\"\")||!n||this.rules.inline.punctuation.exec(n)){let s=[...r[0]].length-1,a,o,l=s,p=0,c=r[0][0]===\"*\"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,t=t.slice(-1*e.length+s);(r=c.exec(t))!=null;){if(a=r[1]||r[2]||r[3]||r[4]||r[5]||r[6],!a)continue;if(o=[...a].length,r[3]||r[4]){l+=o;continue}else if((r[5]||r[6])&&s%3&&!((s+o)%3)){p+=o;continue}if(l-=o,l>0)continue;o=Math.min(o,o+l+p);let g=[...r[0]][0].length,h=e.slice(0,s+r.index+g+o);if(Math.min(s,o)%2){let f=h.slice(1,-1);return{type:\"em\",raw:h,text:f,tokens:this.lexer.inlineTokens(f)}}let R=h.slice(2,-2);return{type:\"strong\",raw:h,text:R,tokens:this.lexer.inlineTokens(R)}}}}codespan(e){let t=this.rules.inline.code.exec(e);if(t){let n=t[2].replace(this.rules.other.newLineCharGlobal,\" \"),r=this.rules.other.nonSpaceChar.test(n),i=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return r&&i&&(n=n.substring(1,n.length-1)),{type:\"codespan\",raw:t[0],text:n}}}br(e){let t=this.rules.inline.br.exec(e);if(t)return{type:\"br\",raw:t[0]}}del(e){let t=this.rules.inline.del.exec(e);if(t)return{type:\"del\",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2])}}autolink(e){let t=this.rules.inline.autolink.exec(e);if(t){let n,r;return t[2]===\"@\"?(n=t[1],r=\"mailto:\"+n):(n=t[1],r=n),{type:\"link\",raw:t[0],text:n,href:r,tokens:[{type:\"text\",raw:n,text:n}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let n,r;if(t[2]===\"@\")n=t[0],r=\"mailto:\"+n;else{let i;do i=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??\"\";while(i!==t[0]);n=t[0],t[1]===\"www.\"?r=\"http://\"+t[0]:r=t[0]}return{type:\"link\",raw:t[0],text:n,href:r,tokens:[{type:\"text\",raw:n,text:n}]}}}inlineText(e){let t=this.rules.inline.text.exec(e);if(t){let n=this.lexer.state.inRawBlock;return{type:\"text\",raw:t[0],text:t[0],escaped:n}}}};var x=class u{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||T,this.options.tokenizer=this.options.tokenizer||new y,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let t={other:m,block:E.normal,inline:M.normal};this.options.pedantic?(t.block=E.pedantic,t.inline=M.pedantic):this.options.gfm&&(t.block=E.gfm,this.options.breaks?t.inline=M.breaks:t.inline=M.gfm),this.tokenizer.rules=t}static get rules(){return{block:E,inline:M}}static lex(e,t){return new u(t).lex(e)}static lexInline(e,t){return new u(t).inlineTokens(e)}lex(e){e=e.replace(m.carriageReturn,`\n`),this.blockTokens(e,this.tokens);for(let t=0;t(r=s.call({lexer:this},e,t))?(e=e.substring(r.raw.length),t.push(r),!0):!1))continue;if(r=this.tokenizer.space(e)){e=e.substring(r.raw.length);let s=t.at(-1);r.raw.length===1&&s!==void 0?s.raw+=`\n`:t.push(r);continue}if(r=this.tokenizer.code(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type===\"paragraph\"||s?.type===\"text\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.text,this.inlineQueue.at(-1).src=s.text):t.push(r);continue}if(r=this.tokenizer.fences(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.heading(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.hr(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.blockquote(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.list(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.html(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.def(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type===\"paragraph\"||s?.type===\"text\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.raw,this.inlineQueue.at(-1).src=s.text):this.tokens.links[r.tag]||(this.tokens.links[r.tag]={href:r.href,title:r.title},t.push(r));continue}if(r=this.tokenizer.table(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.lheading(e)){e=e.substring(r.raw.length),t.push(r);continue}let i=e;if(this.options.extensions?.startBlock){let s=1/0,a=e.slice(1),o;this.options.extensions.startBlock.forEach(l=>{o=l.call({lexer:this},a),typeof o==\"number\"&&o>=0&&(s=Math.min(s,o))}),s<1/0&&s>=0&&(i=e.substring(0,s+1))}if(this.state.top&&(r=this.tokenizer.paragraph(i))){let s=t.at(-1);n&&s?.type===\"paragraph\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):t.push(r),n=i.length!==e.length,e=e.substring(r.raw.length);continue}if(r=this.tokenizer.text(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type===\"text\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):t.push(r);continue}if(e){let s=\"Infinite loop on byte: \"+e.charCodeAt(0);if(this.options.silent){console.error(s);break}else throw new Error(s)}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){let n=e,r=null;if(this.tokens.links){let o=Object.keys(this.tokens.links);if(o.length>0)for(;(r=this.tokenizer.rules.inline.reflinkSearch.exec(n))!=null;)o.includes(r[0].slice(r[0].lastIndexOf(\"[\")+1,-1))&&(n=n.slice(0,r.index)+\"[\"+\"a\".repeat(r[0].length-2)+\"]\"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(r=this.tokenizer.rules.inline.anyPunctuation.exec(n))!=null;)n=n.slice(0,r.index)+\"++\"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);let i;for(;(r=this.tokenizer.rules.inline.blockSkip.exec(n))!=null;)i=r[2]?r[2].length:0,n=n.slice(0,r.index+i)+\"[\"+\"a\".repeat(r[0].length-i-2)+\"]\"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);n=this.options.hooks?.emStrongMask?.call({lexer:this},n)??n;let s=!1,a=\"\";for(;e;){s||(a=\"\"),s=!1;let o;if(this.options.extensions?.inline?.some(p=>(o=p.call({lexer:this},e,t))?(e=e.substring(o.raw.length),t.push(o),!0):!1))continue;if(o=this.tokenizer.escape(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.tag(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.link(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(o.raw.length);let p=t.at(-1);o.type===\"text\"&&p?.type===\"text\"?(p.raw+=o.raw,p.text+=o.text):t.push(o);continue}if(o=this.tokenizer.emStrong(e,n,a)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.codespan(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.br(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.del(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.autolink(e)){e=e.substring(o.raw.length),t.push(o);continue}if(!this.state.inLink&&(o=this.tokenizer.url(e))){e=e.substring(o.raw.length),t.push(o);continue}let l=e;if(this.options.extensions?.startInline){let p=1/0,c=e.slice(1),g;this.options.extensions.startInline.forEach(h=>{g=h.call({lexer:this},c),typeof g==\"number\"&&g>=0&&(p=Math.min(p,g))}),p<1/0&&p>=0&&(l=e.substring(0,p+1))}if(o=this.tokenizer.inlineText(l)){e=e.substring(o.raw.length),o.raw.slice(-1)!==\"_\"&&(a=o.raw.slice(-1)),s=!0;let p=t.at(-1);p?.type===\"text\"?(p.raw+=o.raw,p.text+=o.text):t.push(o);continue}if(e){let p=\"Infinite loop on byte: \"+e.charCodeAt(0);if(this.options.silent){console.error(p);break}else throw new Error(p)}}return t}};var P=class{options;parser;constructor(e){this.options=e||T}space(e){return\"\"}code({text:e,lang:t,escaped:n}){let r=(t||\"\").match(m.notSpaceStart)?.[0],i=e.replace(m.endingNewline,\"\")+`\n`;return r?'
'+(n?i:w(i,!0))+`
\n`:\"
\"+(n?i:w(i,!0))+`
\n`}blockquote({tokens:e}){return`
\n${this.parser.parse(e)}
\n`}html({text:e}){return e}def(e){return\"\"}heading({tokens:e,depth:t}){return`${this.parser.parseInline(e)}\n`}hr(e){return`
\n`}list(e){let t=e.ordered,n=e.start,r=\"\";for(let a=0;a\n`+r+\"\n`}listitem(e){return`
  • ${this.parser.parse(e.tokens)}
  • \n`}checkbox({checked:e}){return\" '}paragraph({tokens:e}){return`

    ${this.parser.parseInline(e)}

    \n`}table(e){let t=\"\",n=\"\";for(let i=0;i${r}`),`\n\n`+t+`\n`+r+`
    \n`}tablerow({text:e}){return`\n${e}\n`}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?\"th\":\"td\";return(e.align?`<${n} align=\"${e.align}\">`:`<${n}>`)+t+`\n`}strong({tokens:e}){return`${this.parser.parseInline(e)}`}em({tokens:e}){return`${this.parser.parseInline(e)}`}codespan({text:e}){return`${w(e,!0)}`}br(e){return\"
    \"}del({tokens:e}){return`${this.parser.parseInline(e)}`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=X(e);if(i===null)return r;e=i;let s='
    \"+r+\"\",s}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=X(e);if(i===null)return w(n);e=i;let s=`\"${n}\"`;return\",s}text(e){return\"tokens\"in e&&e.tokens?this.parser.parseInline(e.tokens):\"escaped\"in e&&e.escaped?e.text:w(e.text)}};var $=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return\"\"+e}image({text:e}){return\"\"+e}br(){return\"\"}checkbox({raw:e}){return e}};var b=class u{options;renderer;textRenderer;constructor(e){this.options=e||T,this.options.renderer=this.options.renderer||new P,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new $}static parse(e,t){return new u(t).parse(e)}static parseInline(e,t){return new u(t).parseInline(e)}parse(e){let t=\"\";for(let n=0;n{let a=i[s].flat(1/0);n=n.concat(this.walkTokens(a,t))}):i.tokens&&(n=n.concat(this.walkTokens(i.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let r={...n};if(r.async=this.defaults.async||r.async||!1,n.extensions&&(n.extensions.forEach(i=>{if(!i.name)throw new Error(\"extension name required\");if(\"renderer\"in i){let s=t.renderers[i.name];s?t.renderers[i.name]=function(...a){let o=i.renderer.apply(this,a);return o===!1&&(o=s.apply(this,a)),o}:t.renderers[i.name]=i.renderer}if(\"tokenizer\"in i){if(!i.level||i.level!==\"block\"&&i.level!==\"inline\")throw new Error(\"extension level must be 'block' or 'inline'\");let s=t[i.level];s?s.unshift(i.tokenizer):t[i.level]=[i.tokenizer],i.start&&(i.level===\"block\"?t.startBlock?t.startBlock.push(i.start):t.startBlock=[i.start]:i.level===\"inline\"&&(t.startInline?t.startInline.push(i.start):t.startInline=[i.start]))}\"childTokens\"in i&&i.childTokens&&(t.childTokens[i.name]=i.childTokens)}),r.extensions=t),n.renderer){let i=this.defaults.renderer||new P(this.defaults);for(let s in n.renderer){if(!(s in i))throw new Error(`renderer '${s}' does not exist`);if([\"options\",\"parser\"].includes(s))continue;let a=s,o=n.renderer[a],l=i[a];i[a]=(...p)=>{let c=o.apply(i,p);return c===!1&&(c=l.apply(i,p)),c||\"\"}}r.renderer=i}if(n.tokenizer){let i=this.defaults.tokenizer||new y(this.defaults);for(let s in n.tokenizer){if(!(s in i))throw new Error(`tokenizer '${s}' does not exist`);if([\"options\",\"rules\",\"lexer\"].includes(s))continue;let a=s,o=n.tokenizer[a],l=i[a];i[a]=(...p)=>{let c=o.apply(i,p);return c===!1&&(c=l.apply(i,p)),c}}r.tokenizer=i}if(n.hooks){let i=this.defaults.hooks||new S;for(let s in n.hooks){if(!(s in i))throw new Error(`hook '${s}' does not exist`);if([\"options\",\"block\"].includes(s))continue;let a=s,o=n.hooks[a],l=i[a];S.passThroughHooks.has(s)?i[a]=p=>{if(this.defaults.async&&S.passThroughHooksRespectAsync.has(s))return(async()=>{let g=await o.call(i,p);return l.call(i,g)})();let c=o.call(i,p);return l.call(i,c)}:i[a]=(...p)=>{if(this.defaults.async)return(async()=>{let g=await o.apply(i,p);return g===!1&&(g=await l.apply(i,p)),g})();let c=o.apply(i,p);return c===!1&&(c=l.apply(i,p)),c}}r.hooks=i}if(n.walkTokens){let i=this.defaults.walkTokens,s=n.walkTokens;r.walkTokens=function(a){let o=[];return o.push(s.call(this,a)),i&&(o=o.concat(i.call(this,a))),o}}this.defaults={...this.defaults,...r}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return x.lex(e,t??this.defaults)}parser(e,t){return b.parse(e,t??this.defaults)}parseMarkdown(e){return(n,r)=>{let i={...r},s={...this.defaults,...i},a=this.onError(!!s.silent,!!s.async);if(this.defaults.async===!0&&i.async===!1)return a(new Error(\"marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.\"));if(typeof n>\"u\"||n===null)return a(new Error(\"marked(): input parameter is undefined or null\"));if(typeof n!=\"string\")return a(new Error(\"marked(): input parameter is of type \"+Object.prototype.toString.call(n)+\", string expected\"));if(s.hooks&&(s.hooks.options=s,s.hooks.block=e),s.async)return(async()=>{let o=s.hooks?await s.hooks.preprocess(n):n,p=await(s.hooks?await s.hooks.provideLexer():e?x.lex:x.lexInline)(o,s),c=s.hooks?await s.hooks.processAllTokens(p):p;s.walkTokens&&await Promise.all(this.walkTokens(c,s.walkTokens));let h=await(s.hooks?await s.hooks.provideParser():e?b.parse:b.parseInline)(c,s);return s.hooks?await s.hooks.postprocess(h):h})().catch(a);try{s.hooks&&(n=s.hooks.preprocess(n));let l=(s.hooks?s.hooks.provideLexer():e?x.lex:x.lexInline)(n,s);s.hooks&&(l=s.hooks.processAllTokens(l)),s.walkTokens&&this.walkTokens(l,s.walkTokens);let c=(s.hooks?s.hooks.provideParser():e?b.parse:b.parseInline)(l,s);return s.hooks&&(c=s.hooks.postprocess(c)),c}catch(o){return a(o)}}}onError(e,t){return n=>{if(n.message+=`\nPlease report this to https://github.com/markedjs/marked.`,e){let r=\"

    An error occurred:

    \"+w(n.message+\"\",!0)+\"
    \";return t?Promise.resolve(r):r}if(t)return Promise.reject(n);throw n}}};var _=new B;function d(u,e){return _.parse(u,e)}d.options=d.setOptions=function(u){return _.setOptions(u),d.defaults=_.defaults,Z(d.defaults),d};d.getDefaults=L;d.defaults=T;d.use=function(...u){return _.use(...u),d.defaults=_.defaults,Z(d.defaults),d};d.walkTokens=function(u,e){return _.walkTokens(u,e)};d.parseInline=_.parseInline;d.Parser=b;d.parser=b.parse;d.Renderer=P;d.TextRenderer=$;d.Lexer=x;d.lexer=x.lex;d.Tokenizer=y;d.Hooks=S;d.parse=d;var Dt=d.options,Ht=d.setOptions,Zt=d.use,Gt=d.walkTokens,Nt=d.parseInline,Qt=d,Ft=b.parse,jt=x.lex;export{S as Hooks,x as Lexer,B as Marked,b as Parser,P as Renderer,$ as TextRenderer,y as Tokenizer,T as defaults,L as getDefaults,jt as lexer,d as marked,Dt as options,Qt as parse,Nt as parseInline,Ft as parser,Ht as setOptions,Zt as use,Gt as walkTokens};\n//# sourceMappingURL=marked.esm.js.map\n","import DOMPurify from \"dompurify\";\nimport { marked } from \"marked\";\nimport { truncateText } from \"./format\";\n\nmarked.setOptions({\n gfm: true,\n breaks: true,\n mangle: false,\n});\n\nconst allowedTags = [\n \"a\",\n \"b\",\n \"blockquote\",\n \"br\",\n \"code\",\n \"del\",\n \"em\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"hr\",\n \"i\",\n \"li\",\n \"ol\",\n \"p\",\n \"pre\",\n \"strong\",\n \"table\",\n \"tbody\",\n \"td\",\n \"th\",\n \"thead\",\n \"tr\",\n \"ul\",\n];\n\nconst allowedAttrs = [\"class\", \"href\", \"rel\", \"target\", \"title\", \"start\"];\n\nlet hooksInstalled = false;\nconst MARKDOWN_CHAR_LIMIT = 140_000;\nconst MARKDOWN_PARSE_LIMIT = 40_000;\nconst MARKDOWN_CACHE_LIMIT = 200;\nconst MARKDOWN_CACHE_MAX_CHARS = 50_000;\nconst markdownCache = new Map();\n\nfunction getCachedMarkdown(key: string): string | null {\n const cached = markdownCache.get(key);\n if (cached === undefined) return null;\n markdownCache.delete(key);\n markdownCache.set(key, cached);\n return cached;\n}\n\nfunction setCachedMarkdown(key: string, value: string) {\n markdownCache.set(key, value);\n if (markdownCache.size <= MARKDOWN_CACHE_LIMIT) return;\n const oldest = markdownCache.keys().next().value;\n if (oldest) markdownCache.delete(oldest);\n}\n\nfunction installHooks() {\n if (hooksInstalled) return;\n hooksInstalled = true;\n\n DOMPurify.addHook(\"afterSanitizeAttributes\", (node) => {\n if (!(node instanceof HTMLAnchorElement)) return;\n const href = node.getAttribute(\"href\");\n if (!href) return;\n node.setAttribute(\"rel\", \"noreferrer noopener\");\n node.setAttribute(\"target\", \"_blank\");\n });\n}\n\nexport function toSanitizedMarkdownHtml(markdown: string): string {\n const input = markdown.trim();\n if (!input) return \"\";\n installHooks();\n if (input.length <= MARKDOWN_CACHE_MAX_CHARS) {\n const cached = getCachedMarkdown(input);\n if (cached !== null) return cached;\n }\n const truncated = truncateText(input, MARKDOWN_CHAR_LIMIT);\n const suffix = truncated.truncated\n ? `\\n\\n… truncated (${truncated.total} chars, showing first ${truncated.text.length}).`\n : \"\";\n if (truncated.text.length > MARKDOWN_PARSE_LIMIT) {\n const escaped = escapeHtml(`${truncated.text}${suffix}`);\n const html = `
    ${escaped}
    `;\n const sanitized = DOMPurify.sanitize(html, {\n ALLOWED_TAGS: allowedTags,\n ALLOWED_ATTR: allowedAttrs,\n });\n if (input.length <= MARKDOWN_CACHE_MAX_CHARS) {\n setCachedMarkdown(input, sanitized);\n }\n return sanitized;\n }\n const rendered = marked.parse(`${truncated.text}${suffix}`) as string;\n const sanitized = DOMPurify.sanitize(rendered, {\n ALLOWED_TAGS: allowedTags,\n ALLOWED_ATTR: allowedAttrs,\n });\n if (input.length <= MARKDOWN_CACHE_MAX_CHARS) {\n setCachedMarkdown(input, sanitized);\n }\n return sanitized;\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(//g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n","import { html, type TemplateResult } from \"lit\";\nimport { icons } from \"../icons\";\n\nconst COPIED_FOR_MS = 1500;\nconst ERROR_FOR_MS = 2000;\nconst COPY_LABEL = \"Copy as markdown\";\nconst COPIED_LABEL = \"Copied\";\nconst ERROR_LABEL = \"Copy failed\";\n\ntype CopyButtonOptions = {\n text: () => string;\n label?: string;\n};\n\nasync function copyTextToClipboard(text: string): Promise {\n if (!text) return false;\n\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction setButtonLabel(button: HTMLButtonElement, label: string) {\n button.title = label;\n button.setAttribute(\"aria-label\", label);\n}\n\nfunction createCopyButton(options: CopyButtonOptions): TemplateResult {\n const idleLabel = options.label ?? COPY_LABEL;\n return html`\n {\n const btn = e.currentTarget as HTMLButtonElement | null;\n const iconContainer = btn?.querySelector(\n \".chat-copy-btn__icon\",\n ) as HTMLElement | null;\n\n if (!btn || btn.dataset.copying === \"1\") return;\n\n btn.dataset.copying = \"1\";\n btn.setAttribute(\"aria-busy\", \"true\");\n btn.disabled = true;\n\n const copied = await copyTextToClipboard(options.text());\n if (!btn.isConnected) return;\n\n delete btn.dataset.copying;\n btn.removeAttribute(\"aria-busy\");\n btn.disabled = false;\n\n if (!copied) {\n btn.dataset.error = \"1\";\n setButtonLabel(btn, ERROR_LABEL);\n\n window.setTimeout(() => {\n if (!btn.isConnected) return;\n delete btn.dataset.error;\n setButtonLabel(btn, idleLabel);\n }, ERROR_FOR_MS);\n return;\n }\n\n btn.dataset.copied = \"1\";\n setButtonLabel(btn, COPIED_LABEL);\n\n window.setTimeout(() => {\n if (!btn.isConnected) return;\n delete btn.dataset.copied;\n setButtonLabel(btn, idleLabel);\n }, COPIED_FOR_MS);\n }}\n >\n \n ${icons.copy}\n ${icons.check}\n \n \n `;\n}\n\nexport function renderCopyAsMarkdownButton(markdown: string): TemplateResult {\n return createCopyButton({ text: () => markdown, label: COPY_LABEL });\n}\n","import rawConfig from \"./tool-display.json\";\nimport type { IconName } from \"./icons\";\n\ntype ToolDisplayActionSpec = {\n label?: string;\n detailKeys?: string[];\n};\n\ntype ToolDisplaySpec = {\n icon?: string;\n title?: string;\n label?: string;\n detailKeys?: string[];\n actions?: Record;\n};\n\ntype ToolDisplayConfig = {\n version?: number;\n fallback?: ToolDisplaySpec;\n tools?: Record;\n};\n\nexport type ToolDisplay = {\n name: string;\n icon: IconName;\n title: string;\n label: string;\n verb?: string;\n detail?: string;\n};\n\nconst TOOL_DISPLAY_CONFIG = rawConfig as ToolDisplayConfig;\nconst FALLBACK = TOOL_DISPLAY_CONFIG.fallback ?? { icon: \"puzzle\" };\nconst TOOL_MAP = TOOL_DISPLAY_CONFIG.tools ?? {};\n\nfunction normalizeToolName(name?: string): string {\n return (name ?? \"tool\").trim();\n}\n\nfunction defaultTitle(name: string): string {\n const cleaned = name.replace(/_/g, \" \").trim();\n if (!cleaned) return \"Tool\";\n return cleaned\n .split(/\\s+/)\n .map((part) =>\n part.length <= 2 && part.toUpperCase() === part\n ? part\n : `${part.at(0)?.toUpperCase() ?? \"\"}${part.slice(1)}`,\n )\n .join(\" \");\n}\n\nfunction normalizeVerb(value?: string): string | undefined {\n const trimmed = value?.trim();\n if (!trimmed) return undefined;\n return trimmed.replace(/_/g, \" \");\n}\n\nfunction coerceDisplayValue(value: unknown): string | undefined {\n if (value === null || value === undefined) return undefined;\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const firstLine = trimmed.split(/\\r?\\n/)[0]?.trim() ?? \"\";\n if (!firstLine) return undefined;\n return firstLine.length > 160 ? `${firstLine.slice(0, 157)}…` : firstLine;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n if (Array.isArray(value)) {\n const values = value\n .map((item) => coerceDisplayValue(item))\n .filter((item): item is string => Boolean(item));\n if (values.length === 0) return undefined;\n const preview = values.slice(0, 3).join(\", \");\n return values.length > 3 ? `${preview}…` : preview;\n }\n return undefined;\n}\n\nfunction lookupValueByPath(args: unknown, path: string): unknown {\n if (!args || typeof args !== \"object\") return undefined;\n let current: unknown = args;\n for (const segment of path.split(\".\")) {\n if (!segment) return undefined;\n if (!current || typeof current !== \"object\") return undefined;\n const record = current as Record;\n current = record[segment];\n }\n return current;\n}\n\nfunction resolveDetailFromKeys(args: unknown, keys: string[]): string | undefined {\n for (const key of keys) {\n const value = lookupValueByPath(args, key);\n const display = coerceDisplayValue(value);\n if (display) return display;\n }\n return undefined;\n}\n\nfunction resolveReadDetail(args: unknown): string | undefined {\n if (!args || typeof args !== \"object\") return undefined;\n const record = args as Record;\n const path = typeof record.path === \"string\" ? record.path : undefined;\n if (!path) return undefined;\n const offset = typeof record.offset === \"number\" ? record.offset : undefined;\n const limit = typeof record.limit === \"number\" ? record.limit : undefined;\n if (offset !== undefined && limit !== undefined) {\n return `${path}:${offset}-${offset + limit}`;\n }\n return path;\n}\n\nfunction resolveWriteDetail(args: unknown): string | undefined {\n if (!args || typeof args !== \"object\") return undefined;\n const record = args as Record;\n const path = typeof record.path === \"string\" ? record.path : undefined;\n return path;\n}\n\nfunction resolveActionSpec(\n spec: ToolDisplaySpec | undefined,\n action: string | undefined,\n): ToolDisplayActionSpec | undefined {\n if (!spec || !action) return undefined;\n return spec.actions?.[action] ?? undefined;\n}\n\nexport function resolveToolDisplay(params: {\n name?: string;\n args?: unknown;\n meta?: string;\n}): ToolDisplay {\n const name = normalizeToolName(params.name);\n const key = name.toLowerCase();\n const spec = TOOL_MAP[key];\n const icon = (spec?.icon ?? FALLBACK.icon ?? \"puzzle\") as IconName;\n const title = spec?.title ?? defaultTitle(name);\n const label = spec?.label ?? name;\n const actionRaw =\n params.args && typeof params.args === \"object\"\n ? ((params.args as Record).action as string | undefined)\n : undefined;\n const action = typeof actionRaw === \"string\" ? actionRaw.trim() : undefined;\n const actionSpec = resolveActionSpec(spec, action);\n const verb = normalizeVerb(actionSpec?.label ?? action);\n\n let detail: string | undefined;\n if (key === \"read\") detail = resolveReadDetail(params.args);\n if (!detail && (key === \"write\" || key === \"edit\" || key === \"attach\")) {\n detail = resolveWriteDetail(params.args);\n }\n\n const detailKeys =\n actionSpec?.detailKeys ?? spec?.detailKeys ?? FALLBACK.detailKeys ?? [];\n if (!detail && detailKeys.length > 0) {\n detail = resolveDetailFromKeys(params.args, detailKeys);\n }\n\n if (!detail && params.meta) {\n detail = params.meta;\n }\n\n if (detail) {\n detail = shortenHomeInString(detail);\n }\n\n return {\n name,\n icon,\n title,\n label,\n verb,\n detail,\n };\n}\n\nexport function formatToolDetail(display: ToolDisplay): string | undefined {\n const parts: string[] = [];\n if (display.verb) parts.push(display.verb);\n if (display.detail) parts.push(display.detail);\n if (parts.length === 0) return undefined;\n return parts.join(\" · \");\n}\n\nexport function formatToolSummary(display: ToolDisplay): string {\n const detail = formatToolDetail(display);\n return detail ? `${display.label}: ${detail}` : display.label;\n}\n\nfunction shortenHomeInString(input: string): string {\n if (!input) return input;\n return input\n .replace(/\\/Users\\/[^/]+/g, \"~\")\n .replace(/\\/home\\/[^/]+/g, \"~\");\n}\n","/**\n * Chat-related constants for the UI layer.\n */\n\n/** Character threshold for showing tool output inline vs collapsed */\nexport const TOOL_INLINE_THRESHOLD = 80;\n\n/** Maximum lines to show in collapsed preview */\nexport const PREVIEW_MAX_LINES = 2;\n\n/** Maximum characters to show in collapsed preview */\nexport const PREVIEW_MAX_CHARS = 100;\n","/**\n * Helper functions for tool card rendering.\n */\n\nimport { PREVIEW_MAX_CHARS, PREVIEW_MAX_LINES } from \"./constants\";\n\n/**\n * Format tool output content for display in the sidebar.\n * Detects JSON and wraps it in a code block with formatting.\n */\nexport function formatToolOutputForSidebar(text: string): string {\n const trimmed = text.trim();\n // Try to detect and format JSON\n if (trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\")) {\n try {\n const parsed = JSON.parse(trimmed);\n return \"```json\\n\" + JSON.stringify(parsed, null, 2) + \"\\n```\";\n } catch {\n // Not valid JSON, return as-is\n }\n }\n return text;\n}\n\n/**\n * Get a truncated preview of tool output text.\n * Truncates to first N lines or first N characters, whichever is shorter.\n */\nexport function getTruncatedPreview(text: string): string {\n const allLines = text.split(\"\\n\");\n const lines = allLines.slice(0, PREVIEW_MAX_LINES);\n const preview = lines.join(\"\\n\");\n if (preview.length > PREVIEW_MAX_CHARS) {\n return preview.slice(0, PREVIEW_MAX_CHARS) + \"…\";\n }\n return lines.length < allLines.length ? preview + \"…\" : preview;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatToolDetail, resolveToolDisplay } from \"../tool-display\";\nimport { icons } from \"../icons\";\nimport type { ToolCard } from \"../types/chat-types\";\nimport { TOOL_INLINE_THRESHOLD } from \"./constants\";\nimport {\n formatToolOutputForSidebar,\n getTruncatedPreview,\n} from \"./tool-helpers\";\nimport { isToolResultMessage } from \"./message-normalizer\";\nimport { extractTextCached } from \"./message-extract\";\n\nexport function extractToolCards(message: unknown): ToolCard[] {\n const m = message as Record;\n const content = normalizeContent(m.content);\n const cards: ToolCard[] = [];\n\n for (const item of content) {\n const kind = String(item.type ?? \"\").toLowerCase();\n const isToolCall =\n [\"toolcall\", \"tool_call\", \"tooluse\", \"tool_use\"].includes(kind) ||\n (typeof item.name === \"string\" && item.arguments != null);\n if (isToolCall) {\n cards.push({\n kind: \"call\",\n name: (item.name as string) ?? \"tool\",\n args: coerceArgs(item.arguments ?? item.args),\n });\n }\n }\n\n for (const item of content) {\n const kind = String(item.type ?? \"\").toLowerCase();\n if (kind !== \"toolresult\" && kind !== \"tool_result\") continue;\n const text = extractToolText(item);\n const name = typeof item.name === \"string\" ? item.name : \"tool\";\n cards.push({ kind: \"result\", name, text });\n }\n\n if (\n isToolResultMessage(message) &&\n !cards.some((card) => card.kind === \"result\")\n ) {\n const name =\n (typeof m.toolName === \"string\" && m.toolName) ||\n (typeof m.tool_name === \"string\" && m.tool_name) ||\n \"tool\";\n const text = extractTextCached(message) ?? undefined;\n cards.push({ kind: \"result\", name, text });\n }\n\n return cards;\n}\n\nexport function renderToolCardSidebar(\n card: ToolCard,\n onOpenSidebar?: (content: string) => void,\n) {\n const display = resolveToolDisplay({ name: card.name, args: card.args });\n const detail = formatToolDetail(display);\n const hasText = Boolean(card.text?.trim());\n\n const canClick = Boolean(onOpenSidebar);\n const handleClick = canClick\n ? () => {\n if (hasText) {\n onOpenSidebar!(formatToolOutputForSidebar(card.text!));\n return;\n }\n const info = `## ${display.label}\\n\\n${\n detail ? `**Command:** \\`${detail}\\`\\n\\n` : \"\"\n }*No output — tool completed successfully.*`;\n onOpenSidebar!(info);\n }\n : undefined;\n\n const isShort = hasText && (card.text?.length ?? 0) <= TOOL_INLINE_THRESHOLD;\n const showCollapsed = hasText && !isShort;\n const showInline = hasText && isShort;\n const isEmpty = !hasText;\n\n return html`\n {\n if (e.key !== \"Enter\" && e.key !== \" \") return;\n e.preventDefault();\n handleClick?.();\n }\n : nothing}\n >\n
    \n
    \n ${icons[display.icon]}\n ${display.label}\n
    \n ${canClick\n ? html`${hasText ? \"View\" : \"\"} ${icons.check}`\n : nothing}\n ${isEmpty && !canClick ? html`${icons.check}` : nothing}\n
    \n ${detail\n ? html`
    ${detail}
    `\n : nothing}\n ${isEmpty\n ? html`
    Completed
    `\n : nothing}\n ${showCollapsed\n ? html`
    ${getTruncatedPreview(card.text!)}
    `\n : nothing}\n ${showInline\n ? html`
    ${card.text}
    `\n : nothing}\n
    \n `;\n}\n\nfunction normalizeContent(content: unknown): Array> {\n if (!Array.isArray(content)) return [];\n return content.filter(Boolean) as Array>;\n}\n\nfunction coerceArgs(value: unknown): unknown {\n if (typeof value !== \"string\") return value;\n const trimmed = value.trim();\n if (!trimmed) return value;\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) return value;\n try {\n return JSON.parse(trimmed);\n } catch {\n return value;\n }\n}\n\nfunction extractToolText(item: Record): string | undefined {\n if (typeof item.text === \"string\") return item.text;\n if (typeof item.content === \"string\") return item.content;\n return undefined;\n}\n","import { html, nothing } from \"lit\";\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\n\nimport type { AssistantIdentity } from \"../assistant-identity\";\nimport { toSanitizedMarkdownHtml } from \"../markdown\";\nimport type { MessageGroup } from \"../types/chat-types\";\nimport { renderCopyAsMarkdownButton } from \"./copy-as-markdown\";\nimport { isToolResultMessage, normalizeRoleForGrouping } from \"./message-normalizer\";\nimport {\n extractTextCached,\n extractThinkingCached,\n formatReasoningMarkdown,\n} from \"./message-extract\";\nimport { extractToolCards, renderToolCardSidebar } from \"./tool-cards\";\n\nexport function renderReadingIndicatorGroup(assistant?: AssistantIdentity) {\n return html`\n
    \n ${renderAvatar(\"assistant\", assistant)}\n
    \n
    \n \n \n \n
    \n
    \n
    \n `;\n}\n\nexport function renderStreamingGroup(\n text: string,\n startedAt: number,\n onOpenSidebar?: (content: string) => void,\n assistant?: AssistantIdentity,\n) {\n const timestamp = new Date(startedAt).toLocaleTimeString([], {\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n const name = assistant?.name ?? \"Assistant\";\n\n return html`\n
    \n ${renderAvatar(\"assistant\", assistant)}\n
    \n ${renderGroupedMessage(\n {\n role: \"assistant\",\n content: [{ type: \"text\", text }],\n timestamp: startedAt,\n },\n { isStreaming: true, showReasoning: false },\n onOpenSidebar,\n )}\n
    \n ${name}\n ${timestamp}\n
    \n
    \n
    \n `;\n}\n\nexport function renderMessageGroup(\n group: MessageGroup,\n opts: {\n onOpenSidebar?: (content: string) => void;\n showReasoning: boolean;\n assistantName?: string;\n assistantAvatar?: string | null;\n },\n) {\n const normalizedRole = normalizeRoleForGrouping(group.role);\n const assistantName = opts.assistantName ?? \"Assistant\";\n const who =\n normalizedRole === \"user\"\n ? \"You\"\n : normalizedRole === \"assistant\"\n ? assistantName\n : normalizedRole;\n const roleClass =\n normalizedRole === \"user\"\n ? \"user\"\n : normalizedRole === \"assistant\"\n ? \"assistant\"\n : \"other\";\n const timestamp = new Date(group.timestamp).toLocaleTimeString([], {\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n\n return html`\n
    \n ${renderAvatar(group.role, {\n name: assistantName,\n avatar: opts.assistantAvatar ?? null,\n })}\n
    \n ${group.messages.map((item, index) =>\n renderGroupedMessage(\n item.message,\n {\n isStreaming:\n group.isStreaming && index === group.messages.length - 1,\n showReasoning: opts.showReasoning,\n },\n opts.onOpenSidebar,\n ),\n )}\n
    \n ${who}\n ${timestamp}\n
    \n
    \n
    \n `;\n}\n\nfunction renderAvatar(\n role: string,\n assistant?: Pick,\n) {\n const normalized = normalizeRoleForGrouping(role);\n const assistantName = assistant?.name?.trim() || \"Assistant\";\n const assistantAvatar = assistant?.avatar?.trim() || \"\";\n const initial =\n normalized === \"user\"\n ? \"U\"\n : normalized === \"assistant\"\n ? assistantName.charAt(0).toUpperCase() || \"A\"\n : normalized === \"tool\"\n ? \"⚙\"\n : \"?\";\n const className =\n normalized === \"user\"\n ? \"user\"\n : normalized === \"assistant\"\n ? \"assistant\"\n : normalized === \"tool\"\n ? \"tool\"\n : \"other\";\n\n if (assistantAvatar && normalized === \"assistant\") {\n if (isAvatarUrl(assistantAvatar)) {\n return html``;\n }\n return html`
    ${assistantAvatar}
    `;\n }\n\n return html`
    ${initial}
    `;\n}\n\nfunction isAvatarUrl(value: string): boolean {\n return (\n /^https?:\\/\\//i.test(value) ||\n /^data:image\\//i.test(value) ||\n /^\\//.test(value) // Relative paths from avatar endpoint\n );\n}\n\nfunction renderGroupedMessage(\n message: unknown,\n opts: { isStreaming: boolean; showReasoning: boolean },\n onOpenSidebar?: (content: string) => void,\n) {\n const m = message as Record;\n const role = typeof m.role === \"string\" ? m.role : \"unknown\";\n const isToolResult =\n isToolResultMessage(message) ||\n role.toLowerCase() === \"toolresult\" ||\n role.toLowerCase() === \"tool_result\" ||\n typeof m.toolCallId === \"string\" ||\n typeof m.tool_call_id === \"string\";\n\n const toolCards = extractToolCards(message);\n const hasToolCards = toolCards.length > 0;\n\n const extractedText = extractTextCached(message);\n const extractedThinking =\n opts.showReasoning && role === \"assistant\"\n ? extractThinkingCached(message)\n : null;\n const markdownBase = extractedText?.trim() ? extractedText : null;\n const reasoningMarkdown = extractedThinking\n ? formatReasoningMarkdown(extractedThinking)\n : null;\n const markdown = markdownBase;\n const canCopyMarkdown = role === \"assistant\" && Boolean(markdown?.trim());\n\n const bubbleClasses = [\n \"chat-bubble\",\n canCopyMarkdown ? \"has-copy\" : \"\",\n opts.isStreaming ? \"streaming\" : \"\",\n \"fade-in\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n if (!markdown && hasToolCards && isToolResult) {\n return html`${toolCards.map((card) =>\n renderToolCardSidebar(card, onOpenSidebar),\n )}`;\n }\n\n if (!markdown && !hasToolCards) return nothing;\n\n return html`\n
    \n ${canCopyMarkdown ? renderCopyAsMarkdownButton(markdown!) : nothing}\n ${reasoningMarkdown\n ? html`
    ${unsafeHTML(\n toSanitizedMarkdownHtml(reasoningMarkdown),\n )}
    `\n : nothing}\n ${markdown\n ? html`
    ${unsafeHTML(toSanitizedMarkdownHtml(markdown))}
    `\n : nothing}\n ${toolCards.map((card) => renderToolCardSidebar(card, onOpenSidebar))}\n
    \n `;\n}\n","import { html, nothing } from \"lit\";\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\n\nimport { icons } from \"../icons\";\nimport { toSanitizedMarkdownHtml } from \"../markdown\";\n\nexport type MarkdownSidebarProps = {\n content: string | null;\n error: string | null;\n onClose: () => void;\n onViewRawText: () => void;\n};\n\nexport function renderMarkdownSidebar(props: MarkdownSidebarProps) {\n return html`\n
    \n
    \n
    Tool Output
    \n \n
    \n
    \n ${props.error\n ? html`\n
    ${props.error}
    \n \n `\n : props.content\n ? html`
    ${unsafeHTML(toSanitizedMarkdownHtml(props.content))}
    `\n : html`
    No content available
    `}\n
    \n
    \n `;\n}\n","import { LitElement, html, css } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\n\n/**\n * A draggable divider for resizable split views.\n * Dispatches 'resize' events with { splitRatio: number } detail.\n */\n@customElement(\"resizable-divider\")\nexport class ResizableDivider extends LitElement {\n @property({ type: Number }) splitRatio = 0.6;\n @property({ type: Number }) minRatio = 0.4;\n @property({ type: Number }) maxRatio = 0.7;\n\n private isDragging = false;\n private startX = 0;\n private startRatio = 0;\n\n static styles = css`\n :host {\n width: 4px;\n cursor: col-resize;\n background: var(--border, #333);\n transition: background 150ms ease-out;\n flex-shrink: 0;\n position: relative;\n }\n\n :host::before {\n content: \"\";\n position: absolute;\n top: 0;\n left: -4px;\n right: -4px;\n bottom: 0;\n }\n\n :host(:hover) {\n background: var(--accent, #007bff);\n }\n\n :host(.dragging) {\n background: var(--accent, #007bff);\n }\n `;\n\n render() {\n return html``;\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.addEventListener(\"mousedown\", this.handleMouseDown);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener(\"mousedown\", this.handleMouseDown);\n document.removeEventListener(\"mousemove\", this.handleMouseMove);\n document.removeEventListener(\"mouseup\", this.handleMouseUp);\n }\n\n private handleMouseDown = (e: MouseEvent) => {\n this.isDragging = true;\n this.startX = e.clientX;\n this.startRatio = this.splitRatio;\n this.classList.add(\"dragging\");\n\n document.addEventListener(\"mousemove\", this.handleMouseMove);\n document.addEventListener(\"mouseup\", this.handleMouseUp);\n\n e.preventDefault();\n };\n\n private handleMouseMove = (e: MouseEvent) => {\n if (!this.isDragging) return;\n\n const container = this.parentElement;\n if (!container) return;\n\n const containerWidth = container.getBoundingClientRect().width;\n const deltaX = e.clientX - this.startX;\n const deltaRatio = deltaX / containerWidth;\n\n let newRatio = this.startRatio + deltaRatio;\n newRatio = Math.max(this.minRatio, Math.min(this.maxRatio, newRatio));\n\n this.dispatchEvent(\n new CustomEvent(\"resize\", {\n detail: { splitRatio: newRatio },\n bubbles: true,\n composed: true,\n })\n );\n };\n\n private handleMouseUp = () => {\n this.isDragging = false;\n this.classList.remove(\"dragging\");\n\n document.removeEventListener(\"mousemove\", this.handleMouseMove);\n document.removeEventListener(\"mouseup\", this.handleMouseUp);\n };\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"resizable-divider\": ResizableDivider;\n }\n}\n","import { html, nothing } from \"lit\";\nimport { repeat } from \"lit/directives/repeat.js\";\nimport type { SessionsListResult } from \"../types\";\nimport type { ChatQueueItem } from \"../ui-types\";\nimport type { ChatItem, MessageGroup } from \"../types/chat-types\";\nimport { icons } from \"../icons\";\nimport {\n normalizeMessage,\n normalizeRoleForGrouping,\n} from \"../chat/message-normalizer\";\nimport {\n renderMessageGroup,\n renderReadingIndicatorGroup,\n renderStreamingGroup,\n} from \"../chat/grouped-render\";\nimport { renderMarkdownSidebar } from \"./markdown-sidebar\";\nimport \"../components/resizable-divider\";\n\nexport type CompactionIndicatorStatus = {\n active: boolean;\n startedAt: number | null;\n completedAt: number | null;\n};\n\nexport type ChatProps = {\n sessionKey: string;\n onSessionKeyChange: (next: string) => void;\n thinkingLevel: string | null;\n showThinking: boolean;\n loading: boolean;\n sending: boolean;\n canAbort?: boolean;\n compactionStatus?: CompactionIndicatorStatus | null;\n messages: unknown[];\n toolMessages: unknown[];\n stream: string | null;\n streamStartedAt: number | null;\n assistantAvatarUrl?: string | null;\n draft: string;\n queue: ChatQueueItem[];\n connected: boolean;\n canSend: boolean;\n disabledReason: string | null;\n error: string | null;\n sessions: SessionsListResult | null;\n // Focus mode\n focusMode: boolean;\n // Sidebar state\n sidebarOpen?: boolean;\n sidebarContent?: string | null;\n sidebarError?: string | null;\n splitRatio?: number;\n assistantName: string;\n assistantAvatar: string | null;\n // Event handlers\n onRefresh: () => void;\n onToggleFocusMode: () => void;\n onDraftChange: (next: string) => void;\n onSend: () => void;\n onAbort?: () => void;\n onQueueRemove: (id: string) => void;\n onNewSession: () => void;\n onOpenSidebar?: (content: string) => void;\n onCloseSidebar?: () => void;\n onSplitRatioChange?: (ratio: number) => void;\n onChatScroll?: (event: Event) => void;\n};\n\nconst COMPACTION_TOAST_DURATION_MS = 5000;\n\nfunction renderCompactionIndicator(status: CompactionIndicatorStatus | null | undefined) {\n if (!status) return nothing;\n \n // Show \"compacting...\" while active\n if (status.active) {\n return html`\n
    \n ${icons.loader} Compacting context...\n
    \n `;\n }\n\n // Show \"compaction complete\" briefly after completion\n if (status.completedAt) {\n const elapsed = Date.now() - status.completedAt;\n if (elapsed < COMPACTION_TOAST_DURATION_MS) {\n return html`\n
    \n ${icons.check} Context compacted\n
    \n `;\n }\n }\n \n return nothing;\n}\n\nexport function renderChat(props: ChatProps) {\n const canCompose = props.connected;\n const isBusy = props.sending || props.stream !== null;\n const canAbort = Boolean(props.canAbort && props.onAbort);\n const activeSession = props.sessions?.sessions?.find(\n (row) => row.key === props.sessionKey,\n );\n const reasoningLevel = activeSession?.reasoningLevel ?? \"off\";\n const showReasoning = props.showThinking && reasoningLevel !== \"off\";\n const assistantIdentity = {\n name: props.assistantName,\n avatar: props.assistantAvatar ?? props.assistantAvatarUrl ?? null,\n };\n\n const composePlaceholder = props.connected\n ? \"Message (↩ to send, Shift+↩ for line breaks)\"\n : \"Connect to the gateway to start chatting…\";\n\n const splitRatio = props.splitRatio ?? 0.6;\n const sidebarOpen = Boolean(props.sidebarOpen && props.onCloseSidebar);\n const thread = html`\n \n ${props.loading ? html`
    Loading chat…
    ` : nothing}\n ${repeat(buildChatItems(props), (item) => item.key, (item) => {\n if (item.kind === \"reading-indicator\") {\n return renderReadingIndicatorGroup(assistantIdentity);\n }\n\n if (item.kind === \"stream\") {\n return renderStreamingGroup(\n item.text,\n item.startedAt,\n props.onOpenSidebar,\n assistantIdentity,\n );\n }\n\n if (item.kind === \"group\") {\n return renderMessageGroup(item, {\n onOpenSidebar: props.onOpenSidebar,\n showReasoning,\n assistantName: props.assistantName,\n assistantAvatar: assistantIdentity.avatar,\n });\n }\n\n return nothing;\n })}\n
    \n `;\n\n return html`\n
    \n ${props.disabledReason\n ? html`
    ${props.disabledReason}
    `\n : nothing}\n\n ${props.error\n ? html`
    ${props.error}
    `\n : nothing}\n\n ${renderCompactionIndicator(props.compactionStatus)}\n\n ${props.focusMode\n ? html`\n \n ${icons.x}\n \n `\n : nothing}\n\n \n \n ${thread}\n
    \n\n ${sidebarOpen\n ? html`\n \n props.onSplitRatioChange?.(e.detail.splitRatio)}\n >\n
    \n ${renderMarkdownSidebar({\n content: props.sidebarContent ?? null,\n error: props.sidebarError ?? null,\n onClose: props.onCloseSidebar!,\n onViewRawText: () => {\n if (!props.sidebarContent || !props.onOpenSidebar) return;\n props.onOpenSidebar(`\\`\\`\\`\\n${props.sidebarContent}\\n\\`\\`\\``);\n },\n })}\n
    \n `\n : nothing}\n
    \n\n ${props.queue.length\n ? html`\n
    \n
    Queued (${props.queue.length})
    \n
    \n ${props.queue.map(\n (item) => html`\n
    \n
    ${item.text}
    \n props.onQueueRemove(item.id)}\n >\n ${icons.x}\n \n
    \n `,\n )}\n
    \n
    \n `\n : nothing}\n\n
    \n \n
    \n \n ${canAbort ? \"Stop\" : \"New session\"}\n \n \n ${isBusy ? \"Queue\" : \"Send\"}\n \n
    \n
    \n \n `;\n}\n\nconst CHAT_HISTORY_RENDER_LIMIT = 200;\n\nfunction groupMessages(items: ChatItem[]): Array {\n const result: Array = [];\n let currentGroup: MessageGroup | null = null;\n\n for (const item of items) {\n if (item.kind !== \"message\") {\n if (currentGroup) {\n result.push(currentGroup);\n currentGroup = null;\n }\n result.push(item);\n continue;\n }\n\n const normalized = normalizeMessage(item.message);\n const role = normalizeRoleForGrouping(normalized.role);\n const timestamp = normalized.timestamp || Date.now();\n\n if (!currentGroup || currentGroup.role !== role) {\n if (currentGroup) result.push(currentGroup);\n currentGroup = {\n kind: \"group\",\n key: `group:${role}:${item.key}`,\n role,\n messages: [{ message: item.message, key: item.key }],\n timestamp,\n isStreaming: false,\n };\n } else {\n currentGroup.messages.push({ message: item.message, key: item.key });\n }\n }\n\n if (currentGroup) result.push(currentGroup);\n return result;\n}\n\nfunction buildChatItems(props: ChatProps): Array {\n const items: ChatItem[] = [];\n const history = Array.isArray(props.messages) ? props.messages : [];\n const tools = Array.isArray(props.toolMessages) ? props.toolMessages : [];\n const historyStart = Math.max(0, history.length - CHAT_HISTORY_RENDER_LIMIT);\n if (historyStart > 0) {\n items.push({\n kind: \"message\",\n key: \"chat:history:notice\",\n message: {\n role: \"system\",\n content: `Showing last ${CHAT_HISTORY_RENDER_LIMIT} messages (${historyStart} hidden).`,\n timestamp: Date.now(),\n },\n });\n }\n for (let i = historyStart; i < history.length; i++) {\n const msg = history[i];\n const normalized = normalizeMessage(msg);\n\n if (!props.showThinking && normalized.role.toLowerCase() === \"toolresult\") {\n continue;\n }\n\n items.push({\n kind: \"message\",\n key: messageKey(msg, i),\n message: msg,\n });\n }\n if (props.showThinking) {\n for (let i = 0; i < tools.length; i++) {\n items.push({\n kind: \"message\",\n key: messageKey(tools[i], i + history.length),\n message: tools[i],\n });\n }\n }\n\n if (props.stream !== null) {\n const key = `stream:${props.sessionKey}:${props.streamStartedAt ?? \"live\"}`;\n if (props.stream.trim().length > 0) {\n items.push({\n kind: \"stream\",\n key,\n text: props.stream,\n startedAt: props.streamStartedAt ?? Date.now(),\n });\n } else {\n items.push({ kind: \"reading-indicator\", key });\n }\n }\n\n return groupMessages(items);\n}\n\nfunction messageKey(message: unknown, index: number): string {\n const m = message as Record;\n const toolCallId = typeof m.toolCallId === \"string\" ? m.toolCallId : \"\";\n if (toolCallId) return `tool:${toolCallId}`;\n const id = typeof m.id === \"string\" ? m.id : \"\";\n if (id) return `msg:${id}`;\n const messageId = typeof m.messageId === \"string\" ? m.messageId : \"\";\n if (messageId) return `msg:${messageId}`;\n const timestamp = typeof m.timestamp === \"number\" ? m.timestamp : null;\n const role = typeof m.role === \"string\" ? m.role : \"unknown\";\n if (timestamp != null) return `msg:${role}:${timestamp}:${index}`;\n return `msg:${role}:${index}`;\n}\n","import type { ConfigUiHints } from \"../types\";\n\nexport type JsonSchema = {\n type?: string | string[];\n title?: string;\n description?: string;\n properties?: Record;\n items?: JsonSchema | JsonSchema[];\n additionalProperties?: JsonSchema | boolean;\n enum?: unknown[];\n const?: unknown;\n default?: unknown;\n anyOf?: JsonSchema[];\n oneOf?: JsonSchema[];\n allOf?: JsonSchema[];\n nullable?: boolean;\n};\n\nexport function schemaType(schema: JsonSchema): string | undefined {\n if (!schema) return undefined;\n if (Array.isArray(schema.type)) {\n const filtered = schema.type.filter((t) => t !== \"null\");\n return filtered[0] ?? schema.type[0];\n }\n return schema.type;\n}\n\nexport function defaultValue(schema?: JsonSchema): unknown {\n if (!schema) return \"\";\n if (schema.default !== undefined) return schema.default;\n const type = schemaType(schema);\n switch (type) {\n case \"object\":\n return {};\n case \"array\":\n return [];\n case \"boolean\":\n return false;\n case \"number\":\n case \"integer\":\n return 0;\n case \"string\":\n return \"\";\n default:\n return \"\";\n }\n}\n\nexport function pathKey(path: Array): string {\n return path.filter((segment) => typeof segment === \"string\").join(\".\");\n}\n\nexport function hintForPath(path: Array, hints: ConfigUiHints) {\n const key = pathKey(path);\n const direct = hints[key];\n if (direct) return direct;\n const segments = key.split(\".\");\n for (const [hintKey, hint] of Object.entries(hints)) {\n if (!hintKey.includes(\"*\")) continue;\n const hintSegments = hintKey.split(\".\");\n if (hintSegments.length !== segments.length) continue;\n let match = true;\n for (let i = 0; i < segments.length; i += 1) {\n if (hintSegments[i] !== \"*\" && hintSegments[i] !== segments[i]) {\n match = false;\n break;\n }\n }\n if (match) return hint;\n }\n return undefined;\n}\n\nexport function humanize(raw: string) {\n return raw\n .replace(/_/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/\\s+/g, \" \")\n .replace(/^./, (m) => m.toUpperCase());\n}\n\nexport function isSensitivePath(path: Array): boolean {\n const key = pathKey(path).toLowerCase();\n return (\n key.includes(\"token\") ||\n key.includes(\"password\") ||\n key.includes(\"secret\") ||\n key.includes(\"apikey\") ||\n key.endsWith(\"key\")\n );\n}\n\n","import { html, nothing, type TemplateResult } from \"lit\";\nimport type { ConfigUiHints } from \"../types\";\nimport {\n defaultValue,\n hintForPath,\n humanize,\n isSensitivePath,\n pathKey,\n schemaType,\n type JsonSchema,\n} from \"./config-form.shared\";\n\nconst META_KEYS = new Set([\"title\", \"description\", \"default\", \"nullable\"]);\n\nfunction isAnySchema(schema: JsonSchema): boolean {\n const keys = Object.keys(schema ?? {}).filter((key) => !META_KEYS.has(key));\n return keys.length === 0;\n}\n\nfunction jsonValue(value: unknown): string {\n if (value === undefined) return \"\";\n try {\n return JSON.stringify(value, null, 2) ?? \"\";\n } catch {\n return \"\";\n }\n}\n\n// SVG Icons as template literals\nconst icons = {\n chevronDown: html``,\n plus: html``,\n minus: html``,\n trash: html``,\n edit: html``,\n};\n\nexport function renderNode(params: {\n schema: JsonSchema;\n value: unknown;\n path: Array;\n hints: ConfigUiHints;\n unsupported: Set;\n disabled: boolean;\n showLabel?: boolean;\n onPatch: (path: Array, value: unknown) => void;\n}): TemplateResult | typeof nothing {\n const { schema, value, path, hints, unsupported, disabled, onPatch } = params;\n const showLabel = params.showLabel ?? true;\n const type = schemaType(schema);\n const hint = hintForPath(path, hints);\n const label = hint?.label ?? schema.title ?? humanize(String(path.at(-1)));\n const help = hint?.help ?? schema.description;\n const key = pathKey(path);\n\n if (unsupported.has(key)) {\n return html`
    \n
    ${label}
    \n
    Unsupported schema node. Use Raw mode.
    \n
    `;\n }\n\n // Handle anyOf/oneOf unions\n if (schema.anyOf || schema.oneOf) {\n const variants = schema.anyOf ?? schema.oneOf ?? [];\n const nonNull = variants.filter(\n (v) => !(v.type === \"null\" || (Array.isArray(v.type) && v.type.includes(\"null\")))\n );\n\n if (nonNull.length === 1) {\n return renderNode({ ...params, schema: nonNull[0] });\n }\n\n // Check if it's a set of literal values (enum-like)\n const extractLiteral = (v: JsonSchema): unknown | undefined => {\n if (v.const !== undefined) return v.const;\n if (v.enum && v.enum.length === 1) return v.enum[0];\n return undefined;\n };\n const literals = nonNull.map(extractLiteral);\n const allLiterals = literals.every((v) => v !== undefined);\n\n if (allLiterals && literals.length > 0 && literals.length <= 5) {\n // Use segmented control for small sets\n const resolvedValue = value ?? schema.default;\n return html`\n
    \n ${showLabel ? html`` : nothing}\n ${help ? html`
    ${help}
    ` : nothing}\n
    \n ${literals.map((lit, idx) => html`\n onPatch(path, lit)}\n >\n ${String(lit)}\n \n `)}\n
    \n
    \n `;\n }\n\n if (allLiterals && literals.length > 5) {\n // Use dropdown for larger sets\n return renderSelect({ ...params, options: literals, value: value ?? schema.default });\n }\n\n // Handle mixed primitive types\n const primitiveTypes = new Set(\n nonNull.map((variant) => schemaType(variant)).filter(Boolean)\n );\n const normalizedTypes = new Set(\n [...primitiveTypes].map((v) => (v === \"integer\" ? \"number\" : v))\n );\n\n if ([...normalizedTypes].every((v) => [\"string\", \"number\", \"boolean\"].includes(v as string))) {\n const hasString = normalizedTypes.has(\"string\");\n const hasNumber = normalizedTypes.has(\"number\");\n const hasBoolean = normalizedTypes.has(\"boolean\");\n \n if (hasBoolean && normalizedTypes.size === 1) {\n return renderNode({\n ...params,\n schema: { ...schema, type: \"boolean\", anyOf: undefined, oneOf: undefined },\n });\n }\n\n if (hasString || hasNumber) {\n return renderTextInput({\n ...params,\n inputType: hasNumber && !hasString ? \"number\" : \"text\",\n });\n }\n }\n }\n\n // Enum - use segmented for small, dropdown for large\n if (schema.enum) {\n const options = schema.enum;\n if (options.length <= 5) {\n const resolvedValue = value ?? schema.default;\n return html`\n
    \n ${showLabel ? html`` : nothing}\n ${help ? html`
    ${help}
    ` : nothing}\n
    \n ${options.map((opt) => html`\n onPatch(path, opt)}\n >\n ${String(opt)}\n \n `)}\n
    \n
    \n `;\n }\n return renderSelect({ ...params, options, value: value ?? schema.default });\n }\n\n // Object type - collapsible section\n if (type === \"object\") {\n return renderObject(params);\n }\n\n // Array type\n if (type === \"array\") {\n return renderArray(params);\n }\n\n // Boolean - toggle row\n if (type === \"boolean\") {\n const displayValue = typeof value === \"boolean\" ? value : typeof schema.default === \"boolean\" ? schema.default : false;\n return html`\n \n `;\n }\n\n // Number/Integer\n if (type === \"number\" || type === \"integer\") {\n return renderNumberInput(params);\n }\n\n // String\n if (type === \"string\") {\n return renderTextInput({ ...params, inputType: \"text\" });\n }\n\n // Fallback\n return html`\n
    \n
    ${label}
    \n
    Unsupported type: ${type}. Use Raw mode.
    \n
    \n `;\n}\n\nfunction renderTextInput(params: {\n schema: JsonSchema;\n value: unknown;\n path: Array;\n hints: ConfigUiHints;\n disabled: boolean;\n showLabel?: boolean;\n inputType: \"text\" | \"number\";\n onPatch: (path: Array, value: unknown) => void;\n}): TemplateResult {\n const { schema, value, path, hints, disabled, onPatch, inputType } = params;\n const showLabel = params.showLabel ?? true;\n const hint = hintForPath(path, hints);\n const label = hint?.label ?? schema.title ?? humanize(String(path.at(-1)));\n const help = hint?.help ?? schema.description;\n const isSensitive = hint?.sensitive ?? isSensitivePath(path);\n const placeholder =\n hint?.placeholder ??\n (isSensitive ? \"••••\" : schema.default !== undefined ? `Default: ${schema.default}` : \"\");\n const displayValue = value ?? \"\";\n\n return html`\n
    \n ${showLabel ? html`` : nothing}\n ${help ? html`
    ${help}
    ` : nothing}\n
    \n {\n const raw = (e.target as HTMLInputElement).value;\n if (inputType === \"number\") {\n if (raw.trim() === \"\") {\n onPatch(path, undefined);\n return;\n }\n const parsed = Number(raw);\n onPatch(path, Number.isNaN(parsed) ? raw : parsed);\n return;\n }\n onPatch(path, raw);\n }}\n />\n ${schema.default !== undefined ? html`\n onPatch(path, schema.default)}\n >↺\n ` : nothing}\n
    \n
    \n `;\n}\n\nfunction renderNumberInput(params: {\n schema: JsonSchema;\n value: unknown;\n path: Array;\n hints: ConfigUiHints;\n disabled: boolean;\n showLabel?: boolean;\n onPatch: (path: Array, value: unknown) => void;\n}): TemplateResult {\n const { schema, value, path, hints, disabled, onPatch } = params;\n const showLabel = params.showLabel ?? true;\n const hint = hintForPath(path, hints);\n const label = hint?.label ?? schema.title ?? humanize(String(path.at(-1)));\n const help = hint?.help ?? schema.description;\n const displayValue = value ?? schema.default ?? \"\";\n const numValue = typeof displayValue === \"number\" ? displayValue : 0;\n\n return html`\n
    \n ${showLabel ? html`` : nothing}\n ${help ? html`
    ${help}
    ` : nothing}\n
    \n onPatch(path, numValue - 1)}\n >−\n {\n const raw = (e.target as HTMLInputElement).value;\n const parsed = raw === \"\" ? undefined : Number(raw);\n onPatch(path, parsed);\n }}\n />\n onPatch(path, numValue + 1)}\n >+\n
    \n
    \n `;\n}\n\nfunction renderSelect(params: {\n schema: JsonSchema;\n value: unknown;\n path: Array;\n hints: ConfigUiHints;\n disabled: boolean;\n showLabel?: boolean;\n options: unknown[];\n onPatch: (path: Array, value: unknown) => void;\n}): TemplateResult {\n const { schema, value, path, hints, disabled, options, onPatch } = params;\n const showLabel = params.showLabel ?? true;\n const hint = hintForPath(path, hints);\n const label = hint?.label ?? schema.title ?? humanize(String(path.at(-1)));\n const help = hint?.help ?? schema.description;\n const resolvedValue = value ?? schema.default;\n const currentIndex = options.findIndex(\n (opt) => opt === resolvedValue || String(opt) === String(resolvedValue),\n );\n const unset = \"__unset__\";\n\n return html`\n
    \n ${showLabel ? html`` : nothing}\n ${help ? html`
    ${help}
    ` : nothing}\n = 0 ? String(currentIndex) : unset}\n @change=${(e: Event) => {\n const val = (e.target as HTMLSelectElement).value;\n onPatch(path, val === unset ? undefined : options[Number(val)]);\n }}\n >\n \n ${options.map((opt, idx) => html`\n \n `)}\n \n
    \n `;\n}\n\nfunction renderObject(params: {\n schema: JsonSchema;\n value: unknown;\n path: Array;\n hints: ConfigUiHints;\n unsupported: Set;\n disabled: boolean;\n showLabel?: boolean;\n onPatch: (path: Array, value: unknown) => void;\n}): TemplateResult {\n const { schema, value, path, hints, unsupported, disabled, onPatch } = params;\n const showLabel = params.showLabel ?? true;\n const hint = hintForPath(path, hints);\n const label = hint?.label ?? schema.title ?? humanize(String(path.at(-1)));\n const help = hint?.help ?? schema.description;\n \n const fallback = value ?? schema.default;\n const obj = fallback && typeof fallback === \"object\" && !Array.isArray(fallback)\n ? (fallback as Record)\n : {};\n const props = schema.properties ?? {};\n const entries = Object.entries(props);\n \n // Sort by hint order\n const sorted = entries.sort((a, b) => {\n const orderA = hintForPath([...path, a[0]], hints)?.order ?? 0;\n const orderB = hintForPath([...path, b[0]], hints)?.order ?? 0;\n if (orderA !== orderB) return orderA - orderB;\n return a[0].localeCompare(b[0]);\n });\n\n const reserved = new Set(Object.keys(props));\n const additional = schema.additionalProperties;\n const allowExtra = Boolean(additional) && typeof additional === \"object\";\n\n // For top-level, don't wrap in collapsible\n if (path.length === 1) {\n return html`\n
    \n ${sorted.map(([propKey, node]) =>\n renderNode({\n schema: node,\n value: obj[propKey],\n path: [...path, propKey],\n hints,\n unsupported,\n disabled,\n onPatch,\n })\n )}\n ${allowExtra ? renderMapField({\n schema: additional as JsonSchema,\n value: obj,\n path,\n hints,\n unsupported,\n disabled,\n reservedKeys: reserved,\n onPatch,\n }) : nothing}\n
    \n `;\n }\n\n // Nested objects get collapsible treatment\n return html`\n
    \n \n ${label}\n ${icons.chevronDown}\n \n ${help ? html`
    ${help}
    ` : nothing}\n
    \n ${sorted.map(([propKey, node]) =>\n renderNode({\n schema: node,\n value: obj[propKey],\n path: [...path, propKey],\n hints,\n unsupported,\n disabled,\n onPatch,\n })\n )}\n ${allowExtra ? renderMapField({\n schema: additional as JsonSchema,\n value: obj,\n path,\n hints,\n unsupported,\n disabled,\n reservedKeys: reserved,\n onPatch,\n }) : nothing}\n
    \n
    \n `;\n}\n\nfunction renderArray(params: {\n schema: JsonSchema;\n value: unknown;\n path: Array;\n hints: ConfigUiHints;\n unsupported: Set;\n disabled: boolean;\n showLabel?: boolean;\n onPatch: (path: Array, value: unknown) => void;\n}): TemplateResult {\n const { schema, value, path, hints, unsupported, disabled, onPatch } = params;\n const showLabel = params.showLabel ?? true;\n const hint = hintForPath(path, hints);\n const label = hint?.label ?? schema.title ?? humanize(String(path.at(-1)));\n const help = hint?.help ?? schema.description;\n\n const itemsSchema = Array.isArray(schema.items) ? schema.items[0] : schema.items;\n if (!itemsSchema) {\n return html`\n
    \n
    ${label}
    \n
    Unsupported array schema. Use Raw mode.
    \n
    \n `;\n }\n\n const arr = Array.isArray(value) ? value : Array.isArray(schema.default) ? schema.default : [];\n\n return html`\n
    \n
    \n ${showLabel ? html`${label}` : nothing}\n ${arr.length} item${arr.length !== 1 ? 's' : ''}\n {\n const next = [...arr, defaultValue(itemsSchema)];\n onPatch(path, next);\n }}\n >\n ${icons.plus}\n Add\n \n
    \n ${help ? html`
    ${help}
    ` : nothing}\n \n ${arr.length === 0 ? html`\n
    \n No items yet. Click \"Add\" to create one.\n
    \n ` : html`\n
    \n ${arr.map((item, idx) => html`\n
    \n
    \n #${idx + 1}\n {\n const next = [...arr];\n next.splice(idx, 1);\n onPatch(path, next);\n }}\n >\n ${icons.trash}\n \n
    \n
    \n ${renderNode({\n schema: itemsSchema,\n value: item,\n path: [...path, idx],\n hints,\n unsupported,\n disabled,\n showLabel: false,\n onPatch,\n })}\n
    \n
    \n `)}\n
    \n `}\n
    \n `;\n}\n\nfunction renderMapField(params: {\n schema: JsonSchema;\n value: Record;\n path: Array;\n hints: ConfigUiHints;\n unsupported: Set;\n disabled: boolean;\n reservedKeys: Set;\n onPatch: (path: Array, value: unknown) => void;\n}): TemplateResult {\n const { schema, value, path, hints, unsupported, disabled, reservedKeys, onPatch } = params;\n const anySchema = isAnySchema(schema);\n const entries = Object.entries(value ?? {}).filter(([key]) => !reservedKeys.has(key));\n\n return html`\n
    \n
    \n Custom entries\n {\n const next = { ...(value ?? {}) };\n let index = 1;\n let key = `custom-${index}`;\n while (key in next) {\n index += 1;\n key = `custom-${index}`;\n }\n next[key] = anySchema ? {} : defaultValue(schema);\n onPatch(path, next);\n }}\n >\n ${icons.plus}\n Add Entry\n \n
    \n \n ${entries.length === 0 ? html`\n
    No custom entries.
    \n ` : html`\n
    \n ${entries.map(([key, entryValue]) => {\n const valuePath = [...path, key];\n const fallback = jsonValue(entryValue);\n return html`\n
    \n
    \n {\n const nextKey = (e.target as HTMLInputElement).value.trim();\n if (!nextKey || nextKey === key) return;\n const next = { ...(value ?? {}) };\n if (nextKey in next) return;\n next[nextKey] = next[key];\n delete next[key];\n onPatch(path, next);\n }}\n />\n
    \n
    \n ${anySchema\n ? html`\n {\n const target = e.target as HTMLTextAreaElement;\n const raw = target.value.trim();\n if (!raw) {\n onPatch(valuePath, undefined);\n return;\n }\n try {\n onPatch(valuePath, JSON.parse(raw));\n } catch {\n target.value = fallback;\n }\n }}\n >\n `\n : renderNode({\n schema,\n value: entryValue,\n path: valuePath,\n hints,\n unsupported,\n disabled,\n showLabel: false,\n onPatch,\n })}\n
    \n {\n const next = { ...(value ?? {}) };\n delete next[key];\n onPatch(path, next);\n }}\n >\n ${icons.trash}\n \n
    \n `;\n })}\n
    \n `}\n
    \n `;\n}\n","import { html, nothing } from \"lit\";\nimport type { ConfigUiHints } from \"../types\";\nimport { icons } from \"../icons\";\nimport {\n hintForPath,\n humanize,\n schemaType,\n type JsonSchema,\n} from \"./config-form.shared\";\nimport { renderNode } from \"./config-form.node\";\n\nexport type ConfigFormProps = {\n schema: JsonSchema | null;\n uiHints: ConfigUiHints;\n value: Record | null;\n disabled?: boolean;\n unsupportedPaths?: string[];\n searchQuery?: string;\n activeSection?: string | null;\n activeSubsection?: string | null;\n onPatch: (path: Array, value: unknown) => void;\n};\n\n// SVG Icons for section cards (Lucide-style)\nconst sectionIcons = {\n env: html``,\n update: html``,\n agents: html``,\n auth: html``,\n channels: html``,\n messages: html``,\n commands: html``,\n hooks: html``,\n skills: html``,\n tools: html``,\n gateway: html``,\n wizard: html``,\n // Additional sections\n meta: html``,\n logging: html``,\n browser: html``,\n ui: html``,\n models: html``,\n bindings: html``,\n broadcast: html``,\n audio: html``,\n session: html``,\n cron: html``,\n web: html``,\n discovery: html``,\n canvasHost: html``,\n talk: html``,\n plugins: html``,\n default: html``,\n};\n\n// Section metadata\nexport const SECTION_META: Record = {\n env: { label: \"Environment Variables\", description: \"Environment variables passed to the gateway process\" },\n update: { label: \"Updates\", description: \"Auto-update settings and release channel\" },\n agents: { label: \"Agents\", description: \"Agent configurations, models, and identities\" },\n auth: { label: \"Authentication\", description: \"API keys and authentication profiles\" },\n channels: { label: \"Channels\", description: \"Messaging channels (Telegram, Discord, Slack, etc.)\" },\n messages: { label: \"Messages\", description: \"Message handling and routing settings\" },\n commands: { label: \"Commands\", description: \"Custom slash commands\" },\n hooks: { label: \"Hooks\", description: \"Webhooks and event hooks\" },\n skills: { label: \"Skills\", description: \"Skill packs and capabilities\" },\n tools: { label: \"Tools\", description: \"Tool configurations (browser, search, etc.)\" },\n gateway: { label: \"Gateway\", description: \"Gateway server settings (port, auth, binding)\" },\n wizard: { label: \"Setup Wizard\", description: \"Setup wizard state and history\" },\n // Additional sections\n meta: { label: \"Metadata\", description: \"Gateway metadata and version information\" },\n logging: { label: \"Logging\", description: \"Log levels and output configuration\" },\n browser: { label: \"Browser\", description: \"Browser automation settings\" },\n ui: { label: \"UI\", description: \"User interface preferences\" },\n models: { label: \"Models\", description: \"AI model configurations and providers\" },\n bindings: { label: \"Bindings\", description: \"Key bindings and shortcuts\" },\n broadcast: { label: \"Broadcast\", description: \"Broadcast and notification settings\" },\n audio: { label: \"Audio\", description: \"Audio input/output settings\" },\n session: { label: \"Session\", description: \"Session management and persistence\" },\n cron: { label: \"Cron\", description: \"Scheduled tasks and automation\" },\n web: { label: \"Web\", description: \"Web server and API settings\" },\n discovery: { label: \"Discovery\", description: \"Service discovery and networking\" },\n canvasHost: { label: \"Canvas Host\", description: \"Canvas rendering and display\" },\n talk: { label: \"Talk\", description: \"Voice and speech settings\" },\n plugins: { label: \"Plugins\", description: \"Plugin management and extensions\" },\n};\n\nfunction getSectionIcon(key: string) {\n return sectionIcons[key as keyof typeof sectionIcons] ?? sectionIcons.default;\n}\n\nfunction matchesSearch(key: string, schema: JsonSchema, query: string): boolean {\n if (!query) return true;\n const q = query.toLowerCase();\n const meta = SECTION_META[key];\n \n // Check key name\n if (key.toLowerCase().includes(q)) return true;\n \n // Check label and description\n if (meta) {\n if (meta.label.toLowerCase().includes(q)) return true;\n if (meta.description.toLowerCase().includes(q)) return true;\n }\n \n return schemaMatches(schema, q);\n}\n\nfunction schemaMatches(schema: JsonSchema, query: string): boolean {\n if (schema.title?.toLowerCase().includes(query)) return true;\n if (schema.description?.toLowerCase().includes(query)) return true;\n if (schema.enum?.some((value) => String(value).toLowerCase().includes(query))) return true;\n\n if (schema.properties) {\n for (const [propKey, propSchema] of Object.entries(schema.properties)) {\n if (propKey.toLowerCase().includes(query)) return true;\n if (schemaMatches(propSchema, query)) return true;\n }\n }\n\n if (schema.items) {\n const items = Array.isArray(schema.items) ? schema.items : [schema.items];\n for (const item of items) {\n if (item && schemaMatches(item, query)) return true;\n }\n }\n\n if (schema.additionalProperties && typeof schema.additionalProperties === \"object\") {\n if (schemaMatches(schema.additionalProperties, query)) return true;\n }\n\n const unions = schema.anyOf ?? schema.oneOf ?? schema.allOf;\n if (unions) {\n for (const entry of unions) {\n if (entry && schemaMatches(entry, query)) return true;\n }\n }\n\n return false;\n}\n\nexport function renderConfigForm(props: ConfigFormProps) {\n if (!props.schema) {\n return html`
    Schema unavailable.
    `;\n }\n const schema = props.schema;\n const value = props.value ?? {};\n if (schemaType(schema) !== \"object\" || !schema.properties) {\n return html`
    Unsupported schema. Use Raw.
    `;\n }\n const unsupported = new Set(props.unsupportedPaths ?? []);\n const properties = schema.properties;\n const searchQuery = props.searchQuery ?? \"\";\n const activeSection = props.activeSection;\n const activeSubsection = props.activeSubsection ?? null;\n\n const entries = Object.entries(properties).sort((a, b) => {\n const orderA = hintForPath([a[0]], props.uiHints)?.order ?? 50;\n const orderB = hintForPath([b[0]], props.uiHints)?.order ?? 50;\n if (orderA !== orderB) return orderA - orderB;\n return a[0].localeCompare(b[0]);\n });\n\n const filteredEntries = entries.filter(([key, node]) => {\n if (activeSection && key !== activeSection) return false;\n if (searchQuery && !matchesSearch(key, node, searchQuery)) return false;\n return true;\n });\n\n let subsectionContext:\n | { sectionKey: string; subsectionKey: string; schema: JsonSchema }\n | null = null;\n if (activeSection && activeSubsection && filteredEntries.length === 1) {\n const sectionSchema = filteredEntries[0]?.[1];\n if (\n sectionSchema &&\n schemaType(sectionSchema) === \"object\" &&\n sectionSchema.properties &&\n sectionSchema.properties[activeSubsection]\n ) {\n subsectionContext = {\n sectionKey: activeSection,\n subsectionKey: activeSubsection,\n schema: sectionSchema.properties[activeSubsection],\n };\n }\n }\n\n if (filteredEntries.length === 0) {\n return html`\n
    \n
    ${icons.search}
    \n
    \n ${searchQuery \n ? `No settings match \"${searchQuery}\"` \n : \"No settings in this section\"}\n
    \n
    \n `;\n }\n\n return html`\n
    \n ${subsectionContext\n ? (() => {\n const { sectionKey, subsectionKey, schema: node } = subsectionContext;\n const hint = hintForPath([sectionKey, subsectionKey], props.uiHints);\n const label = hint?.label ?? node.title ?? humanize(subsectionKey);\n const description = hint?.help ?? node.description ?? \"\";\n const sectionValue = (value as Record)[sectionKey];\n const scopedValue =\n sectionValue && typeof sectionValue === \"object\"\n ? (sectionValue as Record)[subsectionKey]\n : undefined;\n const id = `config-section-${sectionKey}-${subsectionKey}`;\n return html`\n
    \n
    \n ${getSectionIcon(sectionKey)}\n
    \n

    ${label}

    \n ${description\n ? html`

    ${description}

    `\n : nothing}\n
    \n
    \n
    \n ${renderNode({\n schema: node,\n value: scopedValue,\n path: [sectionKey, subsectionKey],\n hints: props.uiHints,\n unsupported,\n disabled: props.disabled ?? false,\n showLabel: false,\n onPatch: props.onPatch,\n })}\n
    \n
    \n `;\n })()\n : filteredEntries.map(([key, node]) => {\n const meta = SECTION_META[key] ?? {\n label: key.charAt(0).toUpperCase() + key.slice(1),\n description: node.description ?? \"\",\n };\n\n return html`\n
    \n
    \n ${getSectionIcon(key)}\n
    \n

    ${meta.label}

    \n ${meta.description\n ? html`

    ${meta.description}

    `\n : nothing}\n
    \n
    \n
    \n ${renderNode({\n schema: node,\n value: (value as Record)[key],\n path: [key],\n hints: props.uiHints,\n unsupported,\n disabled: props.disabled ?? false,\n showLabel: false,\n onPatch: props.onPatch,\n })}\n
    \n
    \n `;\n })}\n
    \n `;\n}\n","import { pathKey, schemaType, type JsonSchema } from \"./config-form.shared\";\n\nexport type ConfigSchemaAnalysis = {\n schema: JsonSchema | null;\n unsupportedPaths: string[];\n};\n\nconst META_KEYS = new Set([\"title\", \"description\", \"default\", \"nullable\"]);\n\nfunction isAnySchema(schema: JsonSchema): boolean {\n const keys = Object.keys(schema ?? {}).filter((key) => !META_KEYS.has(key));\n return keys.length === 0;\n}\n\nfunction normalizeEnum(values: unknown[]): { enumValues: unknown[]; nullable: boolean } {\n const filtered = values.filter((value) => value != null);\n const nullable = filtered.length !== values.length;\n const enumValues: unknown[] = [];\n for (const value of filtered) {\n if (!enumValues.some((existing) => Object.is(existing, value))) {\n enumValues.push(value);\n }\n }\n return { enumValues, nullable };\n}\n\nexport function analyzeConfigSchema(raw: unknown): ConfigSchemaAnalysis {\n if (!raw || typeof raw !== \"object\") {\n return { schema: null, unsupportedPaths: [\"\"] };\n }\n return normalizeSchemaNode(raw as JsonSchema, []);\n}\n\nfunction normalizeSchemaNode(\n schema: JsonSchema,\n path: Array,\n): ConfigSchemaAnalysis {\n const unsupported = new Set();\n const normalized: JsonSchema = { ...schema };\n const pathLabel = pathKey(path) || \"\";\n\n if (schema.anyOf || schema.oneOf || schema.allOf) {\n const union = normalizeUnion(schema, path);\n if (union) return union;\n return { schema, unsupportedPaths: [pathLabel] };\n }\n\n const nullable = Array.isArray(schema.type) && schema.type.includes(\"null\");\n const type =\n schemaType(schema) ??\n (schema.properties || schema.additionalProperties ? \"object\" : undefined);\n normalized.type = type ?? schema.type;\n normalized.nullable = nullable || schema.nullable;\n\n if (normalized.enum) {\n const { enumValues, nullable: enumNullable } = normalizeEnum(normalized.enum);\n normalized.enum = enumValues;\n if (enumNullable) normalized.nullable = true;\n if (enumValues.length === 0) unsupported.add(pathLabel);\n }\n\n if (type === \"object\") {\n const properties = schema.properties ?? {};\n const normalizedProps: Record = {};\n for (const [key, value] of Object.entries(properties)) {\n const res = normalizeSchemaNode(value, [...path, key]);\n if (res.schema) normalizedProps[key] = res.schema;\n for (const entry of res.unsupportedPaths) unsupported.add(entry);\n }\n normalized.properties = normalizedProps;\n\n if (schema.additionalProperties === true) {\n unsupported.add(pathLabel);\n } else if (schema.additionalProperties === false) {\n normalized.additionalProperties = false;\n } else if (\n schema.additionalProperties &&\n typeof schema.additionalProperties === \"object\"\n ) {\n if (!isAnySchema(schema.additionalProperties as JsonSchema)) {\n const res = normalizeSchemaNode(\n schema.additionalProperties as JsonSchema,\n [...path, \"*\"],\n );\n normalized.additionalProperties =\n res.schema ?? (schema.additionalProperties as JsonSchema);\n if (res.unsupportedPaths.length > 0) unsupported.add(pathLabel);\n }\n }\n } else if (type === \"array\") {\n const itemsSchema = Array.isArray(schema.items)\n ? schema.items[0]\n : schema.items;\n if (!itemsSchema) {\n unsupported.add(pathLabel);\n } else {\n const res = normalizeSchemaNode(itemsSchema, [...path, \"*\"]);\n normalized.items = res.schema ?? itemsSchema;\n if (res.unsupportedPaths.length > 0) unsupported.add(pathLabel);\n }\n } else if (\n type !== \"string\" &&\n type !== \"number\" &&\n type !== \"integer\" &&\n type !== \"boolean\" &&\n !normalized.enum\n ) {\n unsupported.add(pathLabel);\n }\n\n return {\n schema: normalized,\n unsupportedPaths: Array.from(unsupported),\n };\n}\n\nfunction normalizeUnion(\n schema: JsonSchema,\n path: Array,\n): ConfigSchemaAnalysis | null {\n if (schema.allOf) return null;\n const union = schema.anyOf ?? schema.oneOf;\n if (!union) return null;\n\n const literals: unknown[] = [];\n const remaining: JsonSchema[] = [];\n let nullable = false;\n\n for (const entry of union) {\n if (!entry || typeof entry !== \"object\") return null;\n if (Array.isArray(entry.enum)) {\n const { enumValues, nullable: enumNullable } = normalizeEnum(entry.enum);\n literals.push(...enumValues);\n if (enumNullable) nullable = true;\n continue;\n }\n if (\"const\" in entry) {\n if (entry.const == null) {\n nullable = true;\n continue;\n }\n literals.push(entry.const);\n continue;\n }\n if (schemaType(entry) === \"null\") {\n nullable = true;\n continue;\n }\n remaining.push(entry);\n }\n\n if (literals.length > 0 && remaining.length === 0) {\n const unique: unknown[] = [];\n for (const value of literals) {\n if (!unique.some((existing) => Object.is(existing, value))) {\n unique.push(value);\n }\n }\n return {\n schema: {\n ...schema,\n enum: unique,\n nullable,\n anyOf: undefined,\n oneOf: undefined,\n allOf: undefined,\n },\n unsupportedPaths: [],\n };\n }\n\n if (remaining.length === 1) {\n const res = normalizeSchemaNode(remaining[0], path);\n if (res.schema) {\n res.schema.nullable = nullable || res.schema.nullable;\n }\n return res;\n }\n\n const primitiveTypes = [\"string\", \"number\", \"integer\", \"boolean\"];\n if (\n remaining.length > 0 &&\n literals.length === 0 &&\n remaining.every((entry) => entry.type && primitiveTypes.includes(String(entry.type)))\n ) {\n return {\n schema: {\n ...schema,\n nullable,\n },\n unsupportedPaths: [],\n };\n }\n\n return null;\n}\n","import { html, nothing } from \"lit\";\nimport type { ConfigUiHints } from \"../types\";\nimport { analyzeConfigSchema, renderConfigForm, SECTION_META } from \"./config-form\";\nimport {\n hintForPath,\n humanize,\n schemaType,\n type JsonSchema,\n} from \"./config-form.shared\";\n\nexport type ConfigProps = {\n raw: string;\n originalRaw: string;\n valid: boolean | null;\n issues: unknown[];\n loading: boolean;\n saving: boolean;\n applying: boolean;\n updating: boolean;\n connected: boolean;\n schema: unknown | null;\n schemaLoading: boolean;\n uiHints: ConfigUiHints;\n formMode: \"form\" | \"raw\";\n formValue: Record | null;\n originalValue: Record | null;\n searchQuery: string;\n activeSection: string | null;\n activeSubsection: string | null;\n onRawChange: (next: string) => void;\n onFormModeChange: (mode: \"form\" | \"raw\") => void;\n onFormPatch: (path: Array, value: unknown) => void;\n onSearchChange: (query: string) => void;\n onSectionChange: (section: string | null) => void;\n onSubsectionChange: (section: string | null) => void;\n onReload: () => void;\n onSave: () => void;\n onApply: () => void;\n onUpdate: () => void;\n};\n\n// SVG Icons for sidebar (Lucide-style)\nconst sidebarIcons = {\n all: html``,\n env: html``,\n update: html``,\n agents: html``,\n auth: html``,\n channels: html``,\n messages: html``,\n commands: html``,\n hooks: html``,\n skills: html``,\n tools: html``,\n gateway: html``,\n wizard: html``,\n // Additional sections\n meta: html``,\n logging: html``,\n browser: html``,\n ui: html``,\n models: html``,\n bindings: html``,\n broadcast: html``,\n audio: html``,\n session: html``,\n cron: html``,\n web: html``,\n discovery: html``,\n canvasHost: html``,\n talk: html``,\n plugins: html``,\n default: html``,\n};\n\n// Section definitions\nconst SECTIONS: Array<{ key: string; label: string }> = [\n { key: \"env\", label: \"Environment\" },\n { key: \"update\", label: \"Updates\" },\n { key: \"agents\", label: \"Agents\" },\n { key: \"auth\", label: \"Authentication\" },\n { key: \"channels\", label: \"Channels\" },\n { key: \"messages\", label: \"Messages\" },\n { key: \"commands\", label: \"Commands\" },\n { key: \"hooks\", label: \"Hooks\" },\n { key: \"skills\", label: \"Skills\" },\n { key: \"tools\", label: \"Tools\" },\n { key: \"gateway\", label: \"Gateway\" },\n { key: \"wizard\", label: \"Setup Wizard\" },\n];\n\ntype SubsectionEntry = {\n key: string;\n label: string;\n description?: string;\n order: number;\n};\n\nconst ALL_SUBSECTION = \"__all__\";\n\nfunction getSectionIcon(key: string) {\n return sidebarIcons[key as keyof typeof sidebarIcons] ?? sidebarIcons.default;\n}\n\nfunction resolveSectionMeta(key: string, schema?: JsonSchema): {\n label: string;\n description?: string;\n} {\n const meta = SECTION_META[key];\n if (meta) return meta;\n return {\n label: schema?.title ?? humanize(key),\n description: schema?.description ?? \"\",\n };\n}\n\nfunction resolveSubsections(params: {\n key: string;\n schema: JsonSchema | undefined;\n uiHints: ConfigUiHints;\n}): SubsectionEntry[] {\n const { key, schema, uiHints } = params;\n if (!schema || schemaType(schema) !== \"object\" || !schema.properties) return [];\n const entries = Object.entries(schema.properties).map(([subKey, node]) => {\n const hint = hintForPath([key, subKey], uiHints);\n const label = hint?.label ?? node.title ?? humanize(subKey);\n const description = hint?.help ?? node.description ?? \"\";\n const order = hint?.order ?? 50;\n return { key: subKey, label, description, order };\n });\n entries.sort((a, b) => (a.order !== b.order ? a.order - b.order : a.key.localeCompare(b.key)));\n return entries;\n}\n\nfunction computeDiff(\n original: Record | null,\n current: Record | null\n): Array<{ path: string; from: unknown; to: unknown }> {\n if (!original || !current) return [];\n const changes: Array<{ path: string; from: unknown; to: unknown }> = [];\n \n function compare(orig: unknown, curr: unknown, path: string) {\n if (orig === curr) return;\n if (typeof orig !== typeof curr) {\n changes.push({ path, from: orig, to: curr });\n return;\n }\n if (typeof orig !== \"object\" || orig === null || curr === null) {\n if (orig !== curr) {\n changes.push({ path, from: orig, to: curr });\n }\n return;\n }\n if (Array.isArray(orig) && Array.isArray(curr)) {\n if (JSON.stringify(orig) !== JSON.stringify(curr)) {\n changes.push({ path, from: orig, to: curr });\n }\n return;\n }\n const origObj = orig as Record;\n const currObj = curr as Record;\n const allKeys = new Set([...Object.keys(origObj), ...Object.keys(currObj)]);\n for (const key of allKeys) {\n compare(origObj[key], currObj[key], path ? `${path}.${key}` : key);\n }\n }\n \n compare(original, current, \"\");\n return changes;\n}\n\nfunction truncateValue(value: unknown, maxLen = 40): string {\n let str: string;\n try {\n const json = JSON.stringify(value);\n str = json ?? String(value);\n } catch {\n str = String(value);\n }\n if (str.length <= maxLen) return str;\n return str.slice(0, maxLen - 3) + \"...\";\n}\n\nexport function renderConfig(props: ConfigProps) {\n const validity =\n props.valid == null ? \"unknown\" : props.valid ? \"valid\" : \"invalid\";\n const analysis = analyzeConfigSchema(props.schema);\n const formUnsafe = analysis.schema\n ? analysis.unsupportedPaths.length > 0\n : false;\n\n // Get available sections from schema\n const schemaProps = analysis.schema?.properties ?? {};\n const availableSections = SECTIONS.filter(s => s.key in schemaProps);\n\n // Add any sections in schema but not in our list\n const knownKeys = new Set(SECTIONS.map(s => s.key));\n const extraSections = Object.keys(schemaProps)\n .filter(k => !knownKeys.has(k))\n .map(k => ({ key: k, label: k.charAt(0).toUpperCase() + k.slice(1) }));\n\n const allSections = [...availableSections, ...extraSections];\n\n const activeSectionSchema =\n props.activeSection && analysis.schema && schemaType(analysis.schema) === \"object\"\n ? (analysis.schema.properties?.[props.activeSection] as JsonSchema | undefined)\n : undefined;\n const activeSectionMeta = props.activeSection\n ? resolveSectionMeta(props.activeSection, activeSectionSchema)\n : null;\n const subsections = props.activeSection\n ? resolveSubsections({\n key: props.activeSection,\n schema: activeSectionSchema,\n uiHints: props.uiHints,\n })\n : [];\n const allowSubnav =\n props.formMode === \"form\" &&\n Boolean(props.activeSection) &&\n subsections.length > 0;\n const isAllSubsection = props.activeSubsection === ALL_SUBSECTION;\n const effectiveSubsection = props.searchQuery\n ? null\n : isAllSubsection\n ? null\n : props.activeSubsection ?? (subsections[0]?.key ?? null);\n\n // Compute diff for showing changes (works for both form and raw modes)\n const diff = props.formMode === \"form\"\n ? computeDiff(props.originalValue, props.formValue)\n : [];\n const hasRawChanges = props.formMode === \"raw\" && props.raw !== props.originalRaw;\n const hasChanges = props.formMode === \"form\" ? diff.length > 0 : hasRawChanges;\n\n // Save/apply buttons require actual changes to be enabled.\n // Note: formUnsafe warns about unsupported schema paths but shouldn't block saving.\n const canSaveForm =\n Boolean(props.formValue) && !props.loading && Boolean(analysis.schema);\n const canSave =\n props.connected &&\n !props.saving &&\n hasChanges &&\n (props.formMode === \"raw\" ? true : canSaveForm);\n const canApply =\n props.connected &&\n !props.applying &&\n !props.updating &&\n hasChanges &&\n (props.formMode === \"raw\" ? true : canSaveForm);\n const canUpdate = props.connected && !props.applying && !props.updating;\n\n return html`\n
    \n \n \n \n \n
    \n \n
    \n
    \n ${hasChanges ? html`\n ${props.formMode === \"raw\" ? \"Unsaved changes\" : `${diff.length} unsaved change${diff.length !== 1 ? \"s\" : \"\"}`}\n ` : html`\n No changes\n `}\n
    \n
    \n \n \n ${props.saving ? \"Saving…\" : \"Save\"}\n \n \n ${props.applying ? \"Applying…\" : \"Apply\"}\n \n \n ${props.updating ? \"Updating…\" : \"Update\"}\n \n
    \n
    \n \n \n ${hasChanges && props.formMode === \"form\" ? html`\n
    \n \n View ${diff.length} pending change${diff.length !== 1 ? \"s\" : \"\"}\n \n \n \n \n
    \n ${diff.map(change => html`\n
    \n
    ${change.path}
    \n
    \n ${truncateValue(change.from)}\n \n ${truncateValue(change.to)}\n
    \n
    \n `)}\n
    \n
    \n ` : nothing}\n\n ${activeSectionMeta && props.formMode === \"form\"\n ? html`\n
    \n
    ${getSectionIcon(props.activeSection ?? \"\")}
    \n
    \n
    ${activeSectionMeta.label}
    \n ${activeSectionMeta.description\n ? html`
    ${activeSectionMeta.description}
    `\n : nothing}\n
    \n
    \n `\n : nothing}\n\n ${allowSubnav\n ? html`\n
    \n props.onSubsectionChange(ALL_SUBSECTION)}\n >\n All\n \n ${subsections.map(\n (entry) => html`\n props.onSubsectionChange(entry.key)}\n >\n ${entry.label}\n \n `,\n )}\n
    \n `\n : nothing}\n\n \n
    \n ${props.formMode === \"form\"\n ? html`\n ${props.schemaLoading\n ? html`
    \n
    \n Loading schema…\n
    `\n : renderConfigForm({\n schema: analysis.schema,\n uiHints: props.uiHints,\n value: props.formValue,\n disabled: props.loading || !props.formValue,\n unsupportedPaths: analysis.unsupportedPaths,\n onPatch: props.onFormPatch,\n searchQuery: props.searchQuery,\n activeSection: props.activeSection,\n activeSubsection: effectiveSubsection,\n })}\n ${formUnsafe\n ? html`
    \n Form view can't safely edit some fields.\n Use Raw to avoid losing config entries.\n
    `\n : nothing}\n `\n : html`\n \n `}\n
    \n\n ${props.issues.length > 0\n ? html`
    \n
    ${JSON.stringify(props.issues, null, 2)}
    \n
    `\n : nothing}\n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport type { ChannelAccountSnapshot } from \"../types\";\nimport type { ChannelKey, ChannelsProps } from \"./channels.types\";\n\nexport function formatDuration(ms?: number | null) {\n if (!ms && ms !== 0) return \"n/a\";\n const sec = Math.round(ms / 1000);\n if (sec < 60) return `${sec}s`;\n const min = Math.round(sec / 60);\n if (min < 60) return `${min}m`;\n const hr = Math.round(min / 60);\n return `${hr}h`;\n}\n\nexport function channelEnabled(key: ChannelKey, props: ChannelsProps) {\n const snapshot = props.snapshot;\n const channels = snapshot?.channels as Record | null;\n if (!snapshot || !channels) return false;\n const channelStatus = channels[key] as Record | undefined;\n const configured = typeof channelStatus?.configured === \"boolean\" && channelStatus.configured;\n const running = typeof channelStatus?.running === \"boolean\" && channelStatus.running;\n const connected = typeof channelStatus?.connected === \"boolean\" && channelStatus.connected;\n const accounts = snapshot.channelAccounts?.[key] ?? [];\n const accountActive = accounts.some(\n (account) => account.configured || account.running || account.connected,\n );\n return configured || running || connected || accountActive;\n}\n\nexport function getChannelAccountCount(\n key: ChannelKey,\n channelAccounts?: Record | null,\n): number {\n return channelAccounts?.[key]?.length ?? 0;\n}\n\nexport function renderChannelAccountCount(\n key: ChannelKey,\n channelAccounts?: Record | null,\n) {\n const count = getChannelAccountCount(key, channelAccounts);\n if (count < 2) return nothing;\n return html`
    Accounts (${count})
    `;\n}\n\n","import { html } from \"lit\";\n\nimport type { ConfigUiHints } from \"../types\";\nimport type { ChannelsProps } from \"./channels.types\";\nimport {\n analyzeConfigSchema,\n renderNode,\n schemaType,\n type JsonSchema,\n} from \"./config-form\";\n\ntype ChannelConfigFormProps = {\n channelId: string;\n configValue: Record | null;\n schema: unknown | null;\n uiHints: ConfigUiHints;\n disabled: boolean;\n onPatch: (path: Array, value: unknown) => void;\n};\n\nfunction resolveSchemaNode(\n schema: JsonSchema | null,\n path: Array,\n): JsonSchema | null {\n let current = schema;\n for (const key of path) {\n if (!current) return null;\n const type = schemaType(current);\n if (type === \"object\") {\n const properties = current.properties ?? {};\n if (typeof key === \"string\" && properties[key]) {\n current = properties[key];\n continue;\n }\n const additional = current.additionalProperties;\n if (typeof key === \"string\" && additional && typeof additional === \"object\") {\n current = additional as JsonSchema;\n continue;\n }\n return null;\n }\n if (type === \"array\") {\n if (typeof key !== \"number\") return null;\n const items = Array.isArray(current.items) ? current.items[0] : current.items;\n current = items ?? null;\n continue;\n }\n return null;\n }\n return current;\n}\n\nfunction resolveChannelValue(\n config: Record,\n channelId: string,\n): Record {\n const channels = (config.channels ?? {}) as Record;\n const fromChannels = channels[channelId];\n const fallback = config[channelId];\n const resolved =\n (fromChannels && typeof fromChannels === \"object\"\n ? (fromChannels as Record)\n : null) ??\n (fallback && typeof fallback === \"object\"\n ? (fallback as Record)\n : null);\n return resolved ?? {};\n}\n\nexport function renderChannelConfigForm(props: ChannelConfigFormProps) {\n const analysis = analyzeConfigSchema(props.schema);\n const normalized = analysis.schema;\n if (!normalized) {\n return html`
    Schema unavailable. Use Raw.
    `;\n }\n const node = resolveSchemaNode(normalized, [\"channels\", props.channelId]);\n if (!node) {\n return html`
    Channel config schema unavailable.
    `;\n }\n const configValue = props.configValue ?? {};\n const value = resolveChannelValue(configValue, props.channelId);\n return html`\n
    \n ${renderNode({\n schema: node,\n value,\n path: [\"channels\", props.channelId],\n hints: props.uiHints,\n unsupported: new Set(analysis.unsupportedPaths),\n disabled: props.disabled,\n showLabel: false,\n onPatch: props.onPatch,\n })}\n
    \n `;\n}\n\nexport function renderChannelConfigSection(params: {\n channelId: string;\n props: ChannelsProps;\n}) {\n const { channelId, props } = params;\n const disabled = props.configSaving || props.configSchemaLoading;\n return html`\n
    \n ${props.configSchemaLoading\n ? html`
    Loading config schema…
    `\n : renderChannelConfigForm({\n channelId,\n configValue: props.configForm,\n schema: props.configSchema,\n uiHints: props.configUiHints,\n disabled,\n onPatch: props.onConfigPatch,\n })}\n
    \n props.onConfigSave()}\n >\n ${props.configSaving ? \"Saving…\" : \"Save\"}\n \n props.onConfigReload()}\n >\n Reload\n \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatAgo } from \"../format\";\nimport type { DiscordStatus } from \"../types\";\nimport type { ChannelsProps } from \"./channels.types\";\nimport { renderChannelConfigSection } from \"./channels.config\";\n\nexport function renderDiscordCard(params: {\n props: ChannelsProps;\n discord?: DiscordStatus | null;\n accountCountLabel: unknown;\n}) {\n const { props, discord, accountCountLabel } = params;\n\n return html`\n
    \n
    Discord
    \n
    Bot status and channel configuration.
    \n ${accountCountLabel}\n\n
    \n
    \n Configured\n ${discord?.configured ? \"Yes\" : \"No\"}\n
    \n
    \n Running\n ${discord?.running ? \"Yes\" : \"No\"}\n
    \n
    \n Last start\n ${discord?.lastStartAt ? formatAgo(discord.lastStartAt) : \"n/a\"}\n
    \n
    \n Last probe\n ${discord?.lastProbeAt ? formatAgo(discord.lastProbeAt) : \"n/a\"}\n
    \n
    \n\n ${discord?.lastError\n ? html`
    \n ${discord.lastError}\n
    `\n : nothing}\n\n ${discord?.probe\n ? html`
    \n Probe ${discord.probe.ok ? \"ok\" : \"failed\"} ·\n ${discord.probe.status ?? \"\"} ${discord.probe.error ?? \"\"}\n
    `\n : nothing}\n\n ${renderChannelConfigSection({ channelId: \"discord\", props })}\n\n
    \n \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatAgo } from \"../format\";\nimport type { GoogleChatStatus } from \"../types\";\nimport { renderChannelConfigSection } from \"./channels.config\";\nimport type { ChannelsProps } from \"./channels.types\";\n\nexport function renderGoogleChatCard(params: {\n props: ChannelsProps;\n googleChat?: GoogleChatStatus | null;\n accountCountLabel: unknown;\n}) {\n const { props, googleChat, accountCountLabel } = params;\n\n return html`\n
    \n
    Google Chat
    \n
    Chat API webhook status and channel configuration.
    \n ${accountCountLabel}\n\n
    \n
    \n Configured\n ${googleChat ? (googleChat.configured ? \"Yes\" : \"No\") : \"n/a\"}\n
    \n
    \n Running\n ${googleChat ? (googleChat.running ? \"Yes\" : \"No\") : \"n/a\"}\n
    \n
    \n Credential\n ${googleChat?.credentialSource ?? \"n/a\"}\n
    \n
    \n Audience\n \n ${googleChat?.audienceType\n ? `${googleChat.audienceType}${googleChat.audience ? ` · ${googleChat.audience}` : \"\"}`\n : \"n/a\"}\n \n
    \n
    \n Last start\n ${googleChat?.lastStartAt ? formatAgo(googleChat.lastStartAt) : \"n/a\"}\n
    \n
    \n Last probe\n ${googleChat?.lastProbeAt ? formatAgo(googleChat.lastProbeAt) : \"n/a\"}\n
    \n
    \n\n ${googleChat?.lastError\n ? html`
    \n ${googleChat.lastError}\n
    `\n : nothing}\n\n ${googleChat?.probe\n ? html`
    \n Probe ${googleChat.probe.ok ? \"ok\" : \"failed\"} ·\n ${googleChat.probe.status ?? \"\"} ${googleChat.probe.error ?? \"\"}\n
    `\n : nothing}\n\n ${renderChannelConfigSection({ channelId: \"googlechat\", props })}\n\n
    \n \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatAgo } from \"../format\";\nimport type { IMessageStatus } from \"../types\";\nimport type { ChannelsProps } from \"./channels.types\";\nimport { renderChannelConfigSection } from \"./channels.config\";\n\nexport function renderIMessageCard(params: {\n props: ChannelsProps;\n imessage?: IMessageStatus | null;\n accountCountLabel: unknown;\n}) {\n const { props, imessage, accountCountLabel } = params;\n\n return html`\n
    \n
    iMessage
    \n
    macOS bridge status and channel configuration.
    \n ${accountCountLabel}\n\n
    \n
    \n Configured\n ${imessage?.configured ? \"Yes\" : \"No\"}\n
    \n
    \n Running\n ${imessage?.running ? \"Yes\" : \"No\"}\n
    \n
    \n Last start\n ${imessage?.lastStartAt ? formatAgo(imessage.lastStartAt) : \"n/a\"}\n
    \n
    \n Last probe\n ${imessage?.lastProbeAt ? formatAgo(imessage.lastProbeAt) : \"n/a\"}\n
    \n
    \n\n ${imessage?.lastError\n ? html`
    \n ${imessage.lastError}\n
    `\n : nothing}\n\n ${imessage?.probe\n ? html`
    \n Probe ${imessage.probe.ok ? \"ok\" : \"failed\"} ·\n ${imessage.probe.error ?? \"\"}\n
    `\n : nothing}\n\n ${renderChannelConfigSection({ channelId: \"imessage\", props })}\n\n
    \n \n
    \n
    \n `;\n}\n","/**\n * Nostr Profile Edit Form\n *\n * Provides UI for editing and publishing Nostr profile (kind:0).\n */\n\nimport { html, nothing, type TemplateResult } from \"lit\";\n\nimport type { NostrProfile as NostrProfileType } from \"../types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface NostrProfileFormState {\n /** Current form values */\n values: NostrProfileType;\n /** Original values for dirty detection */\n original: NostrProfileType;\n /** Whether the form is currently submitting */\n saving: boolean;\n /** Whether import is in progress */\n importing: boolean;\n /** Last error message */\n error: string | null;\n /** Last success message */\n success: string | null;\n /** Validation errors per field */\n fieldErrors: Record;\n /** Whether to show advanced fields */\n showAdvanced: boolean;\n}\n\nexport interface NostrProfileFormCallbacks {\n /** Called when a field value changes */\n onFieldChange: (field: keyof NostrProfileType, value: string) => void;\n /** Called when save is clicked */\n onSave: () => void;\n /** Called when import is clicked */\n onImport: () => void;\n /** Called when cancel is clicked */\n onCancel: () => void;\n /** Called when toggle advanced is clicked */\n onToggleAdvanced: () => void;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction isFormDirty(state: NostrProfileFormState): boolean {\n const { values, original } = state;\n return (\n values.name !== original.name ||\n values.displayName !== original.displayName ||\n values.about !== original.about ||\n values.picture !== original.picture ||\n values.banner !== original.banner ||\n values.website !== original.website ||\n values.nip05 !== original.nip05 ||\n values.lud16 !== original.lud16\n );\n}\n\n// ============================================================================\n// Form Rendering\n// ============================================================================\n\nexport function renderNostrProfileForm(params: {\n state: NostrProfileFormState;\n callbacks: NostrProfileFormCallbacks;\n accountId: string;\n}): TemplateResult {\n const { state, callbacks, accountId } = params;\n const isDirty = isFormDirty(state);\n\n const renderField = (\n field: keyof NostrProfileType,\n label: string,\n opts: {\n type?: \"text\" | \"url\" | \"textarea\";\n placeholder?: string;\n maxLength?: number;\n help?: string;\n } = {}\n ) => {\n const { type = \"text\", placeholder, maxLength, help } = opts;\n const value = state.values[field] ?? \"\";\n const error = state.fieldErrors[field];\n\n const inputId = `nostr-profile-${field}`;\n\n if (type === \"textarea\") {\n return html`\n
    \n \n {\n const target = e.target as HTMLTextAreaElement;\n callbacks.onFieldChange(field, target.value);\n }}\n ?disabled=${state.saving}\n >\n ${help ? html`
    ${help}
    ` : nothing}\n ${error ? html`
    ${error}
    ` : nothing}\n
    \n `;\n }\n\n return html`\n
    \n \n {\n const target = e.target as HTMLInputElement;\n callbacks.onFieldChange(field, target.value);\n }}\n ?disabled=${state.saving}\n />\n ${help ? html`
    ${help}
    ` : nothing}\n ${error ? html`
    ${error}
    ` : nothing}\n
    \n `;\n };\n\n const renderPicturePreview = () => {\n const picture = state.values.picture;\n if (!picture) return nothing;\n\n return html`\n
    \n {\n const img = e.target as HTMLImageElement;\n img.style.display = \"none\";\n }}\n @load=${(e: Event) => {\n const img = e.target as HTMLImageElement;\n img.style.display = \"block\";\n }}\n />\n
    \n `;\n };\n\n return html`\n
    \n
    \n
    Edit Profile
    \n
    Account: ${accountId}
    \n
    \n\n ${state.error\n ? html`
    ${state.error}
    `\n : nothing}\n\n ${state.success\n ? html`
    ${state.success}
    `\n : nothing}\n\n ${renderPicturePreview()}\n\n ${renderField(\"name\", \"Username\", {\n placeholder: \"satoshi\",\n maxLength: 256,\n help: \"Short username (e.g., satoshi)\",\n })}\n\n ${renderField(\"displayName\", \"Display Name\", {\n placeholder: \"Satoshi Nakamoto\",\n maxLength: 256,\n help: \"Your full display name\",\n })}\n\n ${renderField(\"about\", \"Bio\", {\n type: \"textarea\",\n placeholder: \"Tell people about yourself...\",\n maxLength: 2000,\n help: \"A brief bio or description\",\n })}\n\n ${renderField(\"picture\", \"Avatar URL\", {\n type: \"url\",\n placeholder: \"https://example.com/avatar.jpg\",\n help: \"HTTPS URL to your profile picture\",\n })}\n\n ${state.showAdvanced\n ? html`\n
    \n
    Advanced
    \n\n ${renderField(\"banner\", \"Banner URL\", {\n type: \"url\",\n placeholder: \"https://example.com/banner.jpg\",\n help: \"HTTPS URL to a banner image\",\n })}\n\n ${renderField(\"website\", \"Website\", {\n type: \"url\",\n placeholder: \"https://example.com\",\n help: \"Your personal website\",\n })}\n\n ${renderField(\"nip05\", \"NIP-05 Identifier\", {\n placeholder: \"you@example.com\",\n help: \"Verifiable identifier (e.g., you@domain.com)\",\n })}\n\n ${renderField(\"lud16\", \"Lightning Address\", {\n placeholder: \"you@getalby.com\",\n help: \"Lightning address for tips (LUD-16)\",\n })}\n
    \n `\n : nothing}\n\n
    \n \n ${state.saving ? \"Saving...\" : \"Save & Publish\"}\n \n\n \n ${state.importing ? \"Importing...\" : \"Import from Relays\"}\n \n\n \n ${state.showAdvanced ? \"Hide Advanced\" : \"Show Advanced\"}\n \n\n \n Cancel\n \n
    \n\n ${isDirty\n ? html`
    \n You have unsaved changes\n
    `\n : nothing}\n
    \n `;\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Create initial form state from existing profile\n */\nexport function createNostrProfileFormState(\n profile: NostrProfileType | undefined\n): NostrProfileFormState {\n const values: NostrProfileType = {\n name: profile?.name ?? \"\",\n displayName: profile?.displayName ?? \"\",\n about: profile?.about ?? \"\",\n picture: profile?.picture ?? \"\",\n banner: profile?.banner ?? \"\",\n website: profile?.website ?? \"\",\n nip05: profile?.nip05 ?? \"\",\n lud16: profile?.lud16 ?? \"\",\n };\n\n return {\n values,\n original: { ...values },\n saving: false,\n importing: false,\n error: null,\n success: null,\n fieldErrors: {},\n showAdvanced: Boolean(\n profile?.banner || profile?.website || profile?.nip05 || profile?.lud16\n ),\n };\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatAgo } from \"../format\";\nimport type { ChannelAccountSnapshot, NostrStatus } from \"../types\";\nimport type { ChannelsProps } from \"./channels.types\";\nimport { renderChannelConfigSection } from \"./channels.config\";\nimport {\n renderNostrProfileForm,\n type NostrProfileFormState,\n type NostrProfileFormCallbacks,\n} from \"./channels.nostr-profile-form\";\n\n/**\n * Truncate a pubkey for display (shows first and last 8 chars)\n */\nfunction truncatePubkey(pubkey: string | null | undefined): string {\n if (!pubkey) return \"n/a\";\n if (pubkey.length <= 20) return pubkey;\n return `${pubkey.slice(0, 8)}...${pubkey.slice(-8)}`;\n}\n\nexport function renderNostrCard(params: {\n props: ChannelsProps;\n nostr?: NostrStatus | null;\n nostrAccounts: ChannelAccountSnapshot[];\n accountCountLabel: unknown;\n /** Profile form state (optional - if provided, shows form) */\n profileFormState?: NostrProfileFormState | null;\n /** Profile form callbacks */\n profileFormCallbacks?: NostrProfileFormCallbacks | null;\n /** Called when Edit Profile is clicked */\n onEditProfile?: () => void;\n}) {\n const {\n props,\n nostr,\n nostrAccounts,\n accountCountLabel,\n profileFormState,\n profileFormCallbacks,\n onEditProfile,\n } = params;\n const primaryAccount = nostrAccounts[0];\n const summaryConfigured = nostr?.configured ?? primaryAccount?.configured ?? false;\n const summaryRunning = nostr?.running ?? primaryAccount?.running ?? false;\n const summaryPublicKey =\n nostr?.publicKey ??\n (primaryAccount as { publicKey?: string } | undefined)?.publicKey;\n const summaryLastStartAt = nostr?.lastStartAt ?? primaryAccount?.lastStartAt ?? null;\n const summaryLastError = nostr?.lastError ?? primaryAccount?.lastError ?? null;\n const hasMultipleAccounts = nostrAccounts.length > 1;\n const showingForm = profileFormState !== null && profileFormState !== undefined;\n\n const renderAccountCard = (account: ChannelAccountSnapshot) => {\n const publicKey = (account as { publicKey?: string }).publicKey;\n const profile = (account as { profile?: { name?: string; displayName?: string } }).profile;\n const displayName = profile?.displayName ?? profile?.name ?? account.name ?? account.accountId;\n\n return html`\n
    \n
    \n
    ${displayName}
    \n
    ${account.accountId}
    \n
    \n
    \n
    \n Running\n ${account.running ? \"Yes\" : \"No\"}\n
    \n
    \n Configured\n ${account.configured ? \"Yes\" : \"No\"}\n
    \n
    \n Public Key\n ${truncatePubkey(publicKey)}\n
    \n
    \n Last inbound\n ${account.lastInboundAt ? formatAgo(account.lastInboundAt) : \"n/a\"}\n
    \n ${account.lastError\n ? html`\n
    ${account.lastError}
    \n `\n : nothing}\n
    \n
    \n `;\n };\n\n const renderProfileSection = () => {\n // If showing form, render the form instead of the read-only view\n if (showingForm && profileFormCallbacks) {\n return renderNostrProfileForm({\n state: profileFormState,\n callbacks: profileFormCallbacks,\n accountId: nostrAccounts[0]?.accountId ?? \"default\",\n });\n }\n\n const profile =\n (primaryAccount as\n | {\n profile?: {\n name?: string;\n displayName?: string;\n about?: string;\n picture?: string;\n nip05?: string;\n };\n }\n | undefined)?.profile ?? nostr?.profile;\n const { name, displayName, about, picture, nip05 } = profile ?? {};\n const hasAnyProfileData = name || displayName || about || picture || nip05;\n\n return html`\n
    \n
    \n
    Profile
    \n ${summaryConfigured\n ? html`\n \n Edit Profile\n \n `\n : nothing}\n
    \n ${hasAnyProfileData\n ? html`\n
    \n ${picture\n ? html`\n
    \n {\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n
    \n `\n : nothing}\n ${name ? html`
    Name${name}
    ` : nothing}\n ${displayName\n ? html`
    Display Name${displayName}
    `\n : nothing}\n ${about\n ? html`
    About${about}
    `\n : nothing}\n ${nip05 ? html`
    NIP-05${nip05}
    ` : nothing}\n
    \n `\n : html`\n
    \n No profile set. Click \"Edit Profile\" to add your name, bio, and avatar.\n
    \n `}\n
    \n `;\n };\n\n return html`\n
    \n
    Nostr
    \n
    Decentralized DMs via Nostr relays (NIP-04).
    \n ${accountCountLabel}\n\n ${hasMultipleAccounts\n ? html`\n
    \n ${nostrAccounts.map((account) => renderAccountCard(account))}\n
    \n `\n : html`\n
    \n
    \n Configured\n ${summaryConfigured ? \"Yes\" : \"No\"}\n
    \n
    \n Running\n ${summaryRunning ? \"Yes\" : \"No\"}\n
    \n
    \n Public Key\n ${truncatePubkey(summaryPublicKey)}\n
    \n
    \n Last start\n ${summaryLastStartAt ? formatAgo(summaryLastStartAt) : \"n/a\"}\n
    \n
    \n `}\n\n ${summaryLastError\n ? html`
    ${summaryLastError}
    `\n : nothing}\n\n ${renderProfileSection()}\n\n ${renderChannelConfigSection({ channelId: \"nostr\", props })}\n\n
    \n \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatAgo } from \"../format\";\nimport type { SignalStatus } from \"../types\";\nimport type { ChannelsProps } from \"./channels.types\";\nimport { renderChannelConfigSection } from \"./channels.config\";\n\nexport function renderSignalCard(params: {\n props: ChannelsProps;\n signal?: SignalStatus | null;\n accountCountLabel: unknown;\n}) {\n const { props, signal, accountCountLabel } = params;\n\n return html`\n
    \n
    Signal
    \n
    signal-cli status and channel configuration.
    \n ${accountCountLabel}\n\n
    \n
    \n Configured\n ${signal?.configured ? \"Yes\" : \"No\"}\n
    \n
    \n Running\n ${signal?.running ? \"Yes\" : \"No\"}\n
    \n
    \n Base URL\n ${signal?.baseUrl ?? \"n/a\"}\n
    \n
    \n Last start\n ${signal?.lastStartAt ? formatAgo(signal.lastStartAt) : \"n/a\"}\n
    \n
    \n Last probe\n ${signal?.lastProbeAt ? formatAgo(signal.lastProbeAt) : \"n/a\"}\n
    \n
    \n\n ${signal?.lastError\n ? html`
    \n ${signal.lastError}\n
    `\n : nothing}\n\n ${signal?.probe\n ? html`
    \n Probe ${signal.probe.ok ? \"ok\" : \"failed\"} ·\n ${signal.probe.status ?? \"\"} ${signal.probe.error ?? \"\"}\n
    `\n : nothing}\n\n ${renderChannelConfigSection({ channelId: \"signal\", props })}\n\n
    \n \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatAgo } from \"../format\";\nimport type { SlackStatus } from \"../types\";\nimport type { ChannelsProps } from \"./channels.types\";\nimport { renderChannelConfigSection } from \"./channels.config\";\n\nexport function renderSlackCard(params: {\n props: ChannelsProps;\n slack?: SlackStatus | null;\n accountCountLabel: unknown;\n}) {\n const { props, slack, accountCountLabel } = params;\n\n return html`\n
    \n
    Slack
    \n
    Socket mode status and channel configuration.
    \n ${accountCountLabel}\n\n
    \n
    \n Configured\n ${slack?.configured ? \"Yes\" : \"No\"}\n
    \n
    \n Running\n ${slack?.running ? \"Yes\" : \"No\"}\n
    \n
    \n Last start\n ${slack?.lastStartAt ? formatAgo(slack.lastStartAt) : \"n/a\"}\n
    \n
    \n Last probe\n ${slack?.lastProbeAt ? formatAgo(slack.lastProbeAt) : \"n/a\"}\n
    \n
    \n\n ${slack?.lastError\n ? html`
    \n ${slack.lastError}\n
    `\n : nothing}\n\n ${slack?.probe\n ? html`
    \n Probe ${slack.probe.ok ? \"ok\" : \"failed\"} ·\n ${slack.probe.status ?? \"\"} ${slack.probe.error ?? \"\"}\n
    `\n : nothing}\n\n ${renderChannelConfigSection({ channelId: \"slack\", props })}\n\n
    \n \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatAgo } from \"../format\";\nimport type { ChannelAccountSnapshot, TelegramStatus } from \"../types\";\nimport type { ChannelsProps } from \"./channels.types\";\nimport { renderChannelConfigSection } from \"./channels.config\";\n\nexport function renderTelegramCard(params: {\n props: ChannelsProps;\n telegram?: TelegramStatus;\n telegramAccounts: ChannelAccountSnapshot[];\n accountCountLabel: unknown;\n}) {\n const { props, telegram, telegramAccounts, accountCountLabel } = params;\n const hasMultipleAccounts = telegramAccounts.length > 1;\n\n const renderAccountCard = (account: ChannelAccountSnapshot) => {\n const probe = account.probe as { bot?: { username?: string } } | undefined;\n const botUsername = probe?.bot?.username;\n const label = account.name || account.accountId;\n return html`\n
    \n
    \n
    \n ${botUsername ? `@${botUsername}` : label}\n
    \n
    ${account.accountId}
    \n
    \n
    \n
    \n Running\n ${account.running ? \"Yes\" : \"No\"}\n
    \n
    \n Configured\n ${account.configured ? \"Yes\" : \"No\"}\n
    \n
    \n Last inbound\n ${account.lastInboundAt ? formatAgo(account.lastInboundAt) : \"n/a\"}\n
    \n ${account.lastError\n ? html`\n
    \n ${account.lastError}\n
    \n `\n : nothing}\n
    \n
    \n `;\n };\n\n return html`\n
    \n
    Telegram
    \n
    Bot status and channel configuration.
    \n ${accountCountLabel}\n\n ${hasMultipleAccounts\n ? html`\n
    \n ${telegramAccounts.map((account) => renderAccountCard(account))}\n
    \n `\n : html`\n
    \n
    \n Configured\n ${telegram?.configured ? \"Yes\" : \"No\"}\n
    \n
    \n Running\n ${telegram?.running ? \"Yes\" : \"No\"}\n
    \n
    \n Mode\n ${telegram?.mode ?? \"n/a\"}\n
    \n
    \n Last start\n ${telegram?.lastStartAt ? formatAgo(telegram.lastStartAt) : \"n/a\"}\n
    \n
    \n Last probe\n ${telegram?.lastProbeAt ? formatAgo(telegram.lastProbeAt) : \"n/a\"}\n
    \n
    \n `}\n\n ${telegram?.lastError\n ? html`
    \n ${telegram.lastError}\n
    `\n : nothing}\n\n ${telegram?.probe\n ? html`
    \n Probe ${telegram.probe.ok ? \"ok\" : \"failed\"} ·\n ${telegram.probe.status ?? \"\"} ${telegram.probe.error ?? \"\"}\n
    `\n : nothing}\n\n ${renderChannelConfigSection({ channelId: \"telegram\", props })}\n\n
    \n \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatAgo } from \"../format\";\nimport type { WhatsAppStatus } from \"../types\";\nimport type { ChannelsProps } from \"./channels.types\";\nimport { renderChannelConfigSection } from \"./channels.config\";\nimport { formatDuration } from \"./channels.shared\";\n\nexport function renderWhatsAppCard(params: {\n props: ChannelsProps;\n whatsapp?: WhatsAppStatus;\n accountCountLabel: unknown;\n}) {\n const { props, whatsapp, accountCountLabel } = params;\n\n return html`\n
    \n
    WhatsApp
    \n
    Link WhatsApp Web and monitor connection health.
    \n ${accountCountLabel}\n\n
    \n
    \n Configured\n ${whatsapp?.configured ? \"Yes\" : \"No\"}\n
    \n
    \n Linked\n ${whatsapp?.linked ? \"Yes\" : \"No\"}\n
    \n
    \n Running\n ${whatsapp?.running ? \"Yes\" : \"No\"}\n
    \n
    \n Connected\n ${whatsapp?.connected ? \"Yes\" : \"No\"}\n
    \n
    \n Last connect\n \n ${whatsapp?.lastConnectedAt\n ? formatAgo(whatsapp.lastConnectedAt)\n : \"n/a\"}\n \n
    \n
    \n Last message\n \n ${whatsapp?.lastMessageAt ? formatAgo(whatsapp.lastMessageAt) : \"n/a\"}\n \n
    \n
    \n Auth age\n \n ${whatsapp?.authAgeMs != null\n ? formatDuration(whatsapp.authAgeMs)\n : \"n/a\"}\n \n
    \n
    \n\n ${whatsapp?.lastError\n ? html`
    \n ${whatsapp.lastError}\n
    `\n : nothing}\n\n ${props.whatsappMessage\n ? html`
    \n ${props.whatsappMessage}\n
    `\n : nothing}\n\n ${props.whatsappQrDataUrl\n ? html`
    \n \"WhatsApp\n
    `\n : nothing}\n\n
    \n props.onWhatsAppStart(false)}\n >\n ${props.whatsappBusy ? \"Working…\" : \"Show QR\"}\n \n props.onWhatsAppStart(true)}\n >\n Relink\n \n props.onWhatsAppWait()}\n >\n Wait for scan\n \n props.onWhatsAppLogout()}\n >\n Logout\n \n \n
    \n\n ${renderChannelConfigSection({ channelId: \"whatsapp\", props })}\n
    \n `;\n}\n\n","import { html, nothing } from \"lit\";\n\nimport { formatAgo } from \"../format\";\nimport type {\n ChannelAccountSnapshot,\n ChannelUiMetaEntry,\n ChannelsStatusSnapshot,\n DiscordStatus,\n GoogleChatStatus,\n IMessageStatus,\n NostrProfile,\n NostrStatus,\n SignalStatus,\n SlackStatus,\n TelegramStatus,\n WhatsAppStatus,\n} from \"../types\";\nimport type {\n ChannelKey,\n ChannelsChannelData,\n ChannelsProps,\n} from \"./channels.types\";\nimport { channelEnabled, renderChannelAccountCount } from \"./channels.shared\";\nimport { renderChannelConfigSection } from \"./channels.config\";\nimport { renderDiscordCard } from \"./channels.discord\";\nimport { renderGoogleChatCard } from \"./channels.googlechat\";\nimport { renderIMessageCard } from \"./channels.imessage\";\nimport { renderNostrCard } from \"./channels.nostr\";\nimport { renderSignalCard } from \"./channels.signal\";\nimport { renderSlackCard } from \"./channels.slack\";\nimport { renderTelegramCard } from \"./channels.telegram\";\nimport { renderWhatsAppCard } from \"./channels.whatsapp\";\n\nexport function renderChannels(props: ChannelsProps) {\n const channels = props.snapshot?.channels as Record | null;\n const whatsapp = (channels?.whatsapp ?? undefined) as\n | WhatsAppStatus\n | undefined;\n const telegram = (channels?.telegram ?? undefined) as\n | TelegramStatus\n | undefined;\n const discord = (channels?.discord ?? null) as DiscordStatus | null;\n const googlechat = (channels?.googlechat ?? null) as GoogleChatStatus | null;\n const slack = (channels?.slack ?? null) as SlackStatus | null;\n const signal = (channels?.signal ?? null) as SignalStatus | null;\n const imessage = (channels?.imessage ?? null) as IMessageStatus | null;\n const nostr = (channels?.nostr ?? null) as NostrStatus | null;\n const channelOrder = resolveChannelOrder(props.snapshot);\n const orderedChannels = channelOrder\n .map((key, index) => ({\n key,\n enabled: channelEnabled(key, props),\n order: index,\n }))\n .sort((a, b) => {\n if (a.enabled !== b.enabled) return a.enabled ? -1 : 1;\n return a.order - b.order;\n });\n\n return html`\n
    \n ${orderedChannels.map((channel) =>\n renderChannel(channel.key, props, {\n whatsapp,\n telegram,\n discord,\n googlechat,\n slack,\n signal,\n imessage,\n nostr,\n channelAccounts: props.snapshot?.channelAccounts ?? null,\n }),\n )}\n
    \n\n
    \n
    \n
    \n
    Channel health
    \n
    Channel status snapshots from the gateway.
    \n
    \n
    ${props.lastSuccessAt ? formatAgo(props.lastSuccessAt) : \"n/a\"}
    \n
    \n ${props.lastError\n ? html`
    \n ${props.lastError}\n
    `\n : nothing}\n
    \n${props.snapshot ? JSON.stringify(props.snapshot, null, 2) : \"No snapshot yet.\"}\n      
    \n
    \n `;\n}\n\nfunction resolveChannelOrder(snapshot: ChannelsStatusSnapshot | null): ChannelKey[] {\n if (snapshot?.channelMeta?.length) {\n return snapshot.channelMeta.map((entry) => entry.id) as ChannelKey[];\n }\n if (snapshot?.channelOrder?.length) {\n return snapshot.channelOrder;\n }\n return [\n \"whatsapp\",\n \"telegram\",\n \"discord\",\n \"googlechat\",\n \"slack\",\n \"signal\",\n \"imessage\",\n \"nostr\",\n ];\n}\n\nfunction renderChannel(\n key: ChannelKey,\n props: ChannelsProps,\n data: ChannelsChannelData,\n) {\n const accountCountLabel = renderChannelAccountCount(\n key,\n data.channelAccounts,\n );\n switch (key) {\n case \"whatsapp\":\n return renderWhatsAppCard({\n props,\n whatsapp: data.whatsapp,\n accountCountLabel,\n });\n case \"telegram\":\n return renderTelegramCard({\n props,\n telegram: data.telegram,\n telegramAccounts: data.channelAccounts?.telegram ?? [],\n accountCountLabel,\n });\n case \"discord\":\n return renderDiscordCard({\n props,\n discord: data.discord,\n accountCountLabel,\n });\n case \"googlechat\":\n return renderGoogleChatCard({\n props,\n googlechat: data.googlechat,\n accountCountLabel,\n });\n case \"slack\":\n return renderSlackCard({\n props,\n slack: data.slack,\n accountCountLabel,\n });\n case \"signal\":\n return renderSignalCard({\n props,\n signal: data.signal,\n accountCountLabel,\n });\n case \"imessage\":\n return renderIMessageCard({\n props,\n imessage: data.imessage,\n accountCountLabel,\n });\n case \"nostr\": {\n const nostrAccounts = data.channelAccounts?.nostr ?? [];\n const primaryAccount = nostrAccounts[0];\n const accountId = primaryAccount?.accountId ?? \"default\";\n const profile =\n (primaryAccount as { profile?: NostrProfile | null } | undefined)?.profile ?? null;\n const showForm =\n props.nostrProfileAccountId === accountId ? props.nostrProfileFormState : null;\n const profileFormCallbacks = showForm\n ? {\n onFieldChange: props.onNostrProfileFieldChange,\n onSave: props.onNostrProfileSave,\n onImport: props.onNostrProfileImport,\n onCancel: props.onNostrProfileCancel,\n onToggleAdvanced: props.onNostrProfileToggleAdvanced,\n }\n : null;\n return renderNostrCard({\n props,\n nostr: data.nostr,\n nostrAccounts,\n accountCountLabel,\n profileFormState: showForm,\n profileFormCallbacks,\n onEditProfile: () => props.onNostrProfileEdit(accountId, profile),\n });\n }\n default:\n return renderGenericChannelCard(key, props, data.channelAccounts ?? {});\n }\n}\n\nfunction renderGenericChannelCard(\n key: ChannelKey,\n props: ChannelsProps,\n channelAccounts: Record,\n) {\n const label = resolveChannelLabel(props.snapshot, key);\n const status = props.snapshot?.channels?.[key] as Record | undefined;\n const configured = typeof status?.configured === \"boolean\" ? status.configured : undefined;\n const running = typeof status?.running === \"boolean\" ? status.running : undefined;\n const connected = typeof status?.connected === \"boolean\" ? status.connected : undefined;\n const lastError = typeof status?.lastError === \"string\" ? status.lastError : undefined;\n const accounts = channelAccounts[key] ?? [];\n const accountCountLabel = renderChannelAccountCount(key, channelAccounts);\n\n return html`\n
    \n
    ${label}
    \n
    Channel status and configuration.
    \n ${accountCountLabel}\n\n ${accounts.length > 0\n ? html`\n
    \n ${accounts.map((account) => renderGenericAccount(account))}\n
    \n `\n : html`\n
    \n
    \n Configured\n ${configured == null ? \"n/a\" : configured ? \"Yes\" : \"No\"}\n
    \n
    \n Running\n ${running == null ? \"n/a\" : running ? \"Yes\" : \"No\"}\n
    \n
    \n Connected\n ${connected == null ? \"n/a\" : connected ? \"Yes\" : \"No\"}\n
    \n
    \n `}\n\n ${lastError\n ? html`
    \n ${lastError}\n
    `\n : nothing}\n\n ${renderChannelConfigSection({ channelId: key, props })}\n
    \n `;\n}\n\nfunction resolveChannelMetaMap(\n snapshot: ChannelsStatusSnapshot | null,\n): Record {\n if (!snapshot?.channelMeta?.length) return {};\n return Object.fromEntries(snapshot.channelMeta.map((entry) => [entry.id, entry]));\n}\n\nfunction resolveChannelLabel(\n snapshot: ChannelsStatusSnapshot | null,\n key: string,\n): string {\n const meta = resolveChannelMetaMap(snapshot)[key];\n return meta?.label ?? snapshot?.channelLabels?.[key] ?? key;\n}\n\nconst RECENT_ACTIVITY_THRESHOLD_MS = 10 * 60 * 1000; // 10 minutes\n\nfunction hasRecentActivity(account: ChannelAccountSnapshot): boolean {\n if (!account.lastInboundAt) return false;\n return Date.now() - account.lastInboundAt < RECENT_ACTIVITY_THRESHOLD_MS;\n}\n\nfunction deriveRunningStatus(account: ChannelAccountSnapshot): \"Yes\" | \"No\" | \"Active\" {\n if (account.running) return \"Yes\";\n // If we have recent inbound activity, the channel is effectively running\n if (hasRecentActivity(account)) return \"Active\";\n return \"No\";\n}\n\nfunction deriveConnectedStatus(account: ChannelAccountSnapshot): \"Yes\" | \"No\" | \"Active\" | \"n/a\" {\n if (account.connected === true) return \"Yes\";\n if (account.connected === false) return \"No\";\n // If connected is null/undefined but we have recent activity, show as active\n if (hasRecentActivity(account)) return \"Active\";\n return \"n/a\";\n}\n\nfunction renderGenericAccount(account: ChannelAccountSnapshot) {\n const runningStatus = deriveRunningStatus(account);\n const connectedStatus = deriveConnectedStatus(account);\n\n return html`\n
    \n
    \n
    ${account.name || account.accountId}
    \n
    ${account.accountId}
    \n
    \n
    \n
    \n Running\n ${runningStatus}\n
    \n
    \n Configured\n ${account.configured ? \"Yes\" : \"No\"}\n
    \n
    \n Connected\n ${connectedStatus}\n
    \n
    \n Last inbound\n ${account.lastInboundAt ? formatAgo(account.lastInboundAt) : \"n/a\"}\n
    \n ${account.lastError\n ? html`\n
    \n ${account.lastError}\n
    \n `\n : nothing}\n
    \n
    \n `;\n}\n","import { formatAgo, formatDurationMs, formatMs } from \"./format\";\nimport type { CronJob, GatewaySessionRow, PresenceEntry } from \"./types\";\n\nexport function formatPresenceSummary(entry: PresenceEntry): string {\n const host = entry.host ?? \"unknown\";\n const ip = entry.ip ? `(${entry.ip})` : \"\";\n const mode = entry.mode ?? \"\";\n const version = entry.version ?? \"\";\n return `${host} ${ip} ${mode} ${version}`.trim();\n}\n\nexport function formatPresenceAge(entry: PresenceEntry): string {\n const ts = entry.ts ?? null;\n return ts ? formatAgo(ts) : \"n/a\";\n}\n\nexport function formatNextRun(ms?: number | null) {\n if (!ms) return \"n/a\";\n return `${formatMs(ms)} (${formatAgo(ms)})`;\n}\n\nexport function formatSessionTokens(row: GatewaySessionRow) {\n if (row.totalTokens == null) return \"n/a\";\n const total = row.totalTokens ?? 0;\n const ctx = row.contextTokens ?? 0;\n return ctx ? `${total} / ${ctx}` : String(total);\n}\n\nexport function formatEventPayload(payload: unknown): string {\n if (payload == null) return \"\";\n try {\n return JSON.stringify(payload, null, 2);\n } catch {\n return String(payload);\n }\n}\n\nexport function formatCronState(job: CronJob) {\n const state = job.state ?? {};\n const next = state.nextRunAtMs ? formatMs(state.nextRunAtMs) : \"n/a\";\n const last = state.lastRunAtMs ? formatMs(state.lastRunAtMs) : \"n/a\";\n const status = state.lastStatus ?? \"n/a\";\n return `${status} · next ${next} · last ${last}`;\n}\n\nexport function formatCronSchedule(job: CronJob) {\n const s = job.schedule;\n if (s.kind === \"at\") return `At ${formatMs(s.atMs)}`;\n if (s.kind === \"every\") return `Every ${formatDurationMs(s.everyMs)}`;\n return `Cron ${s.expr}${s.tz ? ` (${s.tz})` : \"\"}`;\n}\n\nexport function formatCronPayload(job: CronJob) {\n const p = job.payload;\n if (p.kind === \"systemEvent\") return `System: ${p.text}`;\n return `Agent: ${p.message}`;\n}\n\n","import { html, nothing } from \"lit\";\n\nimport { formatMs } from \"../format\";\nimport {\n formatCronPayload,\n formatCronSchedule,\n formatCronState,\n formatNextRun,\n} from \"../presenter\";\nimport type { ChannelUiMetaEntry, CronJob, CronRunLogEntry, CronStatus } from \"../types\";\nimport type { CronFormState } from \"../ui-types\";\n\nexport type CronProps = {\n loading: boolean;\n status: CronStatus | null;\n jobs: CronJob[];\n error: string | null;\n busy: boolean;\n form: CronFormState;\n channels: string[];\n channelLabels?: Record;\n channelMeta?: ChannelUiMetaEntry[];\n runsJobId: string | null;\n runs: CronRunLogEntry[];\n onFormChange: (patch: Partial) => void;\n onRefresh: () => void;\n onAdd: () => void;\n onToggle: (job: CronJob, enabled: boolean) => void;\n onRun: (job: CronJob) => void;\n onRemove: (job: CronJob) => void;\n onLoadRuns: (jobId: string) => void;\n};\n\nfunction buildChannelOptions(props: CronProps): string[] {\n const options = [\"last\", ...props.channels.filter(Boolean)];\n const current = props.form.channel?.trim();\n if (current && !options.includes(current)) {\n options.push(current);\n }\n const seen = new Set();\n return options.filter((value) => {\n if (seen.has(value)) return false;\n seen.add(value);\n return true;\n });\n}\n\nfunction resolveChannelLabel(props: CronProps, channel: string): string {\n if (channel === \"last\") return \"last\";\n const meta = props.channelMeta?.find((entry) => entry.id === channel);\n if (meta?.label) return meta.label;\n return props.channelLabels?.[channel] ?? channel;\n}\n\nexport function renderCron(props: CronProps) {\n const channelOptions = buildChannelOptions(props);\n return html`\n
    \n
    \n
    Scheduler
    \n
    Gateway-owned cron scheduler status.
    \n
    \n
    \n
    Enabled
    \n
    \n ${props.status\n ? props.status.enabled\n ? \"Yes\"\n : \"No\"\n : \"n/a\"}\n
    \n
    \n
    \n
    Jobs
    \n
    ${props.status?.jobs ?? \"n/a\"}
    \n
    \n
    \n
    Next wake
    \n
    ${formatNextRun(props.status?.nextWakeAtMs ?? null)}
    \n
    \n
    \n
    \n \n ${props.error ? html`${props.error}` : nothing}\n
    \n
    \n\n
    \n
    New Job
    \n
    Create a scheduled wakeup or agent run.
    \n
    \n \n \n \n \n \n
    \n ${renderScheduleFields(props)}\n
    \n \n \n \n
    \n \n\t ${props.form.payloadKind === \"agentTurn\"\n\t ? html`\n\t
    \n \n\t \n \n \n ${props.form.sessionTarget === \"isolated\"\n ? html`\n \n `\n : nothing}\n
    \n `\n : nothing}\n
    \n \n
    \n
    \n
    \n\n
    \n
    Jobs
    \n
    All scheduled jobs stored in the gateway.
    \n ${props.jobs.length === 0\n ? html`
    No jobs yet.
    `\n : html`\n
    \n ${props.jobs.map((job) => renderJob(job, props))}\n
    \n `}\n
    \n\n
    \n
    Run history
    \n
    Latest runs for ${props.runsJobId ?? \"(select a job)\"}.
    \n ${props.runsJobId == null\n ? html`\n
    \n Select a job to inspect run history.\n
    \n `\n : props.runs.length === 0\n ? html`
    No runs yet.
    `\n : html`\n
    \n ${props.runs.map((entry) => renderRun(entry))}\n
    \n `}\n
    \n `;\n}\n\nfunction renderScheduleFields(props: CronProps) {\n const form = props.form;\n if (form.scheduleKind === \"at\") {\n return html`\n \n `;\n }\n if (form.scheduleKind === \"every\") {\n return html`\n
    \n \n \n
    \n `;\n }\n return html`\n
    \n \n \n
    \n `;\n}\n\nfunction renderJob(job: CronJob, props: CronProps) {\n const isSelected = props.runsJobId === job.id;\n const itemClass = `list-item list-item-clickable${isSelected ? \" list-item-selected\" : \"\"}`;\n return html`\n
    props.onLoadRuns(job.id)}>\n
    \n
    ${job.name}
    \n
    ${formatCronSchedule(job)}
    \n
    ${formatCronPayload(job)}
    \n ${job.agentId ? html`
    Agent: ${job.agentId}
    ` : nothing}\n
    \n ${job.enabled ? \"enabled\" : \"disabled\"}\n ${job.sessionTarget}\n ${job.wakeMode}\n
    \n
    \n
    \n
    ${formatCronState(job)}
    \n
    \n {\n event.stopPropagation();\n props.onToggle(job, !job.enabled);\n }}\n >\n ${job.enabled ? \"Disable\" : \"Enable\"}\n \n {\n event.stopPropagation();\n props.onRun(job);\n }}\n >\n Run\n \n {\n event.stopPropagation();\n props.onLoadRuns(job.id);\n }}\n >\n Runs\n \n {\n event.stopPropagation();\n props.onRemove(job);\n }}\n >\n Remove\n \n
    \n
    \n
    \n `;\n}\n\nfunction renderRun(entry: CronRunLogEntry) {\n return html`\n
    \n
    \n
    ${entry.status}
    \n
    ${entry.summary ?? \"\"}
    \n
    \n
    \n
    ${formatMs(entry.ts)}
    \n
    ${entry.durationMs ?? 0}ms
    \n ${entry.error ? html`
    ${entry.error}
    ` : nothing}\n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatEventPayload } from \"../presenter\";\nimport type { EventLogEntry } from \"../app-events\";\n\nexport type DebugProps = {\n loading: boolean;\n status: Record | null;\n health: Record | null;\n models: unknown[];\n heartbeat: unknown;\n eventLog: EventLogEntry[];\n callMethod: string;\n callParams: string;\n callResult: string | null;\n callError: string | null;\n onCallMethodChange: (next: string) => void;\n onCallParamsChange: (next: string) => void;\n onRefresh: () => void;\n onCall: () => void;\n};\n\nexport function renderDebug(props: DebugProps) {\n return html`\n
    \n
    \n
    \n
    \n
    Snapshots
    \n
    Status, health, and heartbeat data.
    \n
    \n \n
    \n
    \n
    \n
    Status
    \n
    ${JSON.stringify(props.status ?? {}, null, 2)}
    \n
    \n
    \n
    Health
    \n
    ${JSON.stringify(props.health ?? {}, null, 2)}
    \n
    \n
    \n
    Last heartbeat
    \n
    ${JSON.stringify(props.heartbeat ?? {}, null, 2)}
    \n
    \n
    \n
    \n\n
    \n
    Manual RPC
    \n
    Send a raw gateway method with JSON params.
    \n
    \n \n \n
    \n
    \n \n
    \n ${props.callError\n ? html`
    \n ${props.callError}\n
    `\n : nothing}\n ${props.callResult\n ? html`
    ${props.callResult}
    `\n : nothing}\n
    \n
    \n\n
    \n
    Models
    \n
    Catalog from models.list.
    \n
    ${JSON.stringify(\n        props.models ?? [],\n        null,\n        2,\n      )}
    \n
    \n\n
    \n
    Event Log
    \n
    Latest gateway events.
    \n ${props.eventLog.length === 0\n ? html`
    No events yet.
    `\n : html`\n
    \n ${props.eventLog.map(\n (evt) => html`\n
    \n
    \n
    ${evt.event}
    \n
    ${new Date(evt.ts).toLocaleTimeString()}
    \n
    \n
    \n
    ${formatEventPayload(evt.payload)}
    \n
    \n
    \n `,\n )}\n
    \n `}\n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatPresenceAge, formatPresenceSummary } from \"../presenter\";\nimport type { PresenceEntry } from \"../types\";\n\nexport type InstancesProps = {\n loading: boolean;\n entries: PresenceEntry[];\n lastError: string | null;\n statusMessage: string | null;\n onRefresh: () => void;\n};\n\nexport function renderInstances(props: InstancesProps) {\n return html`\n
    \n
    \n
    \n
    Connected Instances
    \n
    Presence beacons from the gateway and clients.
    \n
    \n \n
    \n ${props.lastError\n ? html`
    \n ${props.lastError}\n
    `\n : nothing}\n ${props.statusMessage\n ? html`
    \n ${props.statusMessage}\n
    `\n : nothing}\n
    \n ${props.entries.length === 0\n ? html`
    No instances reported yet.
    `\n : props.entries.map((entry) => renderEntry(entry))}\n
    \n
    \n `;\n}\n\nfunction renderEntry(entry: PresenceEntry) {\n const lastInput =\n entry.lastInputSeconds != null\n ? `${entry.lastInputSeconds}s ago`\n : \"n/a\";\n const mode = entry.mode ?? \"unknown\";\n const roles = Array.isArray(entry.roles) ? entry.roles.filter(Boolean) : [];\n const scopes = Array.isArray(entry.scopes) ? entry.scopes.filter(Boolean) : [];\n const scopesLabel =\n scopes.length > 0\n ? scopes.length > 3\n ? `${scopes.length} scopes`\n : `scopes: ${scopes.join(\", \")}`\n : null;\n return html`\n
    \n
    \n
    ${entry.host ?? \"unknown host\"}
    \n
    ${formatPresenceSummary(entry)}
    \n
    \n ${mode}\n ${roles.map((role) => html`${role}`)}\n ${scopesLabel ? html`${scopesLabel}` : nothing}\n ${entry.platform ? html`${entry.platform}` : nothing}\n ${entry.deviceFamily\n ? html`${entry.deviceFamily}`\n : nothing}\n ${entry.modelIdentifier\n ? html`${entry.modelIdentifier}`\n : nothing}\n ${entry.version ? html`${entry.version}` : nothing}\n
    \n
    \n
    \n
    ${formatPresenceAge(entry)}
    \n
    Last input ${lastInput}
    \n
    Reason ${entry.reason ?? \"\"}
    \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport type { LogEntry, LogLevel } from \"../types\";\n\nconst LEVELS: LogLevel[] = [\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"];\n\nexport type LogsProps = {\n loading: boolean;\n error: string | null;\n file: string | null;\n entries: LogEntry[];\n filterText: string;\n levelFilters: Record;\n autoFollow: boolean;\n truncated: boolean;\n onFilterTextChange: (next: string) => void;\n onLevelToggle: (level: LogLevel, enabled: boolean) => void;\n onToggleAutoFollow: (next: boolean) => void;\n onRefresh: () => void;\n onExport: (lines: string[], label: string) => void;\n onScroll: (event: Event) => void;\n};\n\nfunction formatTime(value?: string | null) {\n if (!value) return \"\";\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toLocaleTimeString();\n}\n\nfunction matchesFilter(entry: LogEntry, needle: string) {\n if (!needle) return true;\n const haystack = [entry.message, entry.subsystem, entry.raw]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(needle);\n}\n\nexport function renderLogs(props: LogsProps) {\n const needle = props.filterText.trim().toLowerCase();\n const levelFiltered = LEVELS.some((level) => !props.levelFilters[level]);\n const filtered = props.entries.filter((entry) => {\n if (entry.level && !props.levelFilters[entry.level]) return false;\n return matchesFilter(entry, needle);\n });\n const exportLabel = needle || levelFiltered ? \"filtered\" : \"visible\";\n\n return html`\n
    \n
    \n
    \n
    Logs
    \n
    Gateway file logs (JSONL).
    \n
    \n
    \n \n props.onExport(filtered.map((entry) => entry.raw), exportLabel)}\n >\n Export ${exportLabel}\n \n
    \n
    \n\n
    \n \n \n
    \n\n
    \n ${LEVELS.map(\n (level) => html`\n \n `,\n )}\n
    \n\n ${props.file\n ? html`
    File: ${props.file}
    `\n : nothing}\n ${props.truncated\n ? html`
    \n Log output truncated; showing latest chunk.\n
    `\n : nothing}\n ${props.error\n ? html`
    ${props.error}
    `\n : nothing}\n\n
    \n ${filtered.length === 0\n ? html`
    No log entries.
    `\n : filtered.map(\n (entry) => html`\n
    \n
    ${formatTime(entry.time)}
    \n
    ${entry.level ?? \"\"}
    \n
    ${entry.subsystem ?? \"\"}
    \n
    ${entry.message ?? entry.raw}
    \n
    \n `,\n )}\n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { clampText, formatAgo, formatList } from \"../format\";\nimport type {\n ExecApprovalsAllowlistEntry,\n ExecApprovalsFile,\n ExecApprovalsSnapshot,\n} from \"../controllers/exec-approvals\";\nimport type {\n DevicePairingList,\n DeviceTokenSummary,\n PairedDevice,\n PendingDevice,\n} from \"../controllers/devices\";\n\nexport type NodesProps = {\n loading: boolean;\n nodes: Array>;\n devicesLoading: boolean;\n devicesError: string | null;\n devicesList: DevicePairingList | null;\n configForm: Record | null;\n configLoading: boolean;\n configSaving: boolean;\n configDirty: boolean;\n configFormMode: \"form\" | \"raw\";\n execApprovalsLoading: boolean;\n execApprovalsSaving: boolean;\n execApprovalsDirty: boolean;\n execApprovalsSnapshot: ExecApprovalsSnapshot | null;\n execApprovalsForm: ExecApprovalsFile | null;\n execApprovalsSelectedAgent: string | null;\n execApprovalsTarget: \"gateway\" | \"node\";\n execApprovalsTargetNodeId: string | null;\n onRefresh: () => void;\n onDevicesRefresh: () => void;\n onDeviceApprove: (requestId: string) => void;\n onDeviceReject: (requestId: string) => void;\n onDeviceRotate: (deviceId: string, role: string, scopes?: string[]) => void;\n onDeviceRevoke: (deviceId: string, role: string) => void;\n onLoadConfig: () => void;\n onLoadExecApprovals: () => void;\n onBindDefault: (nodeId: string | null) => void;\n onBindAgent: (agentIndex: number, nodeId: string | null) => void;\n onSaveBindings: () => void;\n onExecApprovalsTargetChange: (kind: \"gateway\" | \"node\", nodeId: string | null) => void;\n onExecApprovalsSelectAgent: (agentId: string) => void;\n onExecApprovalsPatch: (path: Array, value: unknown) => void;\n onExecApprovalsRemove: (path: Array) => void;\n onSaveExecApprovals: () => void;\n};\n\nexport function renderNodes(props: NodesProps) {\n const bindingState = resolveBindingsState(props);\n const approvalsState = resolveExecApprovalsState(props);\n return html`\n ${renderExecApprovals(approvalsState)}\n ${renderBindings(bindingState)}\n ${renderDevices(props)}\n
    \n
    \n
    \n
    Nodes
    \n
    Paired devices and live links.
    \n
    \n \n
    \n
    \n ${props.nodes.length === 0\n ? html`
    No nodes found.
    `\n : props.nodes.map((n) => renderNode(n))}\n
    \n
    \n `;\n}\n\nfunction renderDevices(props: NodesProps) {\n const list = props.devicesList ?? { pending: [], paired: [] };\n const pending = Array.isArray(list.pending) ? list.pending : [];\n const paired = Array.isArray(list.paired) ? list.paired : [];\n return html`\n
    \n
    \n
    \n
    Devices
    \n
    Pairing requests + role tokens.
    \n
    \n \n
    \n ${props.devicesError\n ? html`
    ${props.devicesError}
    `\n : nothing}\n
    \n ${pending.length > 0\n ? html`\n
    Pending
    \n ${pending.map((req) => renderPendingDevice(req, props))}\n `\n : nothing}\n ${paired.length > 0\n ? html`\n
    Paired
    \n ${paired.map((device) => renderPairedDevice(device, props))}\n `\n : nothing}\n ${pending.length === 0 && paired.length === 0\n ? html`
    No paired devices.
    `\n : nothing}\n
    \n
    \n `;\n}\n\nfunction renderPendingDevice(req: PendingDevice, props: NodesProps) {\n const name = req.displayName?.trim() || req.deviceId;\n const age = typeof req.ts === \"number\" ? formatAgo(req.ts) : \"n/a\";\n const role = req.role?.trim() ? `role: ${req.role}` : \"role: -\";\n const repair = req.isRepair ? \" · repair\" : \"\";\n const ip = req.remoteIp ? ` · ${req.remoteIp}` : \"\";\n return html`\n
    \n
    \n
    ${name}
    \n
    ${req.deviceId}${ip}
    \n
    \n ${role} · requested ${age}${repair}\n
    \n
    \n
    \n
    \n \n \n
    \n
    \n
    \n `;\n}\n\nfunction renderPairedDevice(device: PairedDevice, props: NodesProps) {\n const name = device.displayName?.trim() || device.deviceId;\n const ip = device.remoteIp ? ` · ${device.remoteIp}` : \"\";\n const roles = `roles: ${formatList(device.roles)}`;\n const scopes = `scopes: ${formatList(device.scopes)}`;\n const tokens = Array.isArray(device.tokens) ? device.tokens : [];\n return html`\n
    \n
    \n
    ${name}
    \n
    ${device.deviceId}${ip}
    \n
    ${roles} · ${scopes}
    \n ${tokens.length === 0\n ? html`
    Tokens: none
    `\n : html`\n
    Tokens
    \n
    \n ${tokens.map((token) => renderTokenRow(device.deviceId, token, props))}\n
    \n `}\n
    \n
    \n `;\n}\n\nfunction renderTokenRow(deviceId: string, token: DeviceTokenSummary, props: NodesProps) {\n const status = token.revokedAtMs ? \"revoked\" : \"active\";\n const scopes = `scopes: ${formatList(token.scopes)}`;\n const when = formatAgo(token.rotatedAtMs ?? token.createdAtMs ?? token.lastUsedAtMs ?? null);\n return html`\n
    \n
    ${token.role} · ${status} · ${scopes} · ${when}
    \n
    \n props.onDeviceRotate(deviceId, token.role, token.scopes)}\n >\n Rotate\n \n ${token.revokedAtMs\n ? nothing\n : html`\n props.onDeviceRevoke(deviceId, token.role)}\n >\n Revoke\n \n `}\n
    \n
    \n `;\n}\n\ntype BindingAgent = {\n id: string;\n name?: string;\n index: number;\n isDefault: boolean;\n binding?: string | null;\n};\n\ntype BindingNode = {\n id: string;\n label: string;\n};\n\ntype BindingState = {\n ready: boolean;\n disabled: boolean;\n configDirty: boolean;\n configLoading: boolean;\n configSaving: boolean;\n defaultBinding?: string | null;\n agents: BindingAgent[];\n nodes: BindingNode[];\n onBindDefault: (nodeId: string | null) => void;\n onBindAgent: (agentIndex: number, nodeId: string | null) => void;\n onSave: () => void;\n onLoadConfig: () => void;\n formMode: \"form\" | \"raw\";\n};\n\ntype ExecSecurity = \"deny\" | \"allowlist\" | \"full\";\ntype ExecAsk = \"off\" | \"on-miss\" | \"always\";\n\ntype ExecApprovalsResolvedDefaults = {\n security: ExecSecurity;\n ask: ExecAsk;\n askFallback: ExecSecurity;\n autoAllowSkills: boolean;\n};\n\ntype ExecApprovalsAgentOption = {\n id: string;\n name?: string;\n isDefault?: boolean;\n};\n\ntype ExecApprovalsTargetNode = {\n id: string;\n label: string;\n};\n\ntype ExecApprovalsState = {\n ready: boolean;\n disabled: boolean;\n dirty: boolean;\n loading: boolean;\n saving: boolean;\n form: ExecApprovalsFile | null;\n defaults: ExecApprovalsResolvedDefaults;\n selectedScope: string;\n selectedAgent: Record | null;\n agents: ExecApprovalsAgentOption[];\n allowlist: ExecApprovalsAllowlistEntry[];\n target: \"gateway\" | \"node\";\n targetNodeId: string | null;\n targetNodes: ExecApprovalsTargetNode[];\n onSelectScope: (agentId: string) => void;\n onSelectTarget: (kind: \"gateway\" | \"node\", nodeId: string | null) => void;\n onPatch: (path: Array, value: unknown) => void;\n onRemove: (path: Array) => void;\n onLoad: () => void;\n onSave: () => void;\n};\n\nconst EXEC_APPROVALS_DEFAULT_SCOPE = \"__defaults__\";\n\nconst SECURITY_OPTIONS: Array<{ value: ExecSecurity; label: string }> = [\n { value: \"deny\", label: \"Deny\" },\n { value: \"allowlist\", label: \"Allowlist\" },\n { value: \"full\", label: \"Full\" },\n];\n\nconst ASK_OPTIONS: Array<{ value: ExecAsk; label: string }> = [\n { value: \"off\", label: \"Off\" },\n { value: \"on-miss\", label: \"On miss\" },\n { value: \"always\", label: \"Always\" },\n];\n\nfunction resolveBindingsState(props: NodesProps): BindingState {\n const config = props.configForm;\n const nodes = resolveExecNodes(props.nodes);\n const { defaultBinding, agents } = resolveAgentBindings(config);\n const ready = Boolean(config);\n const disabled = props.configSaving || props.configFormMode === \"raw\";\n return {\n ready,\n disabled,\n configDirty: props.configDirty,\n configLoading: props.configLoading,\n configSaving: props.configSaving,\n defaultBinding,\n agents,\n nodes,\n onBindDefault: props.onBindDefault,\n onBindAgent: props.onBindAgent,\n onSave: props.onSaveBindings,\n onLoadConfig: props.onLoadConfig,\n formMode: props.configFormMode,\n };\n}\n\nfunction normalizeSecurity(value?: string): ExecSecurity {\n if (value === \"allowlist\" || value === \"full\" || value === \"deny\") return value;\n return \"deny\";\n}\n\nfunction normalizeAsk(value?: string): ExecAsk {\n if (value === \"always\" || value === \"off\" || value === \"on-miss\") return value;\n return \"on-miss\";\n}\n\nfunction resolveExecApprovalsDefaults(\n form: ExecApprovalsFile | null,\n): ExecApprovalsResolvedDefaults {\n const defaults = form?.defaults ?? {};\n return {\n security: normalizeSecurity(defaults.security),\n ask: normalizeAsk(defaults.ask),\n askFallback: normalizeSecurity(defaults.askFallback ?? \"deny\"),\n autoAllowSkills: Boolean(defaults.autoAllowSkills ?? false),\n };\n}\n\nfunction resolveConfigAgents(config: Record | null): ExecApprovalsAgentOption[] {\n const agentsNode = (config?.agents ?? {}) as Record;\n const list = Array.isArray(agentsNode.list) ? agentsNode.list : [];\n const agents: ExecApprovalsAgentOption[] = [];\n list.forEach((entry) => {\n if (!entry || typeof entry !== \"object\") return;\n const record = entry as Record;\n const id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n if (!id) return;\n const name = typeof record.name === \"string\" ? record.name.trim() : undefined;\n const isDefault = record.default === true;\n agents.push({ id, name: name || undefined, isDefault });\n });\n return agents;\n}\n\nfunction resolveExecApprovalsAgents(\n config: Record | null,\n form: ExecApprovalsFile | null,\n): ExecApprovalsAgentOption[] {\n const configAgents = resolveConfigAgents(config);\n const approvalsAgents = Object.keys(form?.agents ?? {});\n const merged = new Map();\n configAgents.forEach((agent) => merged.set(agent.id, agent));\n approvalsAgents.forEach((id) => {\n if (merged.has(id)) return;\n merged.set(id, { id });\n });\n const agents = Array.from(merged.values());\n if (agents.length === 0) {\n agents.push({ id: \"main\", isDefault: true });\n }\n agents.sort((a, b) => {\n if (a.isDefault && !b.isDefault) return -1;\n if (!a.isDefault && b.isDefault) return 1;\n const aLabel = a.name?.trim() ? a.name : a.id;\n const bLabel = b.name?.trim() ? b.name : b.id;\n return aLabel.localeCompare(bLabel);\n });\n return agents;\n}\n\nfunction resolveExecApprovalsScope(\n selected: string | null,\n agents: ExecApprovalsAgentOption[],\n): string {\n if (selected === EXEC_APPROVALS_DEFAULT_SCOPE) return EXEC_APPROVALS_DEFAULT_SCOPE;\n if (selected && agents.some((agent) => agent.id === selected)) return selected;\n return EXEC_APPROVALS_DEFAULT_SCOPE;\n}\n\nfunction resolveExecApprovalsState(props: NodesProps): ExecApprovalsState {\n const form = props.execApprovalsForm ?? props.execApprovalsSnapshot?.file ?? null;\n const ready = Boolean(form);\n const defaults = resolveExecApprovalsDefaults(form);\n const agents = resolveExecApprovalsAgents(props.configForm, form);\n const targetNodes = resolveExecApprovalsNodes(props.nodes);\n const target = props.execApprovalsTarget;\n let targetNodeId =\n target === \"node\" && props.execApprovalsTargetNodeId\n ? props.execApprovalsTargetNodeId\n : null;\n if (target === \"node\" && targetNodeId && !targetNodes.some((node) => node.id === targetNodeId)) {\n targetNodeId = null;\n }\n const selectedScope = resolveExecApprovalsScope(props.execApprovalsSelectedAgent, agents);\n const selectedAgent =\n selectedScope !== EXEC_APPROVALS_DEFAULT_SCOPE\n ? ((form?.agents ?? {})[selectedScope] as Record | undefined) ??\n null\n : null;\n const allowlist = Array.isArray((selectedAgent as { allowlist?: unknown })?.allowlist)\n ? ((selectedAgent as { allowlist?: ExecApprovalsAllowlistEntry[] }).allowlist ??\n [])\n : [];\n return {\n ready,\n disabled: props.execApprovalsSaving || props.execApprovalsLoading,\n dirty: props.execApprovalsDirty,\n loading: props.execApprovalsLoading,\n saving: props.execApprovalsSaving,\n form,\n defaults,\n selectedScope,\n selectedAgent,\n agents,\n allowlist,\n target,\n targetNodeId,\n targetNodes,\n onSelectScope: props.onExecApprovalsSelectAgent,\n onSelectTarget: props.onExecApprovalsTargetChange,\n onPatch: props.onExecApprovalsPatch,\n onRemove: props.onExecApprovalsRemove,\n onLoad: props.onLoadExecApprovals,\n onSave: props.onSaveExecApprovals,\n };\n}\n\nfunction renderBindings(state: BindingState) {\n const supportsBinding = state.nodes.length > 0;\n const defaultValue = state.defaultBinding ?? \"\";\n return html`\n
    \n
    \n
    \n
    Exec node binding
    \n
    \n Pin agents to a specific node when using exec host=node.\n
    \n
    \n \n ${state.configSaving ? \"Saving…\" : \"Save\"}\n \n
    \n\n ${state.formMode === \"raw\"\n ? html`
    \n Switch the Config tab to Form mode to edit bindings here.\n
    `\n : nothing}\n\n ${!state.ready\n ? html`
    \n
    Load config to edit bindings.
    \n \n
    `\n : html`\n
    \n
    \n
    \n
    Default binding
    \n
    Used when agents do not override a node binding.
    \n
    \n
    \n \n ${!supportsBinding\n ? html`
    No nodes with system.run available.
    `\n : nothing}\n
    \n
    \n\n ${state.agents.length === 0\n ? html`
    No agents found.
    `\n : state.agents.map((agent) =>\n renderAgentBinding(agent, state),\n )}\n
    \n `}\n
    \n `;\n}\n\nfunction renderExecApprovals(state: ExecApprovalsState) {\n const ready = state.ready;\n const targetReady = state.target !== \"node\" || Boolean(state.targetNodeId);\n return html`\n
    \n
    \n
    \n
    Exec approvals
    \n
    \n Allowlist and approval policy for exec host=gateway/node.\n
    \n
    \n \n ${state.saving ? \"Saving…\" : \"Save\"}\n \n
    \n\n ${renderExecApprovalsTarget(state)}\n\n ${!ready\n ? html`
    \n
    Load exec approvals to edit allowlists.
    \n \n
    `\n : html`\n ${renderExecApprovalsTabs(state)}\n ${renderExecApprovalsPolicy(state)}\n ${state.selectedScope === EXEC_APPROVALS_DEFAULT_SCOPE\n ? nothing\n : renderExecApprovalsAllowlist(state)}\n `}\n
    \n `;\n}\n\nfunction renderExecApprovalsTarget(state: ExecApprovalsState) {\n const hasNodes = state.targetNodes.length > 0;\n const nodeValue = state.targetNodeId ?? \"\";\n return html`\n
    \n
    \n
    \n
    Target
    \n
    \n Gateway edits local approvals; node edits the selected node.\n
    \n
    \n
    \n \n ${state.target === \"node\"\n ? html`\n \n `\n : nothing}\n
    \n
    \n ${state.target === \"node\" && !hasNodes\n ? html`
    No nodes advertise exec approvals yet.
    `\n : nothing}\n
    \n `;\n}\n\nfunction renderExecApprovalsTabs(state: ExecApprovalsState) {\n return html`\n
    \n Scope\n
    \n state.onSelectScope(EXEC_APPROVALS_DEFAULT_SCOPE)}\n >\n Defaults\n \n ${state.agents.map((agent) => {\n const label = agent.name?.trim() ? `${agent.name} (${agent.id})` : agent.id;\n return html`\n state.onSelectScope(agent.id)}\n >\n ${label}\n \n `;\n })}\n
    \n
    \n `;\n}\n\nfunction renderExecApprovalsPolicy(state: ExecApprovalsState) {\n const isDefaults = state.selectedScope === EXEC_APPROVALS_DEFAULT_SCOPE;\n const defaults = state.defaults;\n const agent = state.selectedAgent ?? {};\n const basePath = isDefaults ? [\"defaults\"] : [\"agents\", state.selectedScope];\n const agentSecurity = typeof agent.security === \"string\" ? agent.security : undefined;\n const agentAsk = typeof agent.ask === \"string\" ? agent.ask : undefined;\n const agentAskFallback =\n typeof agent.askFallback === \"string\" ? agent.askFallback : undefined;\n const securityValue = isDefaults ? defaults.security : agentSecurity ?? \"__default__\";\n const askValue = isDefaults ? defaults.ask : agentAsk ?? \"__default__\";\n const askFallbackValue = isDefaults\n ? defaults.askFallback\n : agentAskFallback ?? \"__default__\";\n const autoOverride =\n typeof agent.autoAllowSkills === \"boolean\" ? agent.autoAllowSkills : undefined;\n const autoEffective = autoOverride ?? defaults.autoAllowSkills;\n const autoIsDefault = autoOverride == null;\n\n return html`\n
    \n
    \n
    \n
    Security
    \n
    \n ${isDefaults\n ? \"Default security mode.\"\n : `Default: ${defaults.security}.`}\n
    \n
    \n
    \n \n
    \n
    \n\n
    \n
    \n
    Ask
    \n
    \n ${isDefaults ? \"Default prompt policy.\" : `Default: ${defaults.ask}.`}\n
    \n
    \n
    \n \n
    \n
    \n\n
    \n
    \n
    Ask fallback
    \n
    \n ${isDefaults\n ? \"Applied when the UI prompt is unavailable.\"\n : `Default: ${defaults.askFallback}.`}\n
    \n
    \n
    \n \n
    \n
    \n\n
    \n
    \n
    Auto-allow skill CLIs
    \n
    \n ${isDefaults\n ? \"Allow skill executables listed by the Gateway.\"\n : autoIsDefault\n ? `Using default (${defaults.autoAllowSkills ? \"on\" : \"off\"}).`\n : `Override (${autoEffective ? \"on\" : \"off\"}).`}\n
    \n
    \n
    \n \n ${!isDefaults && !autoIsDefault\n ? html` state.onRemove([...basePath, \"autoAllowSkills\"])}\n >\n Use default\n `\n : nothing}\n
    \n
    \n
    \n `;\n}\n\nfunction renderExecApprovalsAllowlist(state: ExecApprovalsState) {\n const allowlistPath = [\"agents\", state.selectedScope, \"allowlist\"];\n const entries = state.allowlist;\n return html`\n
    \n
    \n
    Allowlist
    \n
    Case-insensitive glob patterns.
    \n
    \n {\n const next = [...entries, { pattern: \"\" }];\n state.onPatch(allowlistPath, next);\n }}\n >\n Add pattern\n \n
    \n
    \n ${entries.length === 0\n ? html`
    No allowlist entries yet.
    `\n : entries.map((entry, index) =>\n renderAllowlistEntry(state, entry, index),\n )}\n
    \n `;\n}\n\nfunction renderAllowlistEntry(\n state: ExecApprovalsState,\n entry: ExecApprovalsAllowlistEntry,\n index: number,\n) {\n const lastUsed = entry.lastUsedAt ? formatAgo(entry.lastUsedAt) : \"never\";\n const lastCommand = entry.lastUsedCommand\n ? clampText(entry.lastUsedCommand, 120)\n : null;\n const lastPath = entry.lastResolvedPath\n ? clampText(entry.lastResolvedPath, 120)\n : null;\n return html`\n
    \n
    \n
    ${entry.pattern?.trim() ? entry.pattern : \"New pattern\"}
    \n
    Last used: ${lastUsed}
    \n ${lastCommand ? html`
    ${lastCommand}
    ` : nothing}\n ${lastPath ? html`
    ${lastPath}
    ` : nothing}\n
    \n
    \n \n {\n if (state.allowlist.length <= 1) {\n state.onRemove([\"agents\", state.selectedScope, \"allowlist\"]);\n return;\n }\n state.onRemove([\"agents\", state.selectedScope, \"allowlist\", index]);\n }}\n >\n Remove\n \n
    \n
    \n `;\n}\n\nfunction renderAgentBinding(agent: BindingAgent, state: BindingState) {\n const bindingValue = agent.binding ?? \"__default__\";\n const label = agent.name?.trim() ? `${agent.name} (${agent.id})` : agent.id;\n const supportsBinding = state.nodes.length > 0;\n return html`\n
    \n
    \n
    ${label}
    \n
    \n ${agent.isDefault ? \"default agent\" : \"agent\"} ·\n ${bindingValue === \"__default__\"\n ? `uses default (${state.defaultBinding ?? \"any\"})`\n : `override: ${agent.binding}`}\n
    \n
    \n
    \n \n
    \n
    \n `;\n}\n\nfunction resolveExecNodes(nodes: Array>): BindingNode[] {\n const list: BindingNode[] = [];\n for (const node of nodes) {\n const commands = Array.isArray(node.commands) ? node.commands : [];\n const supports = commands.some((cmd) => String(cmd) === \"system.run\");\n if (!supports) continue;\n const nodeId = typeof node.nodeId === \"string\" ? node.nodeId.trim() : \"\";\n if (!nodeId) continue;\n const displayName =\n typeof node.displayName === \"string\" && node.displayName.trim()\n ? node.displayName.trim()\n : nodeId;\n list.push({ id: nodeId, label: displayName === nodeId ? nodeId : `${displayName} · ${nodeId}` });\n }\n list.sort((a, b) => a.label.localeCompare(b.label));\n return list;\n}\n\nfunction resolveExecApprovalsNodes(nodes: Array>): ExecApprovalsTargetNode[] {\n const list: ExecApprovalsTargetNode[] = [];\n for (const node of nodes) {\n const commands = Array.isArray(node.commands) ? node.commands : [];\n const supports = commands.some(\n (cmd) => String(cmd) === \"system.execApprovals.get\" || String(cmd) === \"system.execApprovals.set\",\n );\n if (!supports) continue;\n const nodeId = typeof node.nodeId === \"string\" ? node.nodeId.trim() : \"\";\n if (!nodeId) continue;\n const displayName =\n typeof node.displayName === \"string\" && node.displayName.trim()\n ? node.displayName.trim()\n : nodeId;\n list.push({ id: nodeId, label: displayName === nodeId ? nodeId : `${displayName} · ${nodeId}` });\n }\n list.sort((a, b) => a.label.localeCompare(b.label));\n return list;\n}\n\nfunction resolveAgentBindings(config: Record | null): {\n defaultBinding?: string | null;\n agents: BindingAgent[];\n} {\n const fallbackAgent: BindingAgent = {\n id: \"main\",\n name: undefined,\n index: 0,\n isDefault: true,\n binding: null,\n };\n if (!config || typeof config !== \"object\") {\n return { defaultBinding: null, agents: [fallbackAgent] };\n }\n const tools = (config.tools ?? {}) as Record;\n const exec = (tools.exec ?? {}) as Record;\n const defaultBinding =\n typeof exec.node === \"string\" && exec.node.trim() ? exec.node.trim() : null;\n\n const agentsNode = (config.agents ?? {}) as Record;\n const list = Array.isArray(agentsNode.list) ? agentsNode.list : [];\n if (list.length === 0) {\n return { defaultBinding, agents: [fallbackAgent] };\n }\n\n const agents: BindingAgent[] = [];\n list.forEach((entry, index) => {\n if (!entry || typeof entry !== \"object\") return;\n const record = entry as Record;\n const id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n if (!id) return;\n const name = typeof record.name === \"string\" ? record.name.trim() : undefined;\n const isDefault = record.default === true;\n const toolsEntry = (record.tools ?? {}) as Record;\n const execEntry = (toolsEntry.exec ?? {}) as Record;\n const binding =\n typeof execEntry.node === \"string\" && execEntry.node.trim()\n ? execEntry.node.trim()\n : null;\n agents.push({\n id,\n name: name || undefined,\n index,\n isDefault,\n binding,\n });\n });\n\n if (agents.length === 0) {\n agents.push(fallbackAgent);\n }\n\n return { defaultBinding, agents };\n}\n\nfunction renderNode(node: Record) {\n const connected = Boolean(node.connected);\n const paired = Boolean(node.paired);\n const title =\n (typeof node.displayName === \"string\" && node.displayName.trim()) ||\n (typeof node.nodeId === \"string\" ? node.nodeId : \"unknown\");\n const caps = Array.isArray(node.caps) ? (node.caps as unknown[]) : [];\n const commands = Array.isArray(node.commands) ? (node.commands as unknown[]) : [];\n return html`\n
    \n
    \n
    ${title}
    \n
    \n ${typeof node.nodeId === \"string\" ? node.nodeId : \"\"}\n ${typeof node.remoteIp === \"string\" ? ` · ${node.remoteIp}` : \"\"}\n ${typeof node.version === \"string\" ? ` · ${node.version}` : \"\"}\n
    \n
    \n ${paired ? \"paired\" : \"unpaired\"}\n \n ${connected ? \"connected\" : \"offline\"}\n \n ${caps.slice(0, 12).map((c) => html`${String(c)}`)}\n ${commands\n .slice(0, 8)\n .map((c) => html`${String(c)}`)}\n
    \n
    \n
    \n `;\n}\n","import { html } from \"lit\";\n\nimport type { GatewayHelloOk } from \"../gateway\";\nimport { formatAgo, formatDurationMs } from \"../format\";\nimport { formatNextRun } from \"../presenter\";\nimport type { UiSettings } from \"../storage\";\n\nexport type OverviewProps = {\n connected: boolean;\n hello: GatewayHelloOk | null;\n settings: UiSettings;\n password: string;\n lastError: string | null;\n presenceCount: number;\n sessionsCount: number | null;\n cronEnabled: boolean | null;\n cronNext: number | null;\n lastChannelsRefresh: number | null;\n onSettingsChange: (next: UiSettings) => void;\n onPasswordChange: (next: string) => void;\n onSessionKeyChange: (next: string) => void;\n onConnect: () => void;\n onRefresh: () => void;\n};\n\nexport function renderOverview(props: OverviewProps) {\n const snapshot = props.hello?.snapshot as\n | { uptimeMs?: number; policy?: { tickIntervalMs?: number } }\n | undefined;\n const uptime = snapshot?.uptimeMs ? formatDurationMs(snapshot.uptimeMs) : \"n/a\";\n const tick = snapshot?.policy?.tickIntervalMs\n ? `${snapshot.policy.tickIntervalMs}ms`\n : \"n/a\";\n const authHint = (() => {\n if (props.connected || !props.lastError) return null;\n const lower = props.lastError.toLowerCase();\n const authFailed = lower.includes(\"unauthorized\") || lower.includes(\"connect failed\");\n if (!authFailed) return null;\n const hasToken = Boolean(props.settings.token.trim());\n const hasPassword = Boolean(props.password.trim());\n if (!hasToken && !hasPassword) {\n return html`\n
    \n This gateway requires auth. Add a token or password, then click Connect.\n
    \n clawdbot dashboard --no-open → tokenized URL
    \n clawdbot doctor --generate-gateway-token → set token\n
    \n
    \n Docs: Control UI auth\n
    \n
    \n `;\n }\n return html`\n
    \n Auth failed. Re-copy a tokenized URL with\n clawdbot dashboard --no-open, or update the token,\n then click Connect.\n
    \n Docs: Control UI auth\n
    \n
    \n `;\n })();\n const insecureContextHint = (() => {\n if (props.connected || !props.lastError) return null;\n const isSecureContext = typeof window !== \"undefined\" ? window.isSecureContext : true;\n if (isSecureContext !== false) return null;\n const lower = props.lastError.toLowerCase();\n if (!lower.includes(\"secure context\") && !lower.includes(\"device identity required\")) {\n return null;\n }\n return html`\n
    \n This page is HTTP, so the browser blocks device identity. Use HTTPS (Tailscale Serve) or\n open http://127.0.0.1:18789 on the gateway host.\n
    \n If you must stay on HTTP, set\n gateway.controlUi.allowInsecureAuth: true (token-only).\n
    \n
    \n Docs: Tailscale Serve\n · \n Docs: Insecure HTTP\n
    \n
    \n `;\n })();\n\n return html`\n
    \n
    \n
    Gateway Access
    \n
    Where the dashboard connects and how it authenticates.
    \n
    \n \n \n \n \n
    \n
    \n \n \n Click Connect to apply connection changes.\n
    \n
    \n\n
    \n
    Snapshot
    \n
    Latest gateway handshake information.
    \n
    \n
    \n
    Status
    \n
    \n ${props.connected ? \"Connected\" : \"Disconnected\"}\n
    \n
    \n
    \n
    Uptime
    \n
    ${uptime}
    \n
    \n
    \n
    Tick Interval
    \n
    ${tick}
    \n
    \n
    \n
    Last Channels Refresh
    \n
    \n ${props.lastChannelsRefresh\n ? formatAgo(props.lastChannelsRefresh)\n : \"n/a\"}\n
    \n
    \n
    \n ${props.lastError\n ? html`
    \n
    ${props.lastError}
    \n ${authHint ?? \"\"}\n ${insecureContextHint ?? \"\"}\n
    `\n : html`
    \n Use Channels to link WhatsApp, Telegram, Discord, Signal, or iMessage.\n
    `}\n
    \n
    \n\n
    \n
    \n
    Instances
    \n
    ${props.presenceCount}
    \n
    Presence beacons in the last 5 minutes.
    \n
    \n
    \n
    Sessions
    \n
    ${props.sessionsCount ?? \"n/a\"}
    \n
    Recent session keys tracked by the gateway.
    \n
    \n
    \n
    Cron
    \n
    \n ${props.cronEnabled == null\n ? \"n/a\"\n : props.cronEnabled\n ? \"Enabled\"\n : \"Disabled\"}\n
    \n
    Next wake ${formatNextRun(props.cronNext)}
    \n
    \n
    \n\n
    \n
    Notes
    \n
    Quick reminders for remote control setups.
    \n
    \n
    \n
    Tailscale serve
    \n
    \n Prefer serve mode to keep the gateway on loopback with tailnet auth.\n
    \n
    \n
    \n
    Session hygiene
    \n
    Use /new or sessions.patch to reset context.
    \n
    \n
    \n
    Cron reminders
    \n
    Use isolated sessions for recurring runs.
    \n
    \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { formatAgo } from \"../format\";\nimport { formatSessionTokens } from \"../presenter\";\nimport { pathForTab } from \"../navigation\";\nimport type { GatewaySessionRow, SessionsListResult } from \"../types\";\n\nexport type SessionsProps = {\n loading: boolean;\n result: SessionsListResult | null;\n error: string | null;\n activeMinutes: string;\n limit: string;\n includeGlobal: boolean;\n includeUnknown: boolean;\n basePath: string;\n onFiltersChange: (next: {\n activeMinutes: string;\n limit: string;\n includeGlobal: boolean;\n includeUnknown: boolean;\n }) => void;\n onRefresh: () => void;\n onPatch: (\n key: string,\n patch: {\n label?: string | null;\n thinkingLevel?: string | null;\n verboseLevel?: string | null;\n reasoningLevel?: string | null;\n },\n ) => void;\n onDelete: (key: string) => void;\n};\n\nconst THINK_LEVELS = [\"\", \"off\", \"minimal\", \"low\", \"medium\", \"high\"] as const;\nconst BINARY_THINK_LEVELS = [\"\", \"off\", \"on\"] as const;\nconst VERBOSE_LEVELS = [\n { value: \"\", label: \"inherit\" },\n { value: \"off\", label: \"off (explicit)\" },\n { value: \"on\", label: \"on\" },\n] as const;\nconst REASONING_LEVELS = [\"\", \"off\", \"on\", \"stream\"] as const;\n\nfunction normalizeProviderId(provider?: string | null): string {\n if (!provider) return \"\";\n const normalized = provider.trim().toLowerCase();\n if (normalized === \"z.ai\" || normalized === \"z-ai\") return \"zai\";\n return normalized;\n}\n\nfunction isBinaryThinkingProvider(provider?: string | null): boolean {\n return normalizeProviderId(provider) === \"zai\";\n}\n\nfunction resolveThinkLevelOptions(provider?: string | null): readonly string[] {\n return isBinaryThinkingProvider(provider) ? BINARY_THINK_LEVELS : THINK_LEVELS;\n}\n\nfunction resolveThinkLevelDisplay(value: string, isBinary: boolean): string {\n if (!isBinary) return value;\n if (!value || value === \"off\") return value;\n return \"on\";\n}\n\nfunction resolveThinkLevelPatchValue(value: string, isBinary: boolean): string | null {\n if (!value) return null;\n if (!isBinary) return value;\n if (value === \"on\") return \"low\";\n return value;\n}\n\nexport function renderSessions(props: SessionsProps) {\n const rows = props.result?.sessions ?? [];\n return html`\n
    \n
    \n
    \n
    Sessions
    \n
    Active session keys and per-session overrides.
    \n
    \n \n
    \n\n
    \n \n \n \n \n
    \n\n ${props.error\n ? html`
    ${props.error}
    `\n : nothing}\n\n
    \n ${props.result ? `Store: ${props.result.path}` : \"\"}\n
    \n\n
    \n
    \n
    Key
    \n
    Label
    \n
    Kind
    \n
    Updated
    \n
    Tokens
    \n
    Thinking
    \n
    Verbose
    \n
    Reasoning
    \n
    Actions
    \n
    \n ${rows.length === 0\n ? html`
    No sessions found.
    `\n : rows.map((row) =>\n renderRow(row, props.basePath, props.onPatch, props.onDelete, props.loading),\n )}\n
    \n
    \n `;\n}\n\nfunction renderRow(\n row: GatewaySessionRow,\n basePath: string,\n onPatch: SessionsProps[\"onPatch\"],\n onDelete: SessionsProps[\"onDelete\"],\n disabled: boolean,\n) {\n const updated = row.updatedAt ? formatAgo(row.updatedAt) : \"n/a\";\n const rawThinking = row.thinkingLevel ?? \"\";\n const isBinaryThinking = isBinaryThinkingProvider(row.modelProvider);\n const thinking = resolveThinkLevelDisplay(rawThinking, isBinaryThinking);\n const thinkLevels = resolveThinkLevelOptions(row.modelProvider);\n const verbose = row.verboseLevel ?? \"\";\n const reasoning = row.reasoningLevel ?? \"\";\n const displayName = row.displayName ?? row.key;\n const canLink = row.kind !== \"global\";\n const chatUrl = canLink\n ? `${pathForTab(\"chat\", basePath)}?session=${encodeURIComponent(row.key)}`\n : null;\n\n return html`\n
    \n
    ${canLink\n ? html`${displayName}`\n : displayName}
    \n
    \n {\n const value = (e.target as HTMLInputElement).value.trim();\n onPatch(row.key, { label: value || null });\n }}\n />\n
    \n
    ${row.kind}
    \n
    ${updated}
    \n
    ${formatSessionTokens(row)}
    \n
    \n {\n const value = (e.target as HTMLSelectElement).value;\n onPatch(row.key, {\n thinkingLevel: resolveThinkLevelPatchValue(value, isBinaryThinking),\n });\n }}\n >\n ${thinkLevels.map((level) =>\n html``,\n )}\n \n
    \n
    \n {\n const value = (e.target as HTMLSelectElement).value;\n onPatch(row.key, { verboseLevel: value || null });\n }}\n >\n ${VERBOSE_LEVELS.map(\n (level) => html``,\n )}\n \n
    \n
    \n {\n const value = (e.target as HTMLSelectElement).value;\n onPatch(row.key, { reasoningLevel: value || null });\n }}\n >\n ${REASONING_LEVELS.map((level) =>\n html``,\n )}\n \n
    \n
    \n \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport type { AppViewState } from \"../app-view-state\";\n\nfunction formatRemaining(ms: number): string {\n const remaining = Math.max(0, ms);\n const totalSeconds = Math.floor(remaining / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h`;\n}\n\nfunction renderMetaRow(label: string, value?: string | null) {\n if (!value) return nothing;\n return html`
    ${label}${value}
    `;\n}\n\nexport function renderExecApprovalPrompt(state: AppViewState) {\n const active = state.execApprovalQueue[0];\n if (!active) return nothing;\n const request = active.request;\n const remainingMs = active.expiresAtMs - Date.now();\n const remaining = remainingMs > 0 ? `expires in ${formatRemaining(remainingMs)}` : \"expired\";\n const queueCount = state.execApprovalQueue.length;\n return html`\n
    \n
    \n
    \n
    \n
    Exec approval needed
    \n
    ${remaining}
    \n
    \n ${queueCount > 1\n ? html`
    ${queueCount} pending
    `\n : nothing}\n
    \n
    ${request.command}
    \n
    \n ${renderMetaRow(\"Host\", request.host)}\n ${renderMetaRow(\"Agent\", request.agentId)}\n ${renderMetaRow(\"Session\", request.sessionKey)}\n ${renderMetaRow(\"CWD\", request.cwd)}\n ${renderMetaRow(\"Resolved\", request.resolvedPath)}\n ${renderMetaRow(\"Security\", request.security)}\n ${renderMetaRow(\"Ask\", request.ask)}\n
    \n ${state.execApprovalError\n ? html`
    ${state.execApprovalError}
    `\n : nothing}\n
    \n state.handleExecApprovalDecision(\"allow-once\")}\n >\n Allow once\n \n state.handleExecApprovalDecision(\"allow-always\")}\n >\n Always allow\n \n state.handleExecApprovalDecision(\"deny\")}\n >\n Deny\n \n
    \n
    \n
    \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport { clampText } from \"../format\";\nimport type { SkillStatusEntry, SkillStatusReport } from \"../types\";\nimport type { SkillMessageMap } from \"../controllers/skills\";\n\nexport type SkillsProps = {\n loading: boolean;\n report: SkillStatusReport | null;\n error: string | null;\n filter: string;\n edits: Record;\n busyKey: string | null;\n messages: SkillMessageMap;\n onFilterChange: (next: string) => void;\n onRefresh: () => void;\n onToggle: (skillKey: string, enabled: boolean) => void;\n onEdit: (skillKey: string, value: string) => void;\n onSaveKey: (skillKey: string) => void;\n onInstall: (skillKey: string, name: string, installId: string) => void;\n};\n\nexport function renderSkills(props: SkillsProps) {\n const skills = props.report?.skills ?? [];\n const filter = props.filter.trim().toLowerCase();\n const filtered = filter\n ? skills.filter((skill) =>\n [skill.name, skill.description, skill.source]\n .join(\" \")\n .toLowerCase()\n .includes(filter),\n )\n : skills;\n\n return html`\n
    \n
    \n
    \n
    Skills
    \n
    Bundled, managed, and workspace skills.
    \n
    \n \n
    \n\n
    \n \n
    ${filtered.length} shown
    \n
    \n\n ${props.error\n ? html`
    ${props.error}
    `\n : nothing}\n\n ${filtered.length === 0\n ? html`
    No skills found.
    `\n : html`\n
    \n ${filtered.map((skill) => renderSkill(skill, props))}\n
    \n `}\n
    \n `;\n}\n\nfunction renderSkill(skill: SkillStatusEntry, props: SkillsProps) {\n const busy = props.busyKey === skill.skillKey;\n const apiKey = props.edits[skill.skillKey] ?? \"\";\n const message = props.messages[skill.skillKey] ?? null;\n const canInstall =\n skill.install.length > 0 && skill.missing.bins.length > 0;\n const missing = [\n ...skill.missing.bins.map((b) => `bin:${b}`),\n ...skill.missing.env.map((e) => `env:${e}`),\n ...skill.missing.config.map((c) => `config:${c}`),\n ...skill.missing.os.map((o) => `os:${o}`),\n ];\n const reasons: string[] = [];\n if (skill.disabled) reasons.push(\"disabled\");\n if (skill.blockedByAllowlist) reasons.push(\"blocked by allowlist\");\n return html`\n
    \n
    \n
    \n ${skill.emoji ? `${skill.emoji} ` : \"\"}${skill.name}\n
    \n
    ${clampText(skill.description, 140)}
    \n
    \n ${skill.source}\n \n ${skill.eligible ? \"eligible\" : \"blocked\"}\n \n ${skill.disabled ? html`disabled` : nothing}\n
    \n ${missing.length > 0\n ? html`\n
    \n Missing: ${missing.join(\", \")}\n
    \n `\n : nothing}\n ${reasons.length > 0\n ? html`\n
    \n Reason: ${reasons.join(\", \")}\n
    \n `\n : nothing}\n
    \n
    \n
    \n props.onToggle(skill.skillKey, skill.disabled)}\n >\n ${skill.disabled ? \"Enable\" : \"Disable\"}\n \n ${canInstall\n ? html`\n props.onInstall(skill.skillKey, skill.name, skill.install[0].id)}\n >\n ${busy ? \"Installing…\" : skill.install[0].label}\n `\n : nothing}\n
    \n ${message\n ? html`\n ${message.message}\n
    `\n : nothing}\n ${skill.primaryEnv\n ? html`\n
    \n API key\n \n props.onEdit(skill.skillKey, (e.target as HTMLInputElement).value)}\n />\n
    \n props.onSaveKey(skill.skillKey)}\n >\n Save key\n \n `\n : nothing}\n
    \n \n `;\n}\n","import { html } from \"lit\";\nimport { repeat } from \"lit/directives/repeat.js\";\n\nimport type { AppViewState } from \"./app-view-state\";\nimport { iconForTab, pathForTab, titleForTab, type Tab } from \"./navigation\";\nimport { icons } from \"./icons\";\nimport { loadChatHistory } from \"./controllers/chat\";\nimport { syncUrlWithSessionKey } from \"./app-settings\";\nimport type { SessionsListResult } from \"./types\";\nimport type { ThemeMode } from \"./theme\";\nimport type { ThemeTransitionContext } from \"./theme-transition\";\n\nexport function renderTab(state: AppViewState, tab: Tab) {\n const href = pathForTab(tab, state.basePath);\n return html`\n {\n if (\n event.defaultPrevented ||\n event.button !== 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n event.preventDefault();\n state.setTab(tab);\n }}\n title=${titleForTab(tab)}\n >\n ${icons[iconForTab(tab)]}\n ${titleForTab(tab)}\n \n `;\n}\n\nexport function renderChatControls(state: AppViewState) {\n const sessionOptions = resolveSessionOptions(state.sessionKey, state.sessionsResult);\n const disableThinkingToggle = state.onboarding;\n const disableFocusToggle = state.onboarding;\n const showThinking = state.onboarding ? false : state.settings.chatShowThinking;\n const focusActive = state.onboarding ? true : state.settings.chatFocusMode;\n // Refresh icon\n const refreshIcon = html``;\n const focusIcon = html``;\n return html`\n
    \n \n {\n state.resetToolStream();\n void loadChatHistory(state);\n }}\n title=\"Refresh chat history\"\n >\n ${refreshIcon}\n \n |\n {\n if (disableThinkingToggle) return;\n state.applySettings({\n ...state.settings,\n chatShowThinking: !state.settings.chatShowThinking,\n });\n }}\n aria-pressed=${showThinking}\n title=${disableThinkingToggle\n ? \"Disabled during onboarding\"\n : \"Toggle assistant thinking/working output\"}\n >\n ${icons.brain}\n \n {\n if (disableFocusToggle) return;\n state.applySettings({\n ...state.settings,\n chatFocusMode: !state.settings.chatFocusMode,\n });\n }}\n aria-pressed=${focusActive}\n title=${disableFocusToggle\n ? \"Disabled during onboarding\"\n : \"Toggle focus mode (hide sidebar + page header)\"}\n >\n ${focusIcon}\n \n
    \n `;\n}\n\nfunction resolveSessionOptions(sessionKey: string, sessions: SessionsListResult | null) {\n const seen = new Set();\n const options: Array<{ key: string; displayName?: string }> = [];\n\n const resolvedCurrent = sessions?.sessions?.find((s) => s.key === sessionKey);\n\n // Add current session key first\n seen.add(sessionKey);\n options.push({ key: sessionKey, displayName: resolvedCurrent?.displayName });\n\n // Add sessions from the result\n if (sessions?.sessions) {\n for (const s of sessions.sessions) {\n if (!seen.has(s.key)) {\n seen.add(s.key);\n options.push({ key: s.key, displayName: s.displayName });\n }\n }\n }\n\n return options;\n}\n\nconst THEME_ORDER: ThemeMode[] = [\"system\", \"light\", \"dark\"];\n\nexport function renderThemeToggle(state: AppViewState) {\n const index = Math.max(0, THEME_ORDER.indexOf(state.theme));\n const applyTheme = (next: ThemeMode) => (event: MouseEvent) => {\n const element = event.currentTarget as HTMLElement;\n const context: ThemeTransitionContext = { element };\n if (event.clientX || event.clientY) {\n context.pointerClientX = event.clientX;\n context.pointerClientY = event.clientY;\n }\n state.setTheme(next, context);\n };\n\n return html`\n
    \n
    \n \n \n ${renderMonitorIcon()}\n \n \n ${renderSunIcon()}\n \n \n ${renderMoonIcon()}\n \n
    \n
    \n `;\n}\n\nfunction renderSunIcon() {\n return html`\n \n \n \n \n \n \n \n \n \n \n \n `;\n}\n\nfunction renderMoonIcon() {\n return html`\n \n \n \n `;\n}\n\nfunction renderMonitorIcon() {\n return html`\n \n \n \n \n \n `;\n}\n","import { html, nothing } from \"lit\";\n\nimport type { GatewayBrowserClient, GatewayHelloOk } from \"./gateway\";\nimport type { AppViewState } from \"./app-view-state\";\nimport { parseAgentSessionKey } from \"../../../src/routing/session-key.js\";\nimport {\n TAB_GROUPS,\n iconForTab,\n pathForTab,\n subtitleForTab,\n titleForTab,\n type Tab,\n} from \"./navigation\";\nimport { icons } from \"./icons\";\nimport type { UiSettings } from \"./storage\";\nimport type { ThemeMode } from \"./theme\";\nimport type { ThemeTransitionContext } from \"./theme-transition\";\nimport type {\n ConfigSnapshot,\n CronJob,\n CronRunLogEntry,\n CronStatus,\n HealthSnapshot,\n LogEntry,\n LogLevel,\n PresenceEntry,\n ChannelsStatusSnapshot,\n SessionsListResult,\n SkillStatusReport,\n StatusSummary,\n} from \"./types\";\nimport type { ChatQueueItem, CronFormState } from \"./ui-types\";\nimport { refreshChatAvatar } from \"./app-chat\";\nimport { renderChat } from \"./views/chat\";\nimport { renderConfig } from \"./views/config\";\nimport { renderChannels } from \"./views/channels\";\nimport { renderCron } from \"./views/cron\";\nimport { renderDebug } from \"./views/debug\";\nimport { renderInstances } from \"./views/instances\";\nimport { renderLogs } from \"./views/logs\";\nimport { renderNodes } from \"./views/nodes\";\nimport { renderOverview } from \"./views/overview\";\nimport { renderSessions } from \"./views/sessions\";\nimport { renderExecApprovalPrompt } from \"./views/exec-approval\";\nimport {\n approveDevicePairing,\n loadDevices,\n rejectDevicePairing,\n revokeDeviceToken,\n rotateDeviceToken,\n} from \"./controllers/devices\";\nimport { renderSkills } from \"./views/skills\";\nimport { renderChatControls, renderTab, renderThemeToggle } from \"./app-render.helpers\";\nimport { loadChannels } from \"./controllers/channels\";\nimport { loadPresence } from \"./controllers/presence\";\nimport { deleteSession, loadSessions, patchSession } from \"./controllers/sessions\";\nimport {\n installSkill,\n loadSkills,\n saveSkillApiKey,\n updateSkillEdit,\n updateSkillEnabled,\n type SkillMessage,\n} from \"./controllers/skills\";\nimport { loadNodes } from \"./controllers/nodes\";\nimport { loadChatHistory } from \"./controllers/chat\";\nimport {\n applyConfig,\n loadConfig,\n runUpdate,\n saveConfig,\n updateConfigFormValue,\n removeConfigFormValue,\n} from \"./controllers/config\";\nimport {\n loadExecApprovals,\n removeExecApprovalsFormValue,\n saveExecApprovals,\n updateExecApprovalsFormValue,\n} from \"./controllers/exec-approvals\";\nimport { loadCronRuns, toggleCronJob, runCronJob, removeCronJob, addCronJob } from \"./controllers/cron\";\nimport { loadDebug, callDebugMethod } from \"./controllers/debug\";\nimport { loadLogs } from \"./controllers/logs\";\n\nconst AVATAR_DATA_RE = /^data:/i;\nconst AVATAR_HTTP_RE = /^https?:\\/\\//i;\n\nfunction resolveAssistantAvatarUrl(state: AppViewState): string | undefined {\n const list = state.agentsList?.agents ?? [];\n const parsed = parseAgentSessionKey(state.sessionKey);\n const agentId =\n parsed?.agentId ??\n state.agentsList?.defaultId ??\n \"main\";\n const agent = list.find((entry) => entry.id === agentId);\n const identity = agent?.identity;\n const candidate = identity?.avatarUrl ?? identity?.avatar;\n if (!candidate) return undefined;\n if (AVATAR_DATA_RE.test(candidate) || AVATAR_HTTP_RE.test(candidate)) return candidate;\n return identity?.avatarUrl;\n}\n\nexport function renderApp(state: AppViewState) {\n const presenceCount = state.presenceEntries.length;\n const sessionsCount = state.sessionsResult?.count ?? null;\n const cronNext = state.cronStatus?.nextWakeAtMs ?? null;\n const chatDisabledReason = state.connected ? null : \"Disconnected from gateway.\";\n const isChat = state.tab === \"chat\";\n const chatFocus = isChat && (state.settings.chatFocusMode || state.onboarding);\n const showThinking = state.onboarding ? false : state.settings.chatShowThinking;\n const assistantAvatarUrl = resolveAssistantAvatarUrl(state);\n const chatAvatarUrl = state.chatAvatarUrl ?? assistantAvatarUrl ?? null;\n\n return html`\n
    \n
    \n
    \n \n state.applySettings({\n ...state.settings,\n navCollapsed: !state.settings.navCollapsed,\n })}\n title=\"${state.settings.navCollapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\"\n aria-label=\"${state.settings.navCollapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\"\n >\n ${icons.menu}\n \n
    \n
    \n \"Clawdbot\"\n
    \n
    \n
    CLAWDBOT
    \n
    Gateway Dashboard
    \n
    \n
    \n
    \n
    \n
    \n \n Health\n ${state.connected ? \"OK\" : \"Offline\"}\n
    \n ${renderThemeToggle(state)}\n
    \n
    \n \n
    \n
    \n
    \n
    ${titleForTab(state.tab)}
    \n
    ${subtitleForTab(state.tab)}
    \n
    \n
    \n ${state.lastError\n ? html`
    ${state.lastError}
    `\n : nothing}\n ${isChat ? renderChatControls(state) : nothing}\n
    \n
    \n\n ${state.tab === \"overview\"\n ? renderOverview({\n connected: state.connected,\n hello: state.hello,\n settings: state.settings,\n password: state.password,\n lastError: state.lastError,\n presenceCount,\n sessionsCount,\n cronEnabled: state.cronStatus?.enabled ?? null,\n cronNext,\n lastChannelsRefresh: state.channelsLastSuccess,\n onSettingsChange: (next) => state.applySettings(next),\n onPasswordChange: (next) => (state.password = next),\n onSessionKeyChange: (next) => {\n state.sessionKey = next;\n state.chatMessage = \"\";\n state.resetToolStream();\n state.applySettings({\n ...state.settings,\n sessionKey: next,\n lastActiveSessionKey: next,\n });\n void state.loadAssistantIdentity();\n },\n onConnect: () => state.connect(),\n onRefresh: () => state.loadOverview(),\n })\n : nothing}\n\n ${state.tab === \"channels\"\n ? renderChannels({\n connected: state.connected,\n loading: state.channelsLoading,\n snapshot: state.channelsSnapshot,\n lastError: state.channelsError,\n lastSuccessAt: state.channelsLastSuccess,\n whatsappMessage: state.whatsappLoginMessage,\n whatsappQrDataUrl: state.whatsappLoginQrDataUrl,\n whatsappConnected: state.whatsappLoginConnected,\n whatsappBusy: state.whatsappBusy,\n configSchema: state.configSchema,\n configSchemaLoading: state.configSchemaLoading,\n configForm: state.configForm,\n configUiHints: state.configUiHints,\n configSaving: state.configSaving,\n configFormDirty: state.configFormDirty,\n nostrProfileFormState: state.nostrProfileFormState,\n nostrProfileAccountId: state.nostrProfileAccountId,\n onRefresh: (probe) => loadChannels(state, probe),\n onWhatsAppStart: (force) => state.handleWhatsAppStart(force),\n onWhatsAppWait: () => state.handleWhatsAppWait(),\n onWhatsAppLogout: () => state.handleWhatsAppLogout(),\n onConfigPatch: (path, value) => updateConfigFormValue(state, path, value),\n onConfigSave: () => state.handleChannelConfigSave(),\n onConfigReload: () => state.handleChannelConfigReload(),\n onNostrProfileEdit: (accountId, profile) =>\n state.handleNostrProfileEdit(accountId, profile),\n onNostrProfileCancel: () => state.handleNostrProfileCancel(),\n onNostrProfileFieldChange: (field, value) =>\n state.handleNostrProfileFieldChange(field, value),\n onNostrProfileSave: () => state.handleNostrProfileSave(),\n onNostrProfileImport: () => state.handleNostrProfileImport(),\n onNostrProfileToggleAdvanced: () => state.handleNostrProfileToggleAdvanced(),\n })\n : nothing}\n\n ${state.tab === \"instances\"\n ? renderInstances({\n loading: state.presenceLoading,\n entries: state.presenceEntries,\n lastError: state.presenceError,\n statusMessage: state.presenceStatus,\n onRefresh: () => loadPresence(state),\n })\n : nothing}\n\n ${state.tab === \"sessions\"\n ? renderSessions({\n loading: state.sessionsLoading,\n result: state.sessionsResult,\n error: state.sessionsError,\n activeMinutes: state.sessionsFilterActive,\n limit: state.sessionsFilterLimit,\n includeGlobal: state.sessionsIncludeGlobal,\n includeUnknown: state.sessionsIncludeUnknown,\n basePath: state.basePath,\n onFiltersChange: (next) => {\n state.sessionsFilterActive = next.activeMinutes;\n state.sessionsFilterLimit = next.limit;\n state.sessionsIncludeGlobal = next.includeGlobal;\n state.sessionsIncludeUnknown = next.includeUnknown;\n\t },\n\t onRefresh: () => loadSessions(state),\n\t onPatch: (key, patch) => patchSession(state, key, patch),\n\t onDelete: (key) => deleteSession(state, key),\n\t })\n\t : nothing}\n\n ${state.tab === \"cron\"\n ? renderCron({\n loading: state.cronLoading,\n status: state.cronStatus,\n jobs: state.cronJobs,\n error: state.cronError,\n busy: state.cronBusy,\n form: state.cronForm,\n channels: state.channelsSnapshot?.channelMeta?.length\n ? state.channelsSnapshot.channelMeta.map((entry) => entry.id)\n : state.channelsSnapshot?.channelOrder ?? [],\n channelLabels: state.channelsSnapshot?.channelLabels ?? {},\n channelMeta: state.channelsSnapshot?.channelMeta ?? [],\n runsJobId: state.cronRunsJobId,\n runs: state.cronRuns,\n onFormChange: (patch) => (state.cronForm = { ...state.cronForm, ...patch }),\n onRefresh: () => state.loadCron(),\n onAdd: () => addCronJob(state),\n onToggle: (job, enabled) => toggleCronJob(state, job, enabled),\n onRun: (job) => runCronJob(state, job),\n onRemove: (job) => removeCronJob(state, job),\n onLoadRuns: (jobId) => loadCronRuns(state, jobId),\n })\n : nothing}\n\n ${state.tab === \"skills\"\n ? renderSkills({\n loading: state.skillsLoading,\n report: state.skillsReport,\n error: state.skillsError,\n filter: state.skillsFilter,\n edits: state.skillEdits,\n messages: state.skillMessages,\n busyKey: state.skillsBusyKey,\n onFilterChange: (next) => (state.skillsFilter = next),\n onRefresh: () => loadSkills(state, { clearMessages: true }),\n onToggle: (key, enabled) => updateSkillEnabled(state, key, enabled),\n onEdit: (key, value) => updateSkillEdit(state, key, value),\n onSaveKey: (key) => saveSkillApiKey(state, key),\n onInstall: (skillKey, name, installId) =>\n installSkill(state, skillKey, name, installId),\n })\n : nothing}\n\n ${state.tab === \"nodes\"\n ? renderNodes({\n loading: state.nodesLoading,\n nodes: state.nodes,\n devicesLoading: state.devicesLoading,\n devicesError: state.devicesError,\n devicesList: state.devicesList,\n configForm: state.configForm ?? (state.configSnapshot?.config as Record | null),\n configLoading: state.configLoading,\n configSaving: state.configSaving,\n configDirty: state.configFormDirty,\n configFormMode: state.configFormMode,\n execApprovalsLoading: state.execApprovalsLoading,\n execApprovalsSaving: state.execApprovalsSaving,\n execApprovalsDirty: state.execApprovalsDirty,\n execApprovalsSnapshot: state.execApprovalsSnapshot,\n execApprovalsForm: state.execApprovalsForm,\n execApprovalsSelectedAgent: state.execApprovalsSelectedAgent,\n execApprovalsTarget: state.execApprovalsTarget,\n execApprovalsTargetNodeId: state.execApprovalsTargetNodeId,\n onRefresh: () => loadNodes(state),\n onDevicesRefresh: () => loadDevices(state),\n onDeviceApprove: (requestId) => approveDevicePairing(state, requestId),\n onDeviceReject: (requestId) => rejectDevicePairing(state, requestId),\n onDeviceRotate: (deviceId, role, scopes) =>\n rotateDeviceToken(state, { deviceId, role, scopes }),\n onDeviceRevoke: (deviceId, role) =>\n revokeDeviceToken(state, { deviceId, role }),\n onLoadConfig: () => loadConfig(state),\n onLoadExecApprovals: () => {\n const target =\n state.execApprovalsTarget === \"node\" && state.execApprovalsTargetNodeId\n ? { kind: \"node\" as const, nodeId: state.execApprovalsTargetNodeId }\n : { kind: \"gateway\" as const };\n return loadExecApprovals(state, target);\n },\n onBindDefault: (nodeId) => {\n if (nodeId) {\n updateConfigFormValue(state, [\"tools\", \"exec\", \"node\"], nodeId);\n } else {\n removeConfigFormValue(state, [\"tools\", \"exec\", \"node\"]);\n }\n },\n onBindAgent: (agentIndex, nodeId) => {\n const basePath = [\"agents\", \"list\", agentIndex, \"tools\", \"exec\", \"node\"];\n if (nodeId) {\n updateConfigFormValue(state, basePath, nodeId);\n } else {\n removeConfigFormValue(state, basePath);\n }\n },\n onSaveBindings: () => saveConfig(state),\n onExecApprovalsTargetChange: (kind, nodeId) => {\n state.execApprovalsTarget = kind;\n state.execApprovalsTargetNodeId = nodeId;\n state.execApprovalsSnapshot = null;\n state.execApprovalsForm = null;\n state.execApprovalsDirty = false;\n state.execApprovalsSelectedAgent = null;\n },\n onExecApprovalsSelectAgent: (agentId) => {\n state.execApprovalsSelectedAgent = agentId;\n },\n onExecApprovalsPatch: (path, value) =>\n updateExecApprovalsFormValue(state, path, value),\n onExecApprovalsRemove: (path) =>\n removeExecApprovalsFormValue(state, path),\n onSaveExecApprovals: () => {\n const target =\n state.execApprovalsTarget === \"node\" && state.execApprovalsTargetNodeId\n ? { kind: \"node\" as const, nodeId: state.execApprovalsTargetNodeId }\n : { kind: \"gateway\" as const };\n return saveExecApprovals(state, target);\n },\n })\n : nothing}\n\n ${state.tab === \"chat\"\n ? renderChat({\n sessionKey: state.sessionKey,\n onSessionKeyChange: (next) => {\n state.sessionKey = next;\n state.chatMessage = \"\";\n state.chatStream = null;\n state.chatStreamStartedAt = null;\n state.chatRunId = null;\n state.chatQueue = [];\n state.resetToolStream();\n state.resetChatScroll();\n state.applySettings({\n ...state.settings,\n sessionKey: next,\n lastActiveSessionKey: next,\n });\n void state.loadAssistantIdentity();\n void loadChatHistory(state);\n void refreshChatAvatar(state);\n },\n thinkingLevel: state.chatThinkingLevel,\n showThinking,\n loading: state.chatLoading,\n sending: state.chatSending,\n compactionStatus: state.compactionStatus,\n assistantAvatarUrl: chatAvatarUrl,\n messages: state.chatMessages,\n toolMessages: state.chatToolMessages,\n stream: state.chatStream,\n streamStartedAt: state.chatStreamStartedAt,\n draft: state.chatMessage,\n queue: state.chatQueue,\n connected: state.connected,\n canSend: state.connected,\n disabledReason: chatDisabledReason,\n error: state.lastError,\n sessions: state.sessionsResult,\n focusMode: chatFocus,\n onRefresh: () => {\n state.resetToolStream();\n return Promise.all([loadChatHistory(state), refreshChatAvatar(state)]);\n },\n onToggleFocusMode: () => {\n if (state.onboarding) return;\n state.applySettings({\n ...state.settings,\n chatFocusMode: !state.settings.chatFocusMode,\n });\n },\n onChatScroll: (event) => state.handleChatScroll(event),\n onDraftChange: (next) => (state.chatMessage = next),\n onSend: () => state.handleSendChat(),\n canAbort: Boolean(state.chatRunId),\n onAbort: () => void state.handleAbortChat(),\n onQueueRemove: (id) => state.removeQueuedMessage(id),\n onNewSession: () =>\n state.handleSendChat(\"/new\", { restoreDraft: true }),\n // Sidebar props for tool output viewing\n sidebarOpen: state.sidebarOpen,\n sidebarContent: state.sidebarContent,\n sidebarError: state.sidebarError,\n splitRatio: state.splitRatio,\n onOpenSidebar: (content: string) => state.handleOpenSidebar(content),\n onCloseSidebar: () => state.handleCloseSidebar(),\n onSplitRatioChange: (ratio: number) => state.handleSplitRatioChange(ratio),\n assistantName: state.assistantName,\n assistantAvatar: state.assistantAvatar,\n })\n : nothing}\n\n ${state.tab === \"config\"\n ? renderConfig({\n raw: state.configRaw,\n originalRaw: state.configRawOriginal,\n valid: state.configValid,\n issues: state.configIssues,\n loading: state.configLoading,\n saving: state.configSaving,\n applying: state.configApplying,\n updating: state.updateRunning,\n connected: state.connected,\n schema: state.configSchema,\n schemaLoading: state.configSchemaLoading,\n uiHints: state.configUiHints,\n formMode: state.configFormMode,\n formValue: state.configForm,\n originalValue: state.configFormOriginal,\n searchQuery: state.configSearchQuery,\n activeSection: state.configActiveSection,\n activeSubsection: state.configActiveSubsection,\n onRawChange: (next) => {\n state.configRaw = next;\n },\n onFormModeChange: (mode) => (state.configFormMode = mode),\n onFormPatch: (path, value) => updateConfigFormValue(state, path, value),\n onSearchChange: (query) => (state.configSearchQuery = query),\n onSectionChange: (section) => {\n state.configActiveSection = section;\n state.configActiveSubsection = null;\n },\n onSubsectionChange: (section) => (state.configActiveSubsection = section),\n onReload: () => loadConfig(state),\n onSave: () => saveConfig(state),\n onApply: () => applyConfig(state),\n onUpdate: () => runUpdate(state),\n })\n : nothing}\n\n ${state.tab === \"debug\"\n ? renderDebug({\n loading: state.debugLoading,\n status: state.debugStatus,\n health: state.debugHealth,\n models: state.debugModels,\n heartbeat: state.debugHeartbeat,\n eventLog: state.eventLog,\n callMethod: state.debugCallMethod,\n callParams: state.debugCallParams,\n callResult: state.debugCallResult,\n callError: state.debugCallError,\n onCallMethodChange: (next) => (state.debugCallMethod = next),\n onCallParamsChange: (next) => (state.debugCallParams = next),\n onRefresh: () => loadDebug(state),\n onCall: () => callDebugMethod(state),\n })\n : nothing}\n\n ${state.tab === \"logs\"\n ? renderLogs({\n loading: state.logsLoading,\n error: state.logsError,\n file: state.logsFile,\n entries: state.logsEntries,\n filterText: state.logsFilterText,\n levelFilters: state.logsLevelFilters,\n autoFollow: state.logsAutoFollow,\n truncated: state.logsTruncated,\n onFilterTextChange: (next) => (state.logsFilterText = next),\n onLevelToggle: (level, enabled) => {\n state.logsLevelFilters = { ...state.logsLevelFilters, [level]: enabled };\n },\n onToggleAutoFollow: (next) => (state.logsAutoFollow = next),\n onRefresh: () => loadLogs(state, { reset: true }),\n onExport: (lines, label) => state.exportLogs(lines, label),\n onScroll: (event) => state.handleLogsScroll(event),\n })\n : nothing}\n
    \n ${renderExecApprovalPrompt(state)}\n
    \n `;\n}\n","import type { LogLevel } from \"./types\";\nimport type { CronFormState } from \"./ui-types\";\n\nexport const DEFAULT_LOG_LEVEL_FILTERS: Record = {\n trace: true,\n debug: true,\n info: true,\n warn: true,\n error: true,\n fatal: true,\n};\n\nexport const DEFAULT_CRON_FORM: CronFormState = {\n name: \"\",\n description: \"\",\n agentId: \"\",\n enabled: true,\n scheduleKind: \"every\",\n scheduleAt: \"\",\n everyAmount: \"30\",\n everyUnit: \"minutes\",\n cronExpr: \"0 7 * * *\",\n cronTz: \"\",\n sessionTarget: \"main\",\n wakeMode: \"next-heartbeat\",\n payloadKind: \"systemEvent\",\n payloadText: \"\",\n deliver: false,\n channel: \"last\",\n to: \"\",\n timeoutSeconds: \"\",\n postToMainPrefix: \"\",\n};\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport type { AgentsListResult } from \"../types\";\n\nexport type AgentsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n agentsLoading: boolean;\n agentsError: string | null;\n agentsList: AgentsListResult | null;\n};\n\nexport async function loadAgents(state: AgentsState) {\n if (!state.client || !state.connected) return;\n if (state.agentsLoading) return;\n state.agentsLoading = true;\n state.agentsError = null;\n try {\n const res = (await state.client.request(\"agents.list\", {})) as AgentsListResult | undefined;\n if (res) state.agentsList = res;\n } catch (err) {\n state.agentsError = String(err);\n } finally {\n state.agentsLoading = false;\n }\n}\n","export const GATEWAY_CLIENT_IDS = {\n WEBCHAT_UI: \"webchat-ui\",\n CONTROL_UI: \"clawdbot-control-ui\",\n WEBCHAT: \"webchat\",\n CLI: \"cli\",\n GATEWAY_CLIENT: \"gateway-client\",\n MACOS_APP: \"clawdbot-macos\",\n IOS_APP: \"clawdbot-ios\",\n ANDROID_APP: \"clawdbot-android\",\n NODE_HOST: \"node-host\",\n TEST: \"test\",\n FINGERPRINT: \"fingerprint\",\n PROBE: \"clawdbot-probe\",\n} as const;\n\nexport type GatewayClientId = (typeof GATEWAY_CLIENT_IDS)[keyof typeof GATEWAY_CLIENT_IDS];\n\n// Back-compat naming (internal): these values are IDs, not display names.\nexport const GATEWAY_CLIENT_NAMES = GATEWAY_CLIENT_IDS;\nexport type GatewayClientName = GatewayClientId;\n\nexport const GATEWAY_CLIENT_MODES = {\n WEBCHAT: \"webchat\",\n CLI: \"cli\",\n UI: \"ui\",\n BACKEND: \"backend\",\n NODE: \"node\",\n PROBE: \"probe\",\n TEST: \"test\",\n} as const;\n\nexport type GatewayClientMode = (typeof GATEWAY_CLIENT_MODES)[keyof typeof GATEWAY_CLIENT_MODES];\n\nexport type GatewayClientInfo = {\n id: GatewayClientId;\n displayName?: string;\n version: string;\n platform: string;\n deviceFamily?: string;\n modelIdentifier?: string;\n mode: GatewayClientMode;\n instanceId?: string;\n};\n\nconst GATEWAY_CLIENT_ID_SET = new Set(Object.values(GATEWAY_CLIENT_IDS));\nconst GATEWAY_CLIENT_MODE_SET = new Set(Object.values(GATEWAY_CLIENT_MODES));\n\nexport function normalizeGatewayClientId(raw?: string | null): GatewayClientId | undefined {\n const normalized = raw?.trim().toLowerCase();\n if (!normalized) return undefined;\n return GATEWAY_CLIENT_ID_SET.has(normalized as GatewayClientId)\n ? (normalized as GatewayClientId)\n : undefined;\n}\n\nexport function normalizeGatewayClientName(raw?: string | null): GatewayClientName | undefined {\n return normalizeGatewayClientId(raw);\n}\n\nexport function normalizeGatewayClientMode(raw?: string | null): GatewayClientMode | undefined {\n const normalized = raw?.trim().toLowerCase();\n if (!normalized) return undefined;\n return GATEWAY_CLIENT_MODE_SET.has(normalized as GatewayClientMode)\n ? (normalized as GatewayClientMode)\n : undefined;\n}\n","export type DeviceAuthPayloadParams = {\n deviceId: string;\n clientId: string;\n clientMode: string;\n role: string;\n scopes: string[];\n signedAtMs: number;\n token?: string | null;\n nonce?: string | null;\n version?: \"v1\" | \"v2\";\n};\n\nexport function buildDeviceAuthPayload(params: DeviceAuthPayloadParams): string {\n const version = params.version ?? (params.nonce ? \"v2\" : \"v1\");\n const scopes = params.scopes.join(\",\");\n const token = params.token ?? \"\";\n const base = [\n version,\n params.deviceId,\n params.clientId,\n params.clientMode,\n params.role,\n scopes,\n String(params.signedAtMs),\n token,\n ];\n if (version === \"v2\") {\n base.push(params.nonce ?? \"\");\n }\n return base.join(\"|\");\n}\n","import { generateUUID } from \"./uuid\";\nimport {\n GATEWAY_CLIENT_MODES,\n GATEWAY_CLIENT_NAMES,\n type GatewayClientMode,\n type GatewayClientName,\n} from \"../../../src/gateway/protocol/client-info.js\";\nimport { buildDeviceAuthPayload } from \"../../../src/gateway/device-auth.js\";\nimport { loadOrCreateDeviceIdentity, signDevicePayload } from \"./device-identity\";\nimport { clearDeviceAuthToken, loadDeviceAuthToken, storeDeviceAuthToken } from \"./device-auth\";\n\nexport type GatewayEventFrame = {\n type: \"event\";\n event: string;\n payload?: unknown;\n seq?: number;\n stateVersion?: { presence: number; health: number };\n};\n\nexport type GatewayResponseFrame = {\n type: \"res\";\n id: string;\n ok: boolean;\n payload?: unknown;\n error?: { code: string; message: string; details?: unknown };\n};\n\nexport type GatewayHelloOk = {\n type: \"hello-ok\";\n protocol: number;\n features?: { methods?: string[]; events?: string[] };\n snapshot?: unknown;\n auth?: {\n deviceToken?: string;\n role?: string;\n scopes?: string[];\n issuedAtMs?: number;\n };\n policy?: { tickIntervalMs?: number };\n};\n\ntype Pending = {\n resolve: (value: unknown) => void;\n reject: (err: unknown) => void;\n};\n\nexport type GatewayBrowserClientOptions = {\n url: string;\n token?: string;\n password?: string;\n clientName?: GatewayClientName;\n clientVersion?: string;\n platform?: string;\n mode?: GatewayClientMode;\n instanceId?: string;\n onHello?: (hello: GatewayHelloOk) => void;\n onEvent?: (evt: GatewayEventFrame) => void;\n onClose?: (info: { code: number; reason: string }) => void;\n onGap?: (info: { expected: number; received: number }) => void;\n};\n\n// 4008 = application-defined code (browser rejects 1008 \"Policy Violation\")\nconst CONNECT_FAILED_CLOSE_CODE = 4008;\n\nexport class GatewayBrowserClient {\n private ws: WebSocket | null = null;\n private pending = new Map();\n private closed = false;\n private lastSeq: number | null = null;\n private connectNonce: string | null = null;\n private connectSent = false;\n private connectTimer: number | null = null;\n private backoffMs = 800;\n\n constructor(private opts: GatewayBrowserClientOptions) {}\n\n start() {\n this.closed = false;\n this.connect();\n }\n\n stop() {\n this.closed = true;\n this.ws?.close();\n this.ws = null;\n this.flushPending(new Error(\"gateway client stopped\"));\n }\n\n get connected() {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n private connect() {\n if (this.closed) return;\n this.ws = new WebSocket(this.opts.url);\n this.ws.onopen = () => this.queueConnect();\n this.ws.onmessage = (ev) => this.handleMessage(String(ev.data ?? \"\"));\n this.ws.onclose = (ev) => {\n const reason = String(ev.reason ?? \"\");\n this.ws = null;\n this.flushPending(new Error(`gateway closed (${ev.code}): ${reason}`));\n this.opts.onClose?.({ code: ev.code, reason });\n this.scheduleReconnect();\n };\n this.ws.onerror = () => {\n // ignored; close handler will fire\n };\n }\n\n private scheduleReconnect() {\n if (this.closed) return;\n const delay = this.backoffMs;\n this.backoffMs = Math.min(this.backoffMs * 1.7, 15_000);\n window.setTimeout(() => this.connect(), delay);\n }\n\n private flushPending(err: Error) {\n for (const [, p] of this.pending) p.reject(err);\n this.pending.clear();\n }\n\n private async sendConnect() {\n if (this.connectSent) return;\n this.connectSent = true;\n if (this.connectTimer !== null) {\n window.clearTimeout(this.connectTimer);\n this.connectTimer = null;\n }\n\n // crypto.subtle is only available in secure contexts (HTTPS, localhost).\n // Over plain HTTP, we skip device identity and fall back to token-only auth.\n // Gateways may reject this unless gateway.controlUi.allowInsecureAuth is enabled.\n const isSecureContext = typeof crypto !== \"undefined\" && !!crypto.subtle;\n\n const scopes = [\"operator.admin\", \"operator.approvals\", \"operator.pairing\"];\n const role = \"operator\";\n let deviceIdentity: Awaited> | null = null;\n let canFallbackToShared = false;\n let authToken = this.opts.token;\n\n if (isSecureContext) {\n deviceIdentity = await loadOrCreateDeviceIdentity();\n const storedToken = loadDeviceAuthToken({\n deviceId: deviceIdentity.deviceId,\n role,\n })?.token;\n authToken = storedToken ?? this.opts.token;\n canFallbackToShared = Boolean(storedToken && this.opts.token);\n }\n const auth =\n authToken || this.opts.password\n ? {\n token: authToken,\n password: this.opts.password,\n }\n : undefined;\n\n let device:\n | {\n id: string;\n publicKey: string;\n signature: string;\n signedAt: number;\n nonce: string | undefined;\n }\n | undefined;\n\n if (isSecureContext && deviceIdentity) {\n const signedAtMs = Date.now();\n const nonce = this.connectNonce ?? undefined;\n const payload = buildDeviceAuthPayload({\n deviceId: deviceIdentity.deviceId,\n clientId: this.opts.clientName ?? GATEWAY_CLIENT_NAMES.CONTROL_UI,\n clientMode: this.opts.mode ?? GATEWAY_CLIENT_MODES.WEBCHAT,\n role,\n scopes,\n signedAtMs,\n token: authToken ?? null,\n nonce,\n });\n const signature = await signDevicePayload(deviceIdentity.privateKey, payload);\n device = {\n id: deviceIdentity.deviceId,\n publicKey: deviceIdentity.publicKey,\n signature,\n signedAt: signedAtMs,\n nonce,\n };\n }\n const params = {\n minProtocol: 3,\n maxProtocol: 3,\n client: {\n id: this.opts.clientName ?? GATEWAY_CLIENT_NAMES.CONTROL_UI,\n version: this.opts.clientVersion ?? \"dev\",\n platform: this.opts.platform ?? navigator.platform ?? \"web\",\n mode: this.opts.mode ?? GATEWAY_CLIENT_MODES.WEBCHAT,\n instanceId: this.opts.instanceId,\n },\n role,\n scopes,\n device,\n caps: [],\n auth,\n userAgent: navigator.userAgent,\n locale: navigator.language,\n };\n\n void this.request(\"connect\", params)\n .then((hello) => {\n if (hello?.auth?.deviceToken && deviceIdentity) {\n storeDeviceAuthToken({\n deviceId: deviceIdentity.deviceId,\n role: hello.auth.role ?? role,\n token: hello.auth.deviceToken,\n scopes: hello.auth.scopes ?? [],\n });\n }\n this.backoffMs = 800;\n this.opts.onHello?.(hello);\n })\n .catch(() => {\n if (canFallbackToShared && deviceIdentity) {\n clearDeviceAuthToken({ deviceId: deviceIdentity.deviceId, role });\n }\n this.ws?.close(CONNECT_FAILED_CLOSE_CODE, \"connect failed\");\n });\n }\n\n private handleMessage(raw: string) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return;\n }\n\n const frame = parsed as { type?: unknown };\n if (frame.type === \"event\") {\n const evt = parsed as GatewayEventFrame;\n if (evt.event === \"connect.challenge\") {\n const payload = evt.payload as { nonce?: unknown } | undefined;\n const nonce = payload && typeof payload.nonce === \"string\" ? payload.nonce : null;\n if (nonce) {\n this.connectNonce = nonce;\n void this.sendConnect();\n }\n return;\n }\n const seq = typeof evt.seq === \"number\" ? evt.seq : null;\n if (seq !== null) {\n if (this.lastSeq !== null && seq > this.lastSeq + 1) {\n this.opts.onGap?.({ expected: this.lastSeq + 1, received: seq });\n }\n this.lastSeq = seq;\n }\n try {\n this.opts.onEvent?.(evt);\n } catch (err) {\n console.error(\"[gateway] event handler error:\", err);\n }\n return;\n }\n\n if (frame.type === \"res\") {\n const res = parsed as GatewayResponseFrame;\n const pending = this.pending.get(res.id);\n if (!pending) return;\n this.pending.delete(res.id);\n if (res.ok) pending.resolve(res.payload);\n else pending.reject(new Error(res.error?.message ?? \"request failed\"));\n return;\n }\n }\n\n request(method: string, params?: unknown): Promise {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error(\"gateway not connected\"));\n }\n const id = generateUUID();\n const frame = { type: \"req\", id, method, params };\n const p = new Promise((resolve, reject) => {\n this.pending.set(id, { resolve: (v) => resolve(v as T), reject });\n });\n this.ws.send(JSON.stringify(frame));\n return p;\n }\n\n private queueConnect() {\n this.connectNonce = null;\n this.connectSent = false;\n if (this.connectTimer !== null) window.clearTimeout(this.connectTimer);\n this.connectTimer = window.setTimeout(() => {\n void this.sendConnect();\n }, 750);\n }\n}\n","export type ExecApprovalRequestPayload = {\n command: string;\n cwd?: string | null;\n host?: string | null;\n security?: string | null;\n ask?: string | null;\n agentId?: string | null;\n resolvedPath?: string | null;\n sessionKey?: string | null;\n};\n\nexport type ExecApprovalRequest = {\n id: string;\n request: ExecApprovalRequestPayload;\n createdAtMs: number;\n expiresAtMs: number;\n};\n\nexport type ExecApprovalResolved = {\n id: string;\n decision?: string | null;\n resolvedBy?: string | null;\n ts?: number | null;\n};\n\nfunction isRecord(value: unknown): value is Record {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function parseExecApprovalRequested(payload: unknown): ExecApprovalRequest | null {\n if (!isRecord(payload)) return null;\n const id = typeof payload.id === \"string\" ? payload.id.trim() : \"\";\n const request = payload.request;\n if (!id || !isRecord(request)) return null;\n const command = typeof request.command === \"string\" ? request.command.trim() : \"\";\n if (!command) return null;\n const createdAtMs = typeof payload.createdAtMs === \"number\" ? payload.createdAtMs : 0;\n const expiresAtMs = typeof payload.expiresAtMs === \"number\" ? payload.expiresAtMs : 0;\n if (!createdAtMs || !expiresAtMs) return null;\n return {\n id,\n request: {\n command,\n cwd: typeof request.cwd === \"string\" ? request.cwd : null,\n host: typeof request.host === \"string\" ? request.host : null,\n security: typeof request.security === \"string\" ? request.security : null,\n ask: typeof request.ask === \"string\" ? request.ask : null,\n agentId: typeof request.agentId === \"string\" ? request.agentId : null,\n resolvedPath: typeof request.resolvedPath === \"string\" ? request.resolvedPath : null,\n sessionKey: typeof request.sessionKey === \"string\" ? request.sessionKey : null,\n },\n createdAtMs,\n expiresAtMs,\n };\n}\n\nexport function parseExecApprovalResolved(payload: unknown): ExecApprovalResolved | null {\n if (!isRecord(payload)) return null;\n const id = typeof payload.id === \"string\" ? payload.id.trim() : \"\";\n if (!id) return null;\n return {\n id,\n decision: typeof payload.decision === \"string\" ? payload.decision : null,\n resolvedBy: typeof payload.resolvedBy === \"string\" ? payload.resolvedBy : null,\n ts: typeof payload.ts === \"number\" ? payload.ts : null,\n };\n}\n\nexport function pruneExecApprovalQueue(queue: ExecApprovalRequest[]): ExecApprovalRequest[] {\n const now = Date.now();\n return queue.filter((entry) => entry.expiresAtMs > now);\n}\n\nexport function addExecApproval(\n queue: ExecApprovalRequest[],\n entry: ExecApprovalRequest,\n): ExecApprovalRequest[] {\n const next = pruneExecApprovalQueue(queue).filter((item) => item.id !== entry.id);\n next.push(entry);\n return next;\n}\n\nexport function removeExecApproval(queue: ExecApprovalRequest[], id: string): ExecApprovalRequest[] {\n return pruneExecApprovalQueue(queue).filter((entry) => entry.id !== id);\n}\n","import type { GatewayBrowserClient } from \"../gateway\";\nimport {\n normalizeAssistantIdentity,\n type AssistantIdentity,\n} from \"../assistant-identity\";\n\nexport type AssistantIdentityState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n sessionKey: string;\n assistantName: string;\n assistantAvatar: string | null;\n assistantAgentId: string | null;\n};\n\nexport async function loadAssistantIdentity(\n state: AssistantIdentityState,\n opts?: { sessionKey?: string },\n) {\n if (!state.client || !state.connected) return;\n const sessionKey = opts?.sessionKey?.trim() || state.sessionKey.trim();\n const params = sessionKey ? { sessionKey } : {};\n try {\n const res = (await state.client.request(\"agent.identity.get\", params)) as\n | Partial\n | undefined;\n if (!res) return;\n const normalized = normalizeAssistantIdentity(res);\n state.assistantName = normalized.name;\n state.assistantAvatar = normalized.avatar;\n state.assistantAgentId = normalized.agentId ?? null;\n } catch {\n // Ignore errors; keep last known identity.\n }\n}\n","import { loadChatHistory } from \"./controllers/chat\";\nimport { loadDevices } from \"./controllers/devices\";\nimport { loadNodes } from \"./controllers/nodes\";\nimport { loadAgents } from \"./controllers/agents\";\nimport type { GatewayEventFrame, GatewayHelloOk } from \"./gateway\";\nimport { GatewayBrowserClient } from \"./gateway\";\nimport type { EventLogEntry } from \"./app-events\";\nimport type { AgentsListResult, PresenceEntry, HealthSnapshot, StatusSummary } from \"./types\";\nimport type { Tab } from \"./navigation\";\nimport type { UiSettings } from \"./storage\";\nimport { handleAgentEvent, resetToolStream, type AgentEventPayload } from \"./app-tool-stream\";\nimport { flushChatQueueForEvent } from \"./app-chat\";\nimport {\n applySettings,\n loadCron,\n refreshActiveTab,\n setLastActiveSessionKey,\n} from \"./app-settings\";\nimport { handleChatEvent, type ChatEventPayload } from \"./controllers/chat\";\nimport {\n addExecApproval,\n parseExecApprovalRequested,\n parseExecApprovalResolved,\n removeExecApproval,\n} from \"./controllers/exec-approval\";\nimport type { ClawdbotApp } from \"./app\";\nimport type { ExecApprovalRequest } from \"./controllers/exec-approval\";\nimport { loadAssistantIdentity } from \"./controllers/assistant-identity\";\n\ntype GatewayHost = {\n settings: UiSettings;\n password: string;\n client: GatewayBrowserClient | null;\n connected: boolean;\n hello: GatewayHelloOk | null;\n lastError: string | null;\n onboarding?: boolean;\n eventLogBuffer: EventLogEntry[];\n eventLog: EventLogEntry[];\n tab: Tab;\n presenceEntries: PresenceEntry[];\n presenceError: string | null;\n presenceStatus: StatusSummary | null;\n agentsLoading: boolean;\n agentsList: AgentsListResult | null;\n agentsError: string | null;\n debugHealth: HealthSnapshot | null;\n assistantName: string;\n assistantAvatar: string | null;\n assistantAgentId: string | null;\n sessionKey: string;\n chatRunId: string | null;\n execApprovalQueue: ExecApprovalRequest[];\n execApprovalError: string | null;\n};\n\ntype SessionDefaultsSnapshot = {\n defaultAgentId?: string;\n mainKey?: string;\n mainSessionKey?: string;\n scope?: string;\n};\n\nfunction normalizeSessionKeyForDefaults(\n value: string | undefined,\n defaults: SessionDefaultsSnapshot,\n): string {\n const raw = (value ?? \"\").trim();\n const mainSessionKey = defaults.mainSessionKey?.trim();\n if (!mainSessionKey) return raw;\n if (!raw) return mainSessionKey;\n const mainKey = defaults.mainKey?.trim() || \"main\";\n const defaultAgentId = defaults.defaultAgentId?.trim();\n const isAlias =\n raw === \"main\" ||\n raw === mainKey ||\n (defaultAgentId &&\n (raw === `agent:${defaultAgentId}:main` ||\n raw === `agent:${defaultAgentId}:${mainKey}`));\n return isAlias ? mainSessionKey : raw;\n}\n\nfunction applySessionDefaults(host: GatewayHost, defaults?: SessionDefaultsSnapshot) {\n if (!defaults?.mainSessionKey) return;\n const resolvedSessionKey = normalizeSessionKeyForDefaults(host.sessionKey, defaults);\n const resolvedSettingsSessionKey = normalizeSessionKeyForDefaults(\n host.settings.sessionKey,\n defaults,\n );\n const resolvedLastActiveSessionKey = normalizeSessionKeyForDefaults(\n host.settings.lastActiveSessionKey,\n defaults,\n );\n const nextSessionKey = resolvedSessionKey || resolvedSettingsSessionKey || host.sessionKey;\n const nextSettings = {\n ...host.settings,\n sessionKey: resolvedSettingsSessionKey || nextSessionKey,\n lastActiveSessionKey: resolvedLastActiveSessionKey || nextSessionKey,\n };\n const shouldUpdateSettings =\n nextSettings.sessionKey !== host.settings.sessionKey ||\n nextSettings.lastActiveSessionKey !== host.settings.lastActiveSessionKey;\n if (nextSessionKey !== host.sessionKey) {\n host.sessionKey = nextSessionKey;\n }\n if (shouldUpdateSettings) {\n applySettings(host as unknown as Parameters[0], nextSettings);\n }\n}\n\nexport function connectGateway(host: GatewayHost) {\n host.lastError = null;\n host.hello = null;\n host.connected = false;\n host.execApprovalQueue = [];\n host.execApprovalError = null;\n\n host.client?.stop();\n host.client = new GatewayBrowserClient({\n url: host.settings.gatewayUrl,\n token: host.settings.token.trim() ? host.settings.token : undefined,\n password: host.password.trim() ? host.password : undefined,\n clientName: \"clawdbot-control-ui\",\n mode: \"webchat\",\n onHello: (hello) => {\n host.connected = true;\n host.lastError = null;\n host.hello = hello;\n applySnapshot(host, hello);\n void loadAssistantIdentity(host as unknown as ClawdbotApp);\n void loadAgents(host as unknown as ClawdbotApp);\n void loadNodes(host as unknown as ClawdbotApp, { quiet: true });\n void loadDevices(host as unknown as ClawdbotApp, { quiet: true });\n void refreshActiveTab(host as unknown as Parameters[0]);\n },\n onClose: ({ code, reason }) => {\n host.connected = false;\n // Code 1012 = Service Restart (expected during config saves, don't show as error)\n if (code !== 1012) {\n host.lastError = `disconnected (${code}): ${reason || \"no reason\"}`;\n }\n },\n onEvent: (evt) => handleGatewayEvent(host, evt),\n onGap: ({ expected, received }) => {\n host.lastError = `event gap detected (expected seq ${expected}, got ${received}); refresh recommended`;\n },\n });\n host.client.start();\n}\n\nexport function handleGatewayEvent(host: GatewayHost, evt: GatewayEventFrame) {\n try {\n handleGatewayEventUnsafe(host, evt);\n } catch (err) {\n console.error(\"[gateway] handleGatewayEvent error:\", evt.event, err);\n }\n}\n\nfunction handleGatewayEventUnsafe(host: GatewayHost, evt: GatewayEventFrame) {\n host.eventLogBuffer = [\n { ts: Date.now(), event: evt.event, payload: evt.payload },\n ...host.eventLogBuffer,\n ].slice(0, 250);\n if (host.tab === \"debug\") {\n host.eventLog = host.eventLogBuffer;\n }\n\n if (evt.event === \"agent\") {\n if (host.onboarding) return;\n handleAgentEvent(\n host as unknown as Parameters[0],\n evt.payload as AgentEventPayload | undefined,\n );\n return;\n }\n\n if (evt.event === \"chat\") {\n const payload = evt.payload as ChatEventPayload | undefined;\n if (payload?.sessionKey) {\n setLastActiveSessionKey(\n host as unknown as Parameters[0],\n payload.sessionKey,\n );\n }\n const state = handleChatEvent(host as unknown as ClawdbotApp, payload);\n if (state === \"final\" || state === \"error\" || state === \"aborted\") {\n resetToolStream(host as unknown as Parameters[0]);\n void flushChatQueueForEvent(\n host as unknown as Parameters[0],\n );\n }\n if (state === \"final\") void loadChatHistory(host as unknown as ClawdbotApp);\n return;\n }\n\n if (evt.event === \"presence\") {\n const payload = evt.payload as { presence?: PresenceEntry[] } | undefined;\n if (payload?.presence && Array.isArray(payload.presence)) {\n host.presenceEntries = payload.presence;\n host.presenceError = null;\n host.presenceStatus = null;\n }\n return;\n }\n\n if (evt.event === \"cron\" && host.tab === \"cron\") {\n void loadCron(host as unknown as Parameters[0]);\n }\n\n if (evt.event === \"device.pair.requested\" || evt.event === \"device.pair.resolved\") {\n void loadDevices(host as unknown as ClawdbotApp, { quiet: true });\n }\n\n if (evt.event === \"exec.approval.requested\") {\n const entry = parseExecApprovalRequested(evt.payload);\n if (entry) {\n host.execApprovalQueue = addExecApproval(host.execApprovalQueue, entry);\n host.execApprovalError = null;\n const delay = Math.max(0, entry.expiresAtMs - Date.now() + 500);\n window.setTimeout(() => {\n host.execApprovalQueue = removeExecApproval(host.execApprovalQueue, entry.id);\n }, delay);\n }\n return;\n }\n\n if (evt.event === \"exec.approval.resolved\") {\n const resolved = parseExecApprovalResolved(evt.payload);\n if (resolved) {\n host.execApprovalQueue = removeExecApproval(host.execApprovalQueue, resolved.id);\n }\n }\n}\n\nexport function applySnapshot(host: GatewayHost, hello: GatewayHelloOk) {\n const snapshot = hello.snapshot as\n | {\n presence?: PresenceEntry[];\n health?: HealthSnapshot;\n sessionDefaults?: SessionDefaultsSnapshot;\n }\n | undefined;\n if (snapshot?.presence && Array.isArray(snapshot.presence)) {\n host.presenceEntries = snapshot.presence;\n }\n if (snapshot?.health) {\n host.debugHealth = snapshot.health;\n }\n if (snapshot?.sessionDefaults) {\n applySessionDefaults(host, snapshot.sessionDefaults);\n }\n}\n","import type { Tab } from \"./navigation\";\nimport { connectGateway } from \"./app-gateway\";\nimport {\n applySettingsFromUrl,\n attachThemeListener,\n detachThemeListener,\n inferBasePath,\n syncTabWithLocation,\n syncThemeWithSettings,\n} from \"./app-settings\";\nimport { observeTopbar, scheduleChatScroll, scheduleLogsScroll } from \"./app-scroll\";\nimport {\n startLogsPolling,\n startNodesPolling,\n stopLogsPolling,\n stopNodesPolling,\n startDebugPolling,\n stopDebugPolling,\n} from \"./app-polling\";\n\ntype LifecycleHost = {\n basePath: string;\n tab: Tab;\n chatHasAutoScrolled: boolean;\n chatLoading: boolean;\n chatMessages: unknown[];\n chatToolMessages: unknown[];\n chatStream: string;\n logsAutoFollow: boolean;\n logsAtBottom: boolean;\n logsEntries: unknown[];\n popStateHandler: () => void;\n topbarObserver: ResizeObserver | null;\n};\n\nexport function handleConnected(host: LifecycleHost) {\n host.basePath = inferBasePath();\n syncTabWithLocation(\n host as unknown as Parameters[0],\n true,\n );\n syncThemeWithSettings(\n host as unknown as Parameters[0],\n );\n attachThemeListener(\n host as unknown as Parameters[0],\n );\n window.addEventListener(\"popstate\", host.popStateHandler);\n applySettingsFromUrl(\n host as unknown as Parameters[0],\n );\n connectGateway(host as unknown as Parameters[0]);\n startNodesPolling(host as unknown as Parameters[0]);\n if (host.tab === \"logs\") {\n startLogsPolling(host as unknown as Parameters[0]);\n }\n if (host.tab === \"debug\") {\n startDebugPolling(host as unknown as Parameters[0]);\n }\n}\n\nexport function handleFirstUpdated(host: LifecycleHost) {\n observeTopbar(host as unknown as Parameters[0]);\n}\n\nexport function handleDisconnected(host: LifecycleHost) {\n window.removeEventListener(\"popstate\", host.popStateHandler);\n stopNodesPolling(host as unknown as Parameters[0]);\n stopLogsPolling(host as unknown as Parameters[0]);\n stopDebugPolling(host as unknown as Parameters[0]);\n detachThemeListener(\n host as unknown as Parameters[0],\n );\n host.topbarObserver?.disconnect();\n host.topbarObserver = null;\n}\n\nexport function handleUpdated(\n host: LifecycleHost,\n changed: Map,\n) {\n if (\n host.tab === \"chat\" &&\n (changed.has(\"chatMessages\") ||\n changed.has(\"chatToolMessages\") ||\n changed.has(\"chatStream\") ||\n changed.has(\"chatLoading\") ||\n changed.has(\"tab\"))\n ) {\n const forcedByTab = changed.has(\"tab\");\n const forcedByLoad =\n changed.has(\"chatLoading\") &&\n changed.get(\"chatLoading\") === true &&\n host.chatLoading === false;\n scheduleChatScroll(\n host as unknown as Parameters[0],\n forcedByTab || forcedByLoad || !host.chatHasAutoScrolled,\n );\n }\n if (\n host.tab === \"logs\" &&\n (changed.has(\"logsEntries\") || changed.has(\"logsAutoFollow\") || changed.has(\"tab\"))\n ) {\n if (host.logsAutoFollow && host.logsAtBottom) {\n scheduleLogsScroll(\n host as unknown as Parameters[0],\n changed.has(\"tab\") || changed.has(\"logsAutoFollow\"),\n );\n }\n }\n}\n","import {\n loadChannels,\n logoutWhatsApp,\n startWhatsAppLogin,\n waitWhatsAppLogin,\n} from \"./controllers/channels\";\nimport { loadConfig, saveConfig } from \"./controllers/config\";\nimport type { ClawdbotApp } from \"./app\";\nimport type { NostrProfile } from \"./types\";\nimport { createNostrProfileFormState } from \"./views/channels.nostr-profile-form\";\n\nexport async function handleWhatsAppStart(host: ClawdbotApp, force: boolean) {\n await startWhatsAppLogin(host, force);\n await loadChannels(host, true);\n}\n\nexport async function handleWhatsAppWait(host: ClawdbotApp) {\n await waitWhatsAppLogin(host);\n await loadChannels(host, true);\n}\n\nexport async function handleWhatsAppLogout(host: ClawdbotApp) {\n await logoutWhatsApp(host);\n await loadChannels(host, true);\n}\n\nexport async function handleChannelConfigSave(host: ClawdbotApp) {\n await saveConfig(host);\n await loadConfig(host);\n await loadChannels(host, true);\n}\n\nexport async function handleChannelConfigReload(host: ClawdbotApp) {\n await loadConfig(host);\n await loadChannels(host, true);\n}\n\nfunction parseValidationErrors(details: unknown): Record {\n if (!Array.isArray(details)) return {};\n const errors: Record = {};\n for (const entry of details) {\n if (typeof entry !== \"string\") continue;\n const [rawField, ...rest] = entry.split(\":\");\n if (!rawField || rest.length === 0) continue;\n const field = rawField.trim();\n const message = rest.join(\":\").trim();\n if (field && message) errors[field] = message;\n }\n return errors;\n}\n\nfunction resolveNostrAccountId(host: ClawdbotApp): string {\n const accounts = host.channelsSnapshot?.channelAccounts?.nostr ?? [];\n return accounts[0]?.accountId ?? host.nostrProfileAccountId ?? \"default\";\n}\n\nfunction buildNostrProfileUrl(accountId: string, suffix = \"\"): string {\n return `/api/channels/nostr/${encodeURIComponent(accountId)}/profile${suffix}`;\n}\n\nexport function handleNostrProfileEdit(\n host: ClawdbotApp,\n accountId: string,\n profile: NostrProfile | null,\n) {\n host.nostrProfileAccountId = accountId;\n host.nostrProfileFormState = createNostrProfileFormState(profile ?? undefined);\n}\n\nexport function handleNostrProfileCancel(host: ClawdbotApp) {\n host.nostrProfileFormState = null;\n host.nostrProfileAccountId = null;\n}\n\nexport function handleNostrProfileFieldChange(\n host: ClawdbotApp,\n field: keyof NostrProfile,\n value: string,\n) {\n const state = host.nostrProfileFormState;\n if (!state) return;\n host.nostrProfileFormState = {\n ...state,\n values: {\n ...state.values,\n [field]: value,\n },\n fieldErrors: {\n ...state.fieldErrors,\n [field]: \"\",\n },\n };\n}\n\nexport function handleNostrProfileToggleAdvanced(host: ClawdbotApp) {\n const state = host.nostrProfileFormState;\n if (!state) return;\n host.nostrProfileFormState = {\n ...state,\n showAdvanced: !state.showAdvanced,\n };\n}\n\nexport async function handleNostrProfileSave(host: ClawdbotApp) {\n const state = host.nostrProfileFormState;\n if (!state || state.saving) return;\n const accountId = resolveNostrAccountId(host);\n\n host.nostrProfileFormState = {\n ...state,\n saving: true,\n error: null,\n success: null,\n fieldErrors: {},\n };\n\n try {\n const response = await fetch(buildNostrProfileUrl(accountId), {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(state.values),\n });\n const data = (await response.json().catch(() => null)) as\n | { ok?: boolean; error?: string; details?: unknown; persisted?: boolean }\n | null;\n\n if (!response.ok || data?.ok === false || !data) {\n const errorMessage = data?.error ?? `Profile update failed (${response.status})`;\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: errorMessage,\n success: null,\n fieldErrors: parseValidationErrors(data?.details),\n };\n return;\n }\n\n if (!data.persisted) {\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: \"Profile publish failed on all relays.\",\n success: null,\n };\n return;\n }\n\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: null,\n success: \"Profile published to relays.\",\n fieldErrors: {},\n original: { ...state.values },\n };\n await loadChannels(host, true);\n } catch (err) {\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: `Profile update failed: ${String(err)}`,\n success: null,\n };\n }\n}\n\nexport async function handleNostrProfileImport(host: ClawdbotApp) {\n const state = host.nostrProfileFormState;\n if (!state || state.importing) return;\n const accountId = resolveNostrAccountId(host);\n\n host.nostrProfileFormState = {\n ...state,\n importing: true,\n error: null,\n success: null,\n };\n\n try {\n const response = await fetch(buildNostrProfileUrl(accountId, \"/import\"), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ autoMerge: true }),\n });\n const data = (await response.json().catch(() => null)) as\n | { ok?: boolean; error?: string; imported?: NostrProfile; merged?: NostrProfile; saved?: boolean }\n | null;\n\n if (!response.ok || data?.ok === false || !data) {\n const errorMessage = data?.error ?? `Profile import failed (${response.status})`;\n host.nostrProfileFormState = {\n ...state,\n importing: false,\n error: errorMessage,\n success: null,\n };\n return;\n }\n\n const merged = data.merged ?? data.imported ?? null;\n const nextValues = merged ? { ...state.values, ...merged } : state.values;\n const showAdvanced = Boolean(\n nextValues.banner || nextValues.website || nextValues.nip05 || nextValues.lud16,\n );\n\n host.nostrProfileFormState = {\n ...state,\n importing: false,\n values: nextValues,\n error: null,\n success: data.saved\n ? \"Profile imported from relays. Review and publish.\"\n : \"Profile imported. Review and publish.\",\n showAdvanced,\n };\n\n if (data.saved) {\n await loadChannels(host, true);\n }\n } catch (err) {\n host.nostrProfileFormState = {\n ...state,\n importing: false,\n error: `Profile import failed: ${String(err)}`,\n success: null,\n };\n }\n}\n","import { LitElement, html, nothing } from \"lit\";\nimport { customElement, state } from \"lit/decorators.js\";\n\nimport type { GatewayBrowserClient, GatewayHelloOk } from \"./gateway\";\nimport { resolveInjectedAssistantIdentity } from \"./assistant-identity\";\nimport { loadSettings, type UiSettings } from \"./storage\";\nimport { renderApp } from \"./app-render\";\nimport type { Tab } from \"./navigation\";\nimport type { ResolvedTheme, ThemeMode } from \"./theme\";\nimport type {\n AgentsListResult,\n ConfigSnapshot,\n ConfigUiHints,\n CronJob,\n CronRunLogEntry,\n CronStatus,\n HealthSnapshot,\n LogEntry,\n LogLevel,\n PresenceEntry,\n ChannelsStatusSnapshot,\n SessionsListResult,\n SkillStatusReport,\n StatusSummary,\n NostrProfile,\n} from \"./types\";\nimport { type ChatQueueItem, type CronFormState } from \"./ui-types\";\nimport type { EventLogEntry } from \"./app-events\";\nimport { DEFAULT_CRON_FORM, DEFAULT_LOG_LEVEL_FILTERS } from \"./app-defaults\";\nimport type {\n ExecApprovalsFile,\n ExecApprovalsSnapshot,\n} from \"./controllers/exec-approvals\";\nimport type { DevicePairingList } from \"./controllers/devices\";\nimport type { ExecApprovalRequest } from \"./controllers/exec-approval\";\nimport {\n resetToolStream as resetToolStreamInternal,\n type ToolStreamEntry,\n} from \"./app-tool-stream\";\nimport {\n exportLogs as exportLogsInternal,\n handleChatScroll as handleChatScrollInternal,\n handleLogsScroll as handleLogsScrollInternal,\n resetChatScroll as resetChatScrollInternal,\n} from \"./app-scroll\";\nimport { connectGateway as connectGatewayInternal } from \"./app-gateway\";\nimport {\n handleConnected,\n handleDisconnected,\n handleFirstUpdated,\n handleUpdated,\n} from \"./app-lifecycle\";\nimport {\n applySettings as applySettingsInternal,\n loadCron as loadCronInternal,\n loadOverview as loadOverviewInternal,\n setTab as setTabInternal,\n setTheme as setThemeInternal,\n onPopState as onPopStateInternal,\n} from \"./app-settings\";\nimport {\n handleAbortChat as handleAbortChatInternal,\n handleSendChat as handleSendChatInternal,\n removeQueuedMessage as removeQueuedMessageInternal,\n} from \"./app-chat\";\nimport {\n handleChannelConfigReload as handleChannelConfigReloadInternal,\n handleChannelConfigSave as handleChannelConfigSaveInternal,\n handleNostrProfileCancel as handleNostrProfileCancelInternal,\n handleNostrProfileEdit as handleNostrProfileEditInternal,\n handleNostrProfileFieldChange as handleNostrProfileFieldChangeInternal,\n handleNostrProfileImport as handleNostrProfileImportInternal,\n handleNostrProfileSave as handleNostrProfileSaveInternal,\n handleNostrProfileToggleAdvanced as handleNostrProfileToggleAdvancedInternal,\n handleWhatsAppLogout as handleWhatsAppLogoutInternal,\n handleWhatsAppStart as handleWhatsAppStartInternal,\n handleWhatsAppWait as handleWhatsAppWaitInternal,\n} from \"./app-channels\";\nimport type { NostrProfileFormState } from \"./views/channels.nostr-profile-form\";\nimport { loadAssistantIdentity as loadAssistantIdentityInternal } from \"./controllers/assistant-identity\";\n\ndeclare global {\n interface Window {\n __CLAWDBOT_CONTROL_UI_BASE_PATH__?: string;\n }\n}\n\nconst injectedAssistantIdentity = resolveInjectedAssistantIdentity();\n\nfunction resolveOnboardingMode(): boolean {\n if (!window.location.search) return false;\n const params = new URLSearchParams(window.location.search);\n const raw = params.get(\"onboarding\");\n if (!raw) return false;\n const normalized = raw.trim().toLowerCase();\n return normalized === \"1\" || normalized === \"true\" || normalized === \"yes\" || normalized === \"on\";\n}\n\n@customElement(\"clawdbot-app\")\nexport class ClawdbotApp extends LitElement {\n @state() settings: UiSettings = loadSettings();\n @state() password = \"\";\n @state() tab: Tab = \"chat\";\n @state() onboarding = resolveOnboardingMode();\n @state() connected = false;\n @state() theme: ThemeMode = this.settings.theme ?? \"system\";\n @state() themeResolved: ResolvedTheme = \"dark\";\n @state() hello: GatewayHelloOk | null = null;\n @state() lastError: string | null = null;\n @state() eventLog: EventLogEntry[] = [];\n private eventLogBuffer: EventLogEntry[] = [];\n private toolStreamSyncTimer: number | null = null;\n private sidebarCloseTimer: number | null = null;\n\n @state() assistantName = injectedAssistantIdentity.name;\n @state() assistantAvatar = injectedAssistantIdentity.avatar;\n @state() assistantAgentId = injectedAssistantIdentity.agentId ?? null;\n\n @state() sessionKey = this.settings.sessionKey;\n @state() chatLoading = false;\n @state() chatSending = false;\n @state() chatMessage = \"\";\n @state() chatMessages: unknown[] = [];\n @state() chatToolMessages: unknown[] = [];\n @state() chatStream: string | null = null;\n @state() chatStreamStartedAt: number | null = null;\n @state() chatRunId: string | null = null;\n @state() compactionStatus: import(\"./app-tool-stream\").CompactionStatus | null = null;\n @state() chatAvatarUrl: string | null = null;\n @state() chatThinkingLevel: string | null = null;\n @state() chatQueue: ChatQueueItem[] = [];\n // Sidebar state for tool output viewing\n @state() sidebarOpen = false;\n @state() sidebarContent: string | null = null;\n @state() sidebarError: string | null = null;\n @state() splitRatio = this.settings.splitRatio;\n\n @state() nodesLoading = false;\n @state() nodes: Array> = [];\n @state() devicesLoading = false;\n @state() devicesError: string | null = null;\n @state() devicesList: DevicePairingList | null = null;\n @state() execApprovalsLoading = false;\n @state() execApprovalsSaving = false;\n @state() execApprovalsDirty = false;\n @state() execApprovalsSnapshot: ExecApprovalsSnapshot | null = null;\n @state() execApprovalsForm: ExecApprovalsFile | null = null;\n @state() execApprovalsSelectedAgent: string | null = null;\n @state() execApprovalsTarget: \"gateway\" | \"node\" = \"gateway\";\n @state() execApprovalsTargetNodeId: string | null = null;\n @state() execApprovalQueue: ExecApprovalRequest[] = [];\n @state() execApprovalBusy = false;\n @state() execApprovalError: string | null = null;\n\n @state() configLoading = false;\n @state() configRaw = \"{\\n}\\n\";\n @state() configRawOriginal = \"\";\n @state() configValid: boolean | null = null;\n @state() configIssues: unknown[] = [];\n @state() configSaving = false;\n @state() configApplying = false;\n @state() updateRunning = false;\n @state() applySessionKey = this.settings.lastActiveSessionKey;\n @state() configSnapshot: ConfigSnapshot | null = null;\n @state() configSchema: unknown | null = null;\n @state() configSchemaVersion: string | null = null;\n @state() configSchemaLoading = false;\n @state() configUiHints: ConfigUiHints = {};\n @state() configForm: Record | null = null;\n @state() configFormOriginal: Record | null = null;\n @state() configFormDirty = false;\n @state() configFormMode: \"form\" | \"raw\" = \"form\";\n @state() configSearchQuery = \"\";\n @state() configActiveSection: string | null = null;\n @state() configActiveSubsection: string | null = null;\n\n @state() channelsLoading = false;\n @state() channelsSnapshot: ChannelsStatusSnapshot | null = null;\n @state() channelsError: string | null = null;\n @state() channelsLastSuccess: number | null = null;\n @state() whatsappLoginMessage: string | null = null;\n @state() whatsappLoginQrDataUrl: string | null = null;\n @state() whatsappLoginConnected: boolean | null = null;\n @state() whatsappBusy = false;\n @state() nostrProfileFormState: NostrProfileFormState | null = null;\n @state() nostrProfileAccountId: string | null = null;\n\n @state() presenceLoading = false;\n @state() presenceEntries: PresenceEntry[] = [];\n @state() presenceError: string | null = null;\n @state() presenceStatus: string | null = null;\n\n @state() agentsLoading = false;\n @state() agentsList: AgentsListResult | null = null;\n @state() agentsError: string | null = null;\n\n @state() sessionsLoading = false;\n @state() sessionsResult: SessionsListResult | null = null;\n @state() sessionsError: string | null = null;\n @state() sessionsFilterActive = \"\";\n @state() sessionsFilterLimit = \"120\";\n @state() sessionsIncludeGlobal = true;\n @state() sessionsIncludeUnknown = false;\n\n @state() cronLoading = false;\n @state() cronJobs: CronJob[] = [];\n @state() cronStatus: CronStatus | null = null;\n @state() cronError: string | null = null;\n @state() cronForm: CronFormState = { ...DEFAULT_CRON_FORM };\n @state() cronRunsJobId: string | null = null;\n @state() cronRuns: CronRunLogEntry[] = [];\n @state() cronBusy = false;\n\n @state() skillsLoading = false;\n @state() skillsReport: SkillStatusReport | null = null;\n @state() skillsError: string | null = null;\n @state() skillsFilter = \"\";\n @state() skillEdits: Record = {};\n @state() skillsBusyKey: string | null = null;\n @state() skillMessages: Record = {};\n\n @state() debugLoading = false;\n @state() debugStatus: StatusSummary | null = null;\n @state() debugHealth: HealthSnapshot | null = null;\n @state() debugModels: unknown[] = [];\n @state() debugHeartbeat: unknown | null = null;\n @state() debugCallMethod = \"\";\n @state() debugCallParams = \"{}\";\n @state() debugCallResult: string | null = null;\n @state() debugCallError: string | null = null;\n\n @state() logsLoading = false;\n @state() logsError: string | null = null;\n @state() logsFile: string | null = null;\n @state() logsEntries: LogEntry[] = [];\n @state() logsFilterText = \"\";\n @state() logsLevelFilters: Record = {\n ...DEFAULT_LOG_LEVEL_FILTERS,\n };\n @state() logsAutoFollow = true;\n @state() logsTruncated = false;\n @state() logsCursor: number | null = null;\n @state() logsLastFetchAt: number | null = null;\n @state() logsLimit = 500;\n @state() logsMaxBytes = 250_000;\n @state() logsAtBottom = true;\n\n client: GatewayBrowserClient | null = null;\n private chatScrollFrame: number | null = null;\n private chatScrollTimeout: number | null = null;\n private chatHasAutoScrolled = false;\n private chatUserNearBottom = true;\n private nodesPollInterval: number | null = null;\n private logsPollInterval: number | null = null;\n private debugPollInterval: number | null = null;\n private logsScrollFrame: number | null = null;\n private toolStreamById = new Map();\n private toolStreamOrder: string[] = [];\n basePath = \"\";\n private popStateHandler = () =>\n onPopStateInternal(\n this as unknown as Parameters[0],\n );\n private themeMedia: MediaQueryList | null = null;\n private themeMediaHandler: ((event: MediaQueryListEvent) => void) | null = null;\n private topbarObserver: ResizeObserver | null = null;\n\n createRenderRoot() {\n return this;\n }\n\n connectedCallback() {\n super.connectedCallback();\n handleConnected(this as unknown as Parameters[0]);\n }\n\n protected firstUpdated() {\n handleFirstUpdated(this as unknown as Parameters[0]);\n }\n\n disconnectedCallback() {\n handleDisconnected(this as unknown as Parameters[0]);\n super.disconnectedCallback();\n }\n\n protected updated(changed: Map) {\n handleUpdated(\n this as unknown as Parameters[0],\n changed,\n );\n }\n\n connect() {\n connectGatewayInternal(\n this as unknown as Parameters[0],\n );\n }\n\n handleChatScroll(event: Event) {\n handleChatScrollInternal(\n this as unknown as Parameters[0],\n event,\n );\n }\n\n handleLogsScroll(event: Event) {\n handleLogsScrollInternal(\n this as unknown as Parameters[0],\n event,\n );\n }\n\n exportLogs(lines: string[], label: string) {\n exportLogsInternal(lines, label);\n }\n\n resetToolStream() {\n resetToolStreamInternal(\n this as unknown as Parameters[0],\n );\n }\n\n resetChatScroll() {\n resetChatScrollInternal(\n this as unknown as Parameters[0],\n );\n }\n\n async loadAssistantIdentity() {\n await loadAssistantIdentityInternal(this);\n }\n\n applySettings(next: UiSettings) {\n applySettingsInternal(\n this as unknown as Parameters[0],\n next,\n );\n }\n\n setTab(next: Tab) {\n setTabInternal(this as unknown as Parameters[0], next);\n }\n\n setTheme(next: ThemeMode, context?: Parameters[2]) {\n setThemeInternal(\n this as unknown as Parameters[0],\n next,\n context,\n );\n }\n\n async loadOverview() {\n await loadOverviewInternal(\n this as unknown as Parameters[0],\n );\n }\n\n async loadCron() {\n await loadCronInternal(\n this as unknown as Parameters[0],\n );\n }\n\n async handleAbortChat() {\n await handleAbortChatInternal(\n this as unknown as Parameters[0],\n );\n }\n\n removeQueuedMessage(id: string) {\n removeQueuedMessageInternal(\n this as unknown as Parameters[0],\n id,\n );\n }\n\n async handleSendChat(\n messageOverride?: string,\n opts?: Parameters[2],\n ) {\n await handleSendChatInternal(\n this as unknown as Parameters[0],\n messageOverride,\n opts,\n );\n }\n\n async handleWhatsAppStart(force: boolean) {\n await handleWhatsAppStartInternal(this, force);\n }\n\n async handleWhatsAppWait() {\n await handleWhatsAppWaitInternal(this);\n }\n\n async handleWhatsAppLogout() {\n await handleWhatsAppLogoutInternal(this);\n }\n\n async handleChannelConfigSave() {\n await handleChannelConfigSaveInternal(this);\n }\n\n async handleChannelConfigReload() {\n await handleChannelConfigReloadInternal(this);\n }\n\n handleNostrProfileEdit(accountId: string, profile: NostrProfile | null) {\n handleNostrProfileEditInternal(this, accountId, profile);\n }\n\n handleNostrProfileCancel() {\n handleNostrProfileCancelInternal(this);\n }\n\n handleNostrProfileFieldChange(field: keyof NostrProfile, value: string) {\n handleNostrProfileFieldChangeInternal(this, field, value);\n }\n\n async handleNostrProfileSave() {\n await handleNostrProfileSaveInternal(this);\n }\n\n async handleNostrProfileImport() {\n await handleNostrProfileImportInternal(this);\n }\n\n handleNostrProfileToggleAdvanced() {\n handleNostrProfileToggleAdvancedInternal(this);\n }\n\n async handleExecApprovalDecision(decision: \"allow-once\" | \"allow-always\" | \"deny\") {\n const active = this.execApprovalQueue[0];\n if (!active || !this.client || this.execApprovalBusy) return;\n this.execApprovalBusy = true;\n this.execApprovalError = null;\n try {\n await this.client.request(\"exec.approval.resolve\", {\n id: active.id,\n decision,\n });\n this.execApprovalQueue = this.execApprovalQueue.filter((entry) => entry.id !== active.id);\n } catch (err) {\n this.execApprovalError = `Exec approval failed: ${String(err)}`;\n } finally {\n this.execApprovalBusy = false;\n }\n }\n\n // Sidebar handlers for tool output viewing\n handleOpenSidebar(content: string) {\n if (this.sidebarCloseTimer != null) {\n window.clearTimeout(this.sidebarCloseTimer);\n this.sidebarCloseTimer = null;\n }\n this.sidebarContent = content;\n this.sidebarError = null;\n this.sidebarOpen = true;\n }\n\n handleCloseSidebar() {\n this.sidebarOpen = false;\n // Clear content after transition\n if (this.sidebarCloseTimer != null) {\n window.clearTimeout(this.sidebarCloseTimer);\n }\n this.sidebarCloseTimer = window.setTimeout(() => {\n if (this.sidebarOpen) return;\n this.sidebarContent = null;\n this.sidebarError = null;\n this.sidebarCloseTimer = null;\n }, 200);\n }\n\n handleSplitRatioChange(ratio: number) {\n const newRatio = Math.max(0.4, Math.min(0.7, ratio));\n this.splitRatio = newRatio;\n this.applySettings({ ...this.settings, splitRatio: newRatio });\n }\n\n render() {\n return renderApp(this);\n }\n}\n"],"names":["t","e","s","o","n$3","r","n","i","S","c","h","a","l","p","d","u","f","b","y$2","y","v","_","m","g","$","x","E","A","C","P","V","N","S$1","I","L","z","H","M","R","k","Z","I$2","Z$1","j","B","D","MAX_ASSISTANT_NAME","MAX_ASSISTANT_AVATAR","DEFAULT_ASSISTANT_NAME","coerceIdentityValue","value","maxLength","trimmed","normalizeAssistantIdentity","input","name","avatar","resolveInjectedAssistantIdentity","KEY","loadSettings","defaults","raw","parsed","saveSettings","next","parseAgentSessionKey","sessionKey","parts","agentId","rest","TAB_GROUPS","TAB_PATHS","PATH_TO_TAB","tab","path","normalizeBasePath","basePath","base","normalizePath","normalized","pathForTab","tabFromPath","pathname","inferBasePathFromPathname","segments","candidate","prefix","iconForTab","titleForTab","subtitleForTab","icons","html","QUICK_TAG_RE","FINAL_TAG_RE","THINKING_TAG_RE","applyTrim","mode","stripReasoningTagsFromText","text","options","cleaned","result","lastIndex","inThinking","match","idx","isClose","formatMs","ms","formatAgo","diff","sec","min","hr","formatDurationMs","formatList","values","clampText","max","truncateText","toNumber","fallback","stripThinkingTags","ENVELOPE_PREFIX","ENVELOPE_CHANNELS","textCache","thinkingCache","looksLikeEnvelopeHeader","header","label","stripEnvelope","extractText","message","role","content","item","joined","extractTextCached","obj","extractThinking","rawText","extractRawText","extracted","extractThinkingCached","formatReasoningMarkdown","lines","line","uuidFromBytes","bytes","hex","weakRandomBytes","now","generateUUID","cryptoLike","loadChatHistory","state","res","err","sendChatMessage","msg","runId","error","abortChatRun","handleChatEvent","payload","current","loadSessions","params","activeMinutes","limit","patchSession","key","patch","deleteSession","TOOL_STREAM_LIMIT","TOOL_STREAM_THROTTLE_MS","TOOL_OUTPUT_CHAR_LIMIT","extractToolOutputText","record","entry","part","formatToolOutput","contentText","truncated","buildToolStreamMessage","trimToolStream","host","overflow","removed","id","syncToolStreamMessages","flushToolStreamSync","scheduleToolStreamSync","force","resetToolStream","COMPACTION_TOAST_DURATION_MS","handleCompactionEvent","data","phase","handleAgentEvent","toolCallId","args","output","scheduleChatScroll","pickScrollTarget","container","overflowY","target","distanceFromBottom","retryDelay","latest","latestDistanceFromBottom","scheduleLogsScroll","handleChatScroll","event","handleLogsScroll","resetChatScroll","exportLogs","blob","url","anchor","stamp","observeTopbar","topbar","update","height","cloneConfigObject","serializeConfigForm","form","setPathValue","nextKey","lastKey","removePathValue","loadConfig","applyConfigSnapshot","loadConfigSchema","applyConfigSchema","snapshot","rawFromSnapshot","saveConfig","baseHash","applyConfig","runUpdate","updateConfigFormValue","removeConfigFormValue","loadCronStatus","loadCronJobs","buildCronSchedule","amount","unit","expr","buildCronPayload","timeoutSeconds","addCronJob","schedule","job","toggleCronJob","enabled","runCronJob","loadCronRuns","removeCronJob","jobId","loadChannels","probe","startWhatsAppLogin","waitWhatsAppLogin","logoutWhatsApp","loadDebug","status","health","models","heartbeat","modelPayload","callDebugMethod","LOG_BUFFER_LIMIT","LEVELS","parseMaybeJsonString","normalizeLevel","lowered","parseLogLine","meta","time","level","contextCandidate","contextObj","subsystem","loadLogs","opts","entries","shouldReset","ed25519_CURVE","Gx","Gy","_a","_d","L2","captureTrace","isBig","isStr","isBytes","abytes","length","title","len","needsLen","ofLen","got","u8n","u8fr","buf","padh","pad","bytesToHex","_ch","ch","hexToBytes","hl","al","array","ai","hi","n1","n2","cr","subtle","concatBytes","arrs","sum","randomBytes","big","assertRange","modN","invert","num","md","q","callHash","fn","hashes","apoint","Point","B256","X","Y","T","zip215","normed","lastByte","bytesToNumLE","y2","isValid","uvRatio","isXOdd","isLastByteOdd","X2","Y2","Z2","Z4","aX2","left","right","XY","ZT","other","X1","Y1","Z1","X1Z2","X2Z1","Y1Z2","Y2Z1","x1y1","G","F","X3","Y3","T3","Z3","T1","T2","safe","wNAF","scalar","iz","numTo32bLE","pow2","power","pow_2_252_3","b2","b4","b5","b10","b20","b40","b80","b160","b240","b250","RM1","v3","v7","pow","vx2","root1","root2","useRoot1","useRoot2","noRoot","modL_LE","hash","sha512a","sha512s","hash2extK","hashed","head","point","pointBytes","getExtendedPublicKeyAsync","secretKey","getExtendedPublicKey","getPublicKeyAsync","hashFinishA","_sign","rBytes","signAsync","randomSecretKey","seed","utils","W","scalarBits","pwindows","pwindowSize","precompute","points","w","Gpows","ctneg","cnd","comp","pow_2_w","maxNum","mask","shiftBy","wbits","off","offF","offP","isEven","isNeg","STORAGE_KEY","base64UrlEncode","binary","byte","base64UrlDecode","padded","out","fingerprintPublicKey","publicKey","generateIdentity","privateKey","loadOrCreateDeviceIdentity","derivedId","updated","identity","stored","signDevicePayload","privateKeyBase64Url","sig","normalizeRole","normalizeScopes","scopes","scope","readStore","writeStore","store","loadDeviceAuthToken","storeDeviceAuthToken","existing","clearDeviceAuthToken","loadDevices","approveDevicePairing","requestId","rejectDevicePairing","rotateDeviceToken","revokeDeviceToken","loadNodes","resolveExecApprovalsRpc","nodeId","resolveExecApprovalsSaveRpc","loadExecApprovals","rpc","applyExecApprovalsSnapshot","saveExecApprovals","file","updateExecApprovalsFormValue","removeExecApprovalsFormValue","loadPresence","setSkillMessage","getErrorMessage","loadSkills","updateSkillEdit","skillKey","updateSkillEnabled","saveSkillApiKey","apiKey","installSkill","installId","getSystemTheme","resolveTheme","clamp01","hasReducedMotionPreference","cleanupThemeTransition","root","startThemeTransition","nextTheme","applyTheme","context","currentTheme","documentReference","document_","prefersReducedMotion","xPercent","yPercent","rect","transition","startNodesPolling","stopNodesPolling","startLogsPolling","stopLogsPolling","startDebugPolling","stopDebugPolling","applySettings","applyResolvedTheme","setLastActiveSessionKey","applySettingsFromUrl","tokenRaw","passwordRaw","sessionRaw","gatewayUrlRaw","shouldCleanUrl","token","password","session","gatewayUrl","setTab","refreshActiveTab","syncUrlWithTab","setTheme","loadOverview","loadChannelsTab","loadCron","refreshChat","inferBasePath","configured","syncThemeWithSettings","resolved","attachThemeListener","detachThemeListener","syncTabWithLocation","replace","setTabFromRoute","onPopState","targetPath","currentPath","syncUrlWithSessionKey","isChatBusy","isChatStopCommand","handleAbortChat","enqueueChatMessage","sendChatMessageNow","ok","flushChatQueue","removeQueuedMessage","handleSendChat","messageOverride","previousDraft","refreshChatAvatar","flushChatQueueForEvent","resolveAgentIdForSession","buildAvatarMetaUrl","encoded","avatarUrl","i$1","normalizeMessage","hasToolId","contentRaw","contentItems","hasToolContent","hasToolName","timestamp","normalizeRoleForGrouping","lower","isToolResultMessage","setPrototypeOf","isFrozen","getPrototypeOf","getOwnPropertyDescriptor","freeze","seal","create","apply","construct","func","thisArg","_len","_key","Func","_len2","_key2","arrayForEach","unapply","arrayLastIndexOf","arrayPop","arrayPush","arraySplice","stringToLowerCase","stringToString","stringMatch","stringReplace","stringIndexOf","stringTrim","objectHasOwnProperty","regExpTest","typeErrorCreate","unconstruct","_len3","_key3","_len4","_key4","addToSet","set","transformCaseFunc","element","lcElement","cleanArray","index","clone","object","newObject","property","lookupGetter","prop","desc","fallbackValue","html$1","svg$1","svgFilters","svgDisallowed","mathMl$1","mathMlDisallowed","svg","mathMl","xml","MUSTACHE_EXPR","ERB_EXPR","TMPLIT_EXPR","DATA_ATTR","ARIA_ATTR","IS_ALLOWED_URI","IS_SCRIPT_OR_DATA","ATTR_WHITESPACE","DOCTYPE_NAME","CUSTOM_ELEMENT","EXPRESSIONS","NODE_TYPE","getGlobal","_createTrustedTypesPolicy","trustedTypes","purifyHostElement","suffix","ATTR_NAME","policyName","scriptUrl","_createHooksMap","createDOMPurify","window","DOMPurify","document","originalDocument","currentScript","DocumentFragment","HTMLTemplateElement","Node","Element","NodeFilter","NamedNodeMap","HTMLFormElement","DOMParser","ElementPrototype","cloneNode","remove","getNextSibling","getChildNodes","getParentNode","template","trustedTypesPolicy","emptyHTML","implementation","createNodeIterator","createDocumentFragment","getElementsByTagName","importNode","hooks","IS_ALLOWED_URI$1","ALLOWED_TAGS","DEFAULT_ALLOWED_TAGS","ALLOWED_ATTR","DEFAULT_ALLOWED_ATTR","CUSTOM_ELEMENT_HANDLING","FORBID_TAGS","FORBID_ATTR","EXTRA_ELEMENT_HANDLING","ALLOW_ARIA_ATTR","ALLOW_DATA_ATTR","ALLOW_UNKNOWN_PROTOCOLS","ALLOW_SELF_CLOSE_IN_ATTR","SAFE_FOR_TEMPLATES","SAFE_FOR_XML","WHOLE_DOCUMENT","SET_CONFIG","FORCE_BODY","RETURN_DOM","RETURN_DOM_FRAGMENT","RETURN_TRUSTED_TYPE","SANITIZE_DOM","SANITIZE_NAMED_PROPS","SANITIZE_NAMED_PROPS_PREFIX","KEEP_CONTENT","IN_PLACE","USE_PROFILES","FORBID_CONTENTS","DEFAULT_FORBID_CONTENTS","DATA_URI_TAGS","DEFAULT_DATA_URI_TAGS","URI_SAFE_ATTRIBUTES","DEFAULT_URI_SAFE_ATTRIBUTES","MATHML_NAMESPACE","SVG_NAMESPACE","HTML_NAMESPACE","NAMESPACE","IS_EMPTY_INPUT","ALLOWED_NAMESPACES","DEFAULT_ALLOWED_NAMESPACES","MATHML_TEXT_INTEGRATION_POINTS","HTML_INTEGRATION_POINTS","COMMON_SVG_AND_HTML_ELEMENTS","PARSER_MEDIA_TYPE","SUPPORTED_PARSER_MEDIA_TYPES","DEFAULT_PARSER_MEDIA_TYPE","CONFIG","formElement","isRegexOrFunction","testValue","_parseConfig","cfg","ALL_SVG_TAGS","ALL_MATHML_TAGS","_checkValidNamespace","parent","tagName","parentTagName","_forceRemove","node","_removeAttribute","_initDocument","dirty","doc","leadingWhitespace","matches","dirtyPayload","body","_createNodeIterator","_isClobbered","_isNode","_executeHooks","currentNode","hook","_sanitizeElements","_isBasicCustomElement","parentNode","childNodes","childCount","childClone","_isValidAttribute","lcTag","lcName","_sanitizeAttributes","attributes","hookEvent","attr","namespaceURI","attrValue","initValue","_sanitizeShadowDOM","fragment","shadowNode","shadowIterator","importedNode","returnNode","nodeIterator","serializedHTML","tag","entryPoint","hookFunction","purify","me","xe","be","Re","Te","re","se","Oe","Q","we","ye","Pe","Se","ie","$e","U","te","_e","Le","Me","ze","oe","Ae","K","ae","Ce","le","Ie","Ee","Be","ue","qe","ve","pe","De","He","Ze","Ge","Ne","Qe","Fe","je","ce","he","Ue","ne","Ke","We","Xe","ke","J","de","ge","Je","O","ee","fe","marked","allowedTags","allowedAttrs","hooksInstalled","MARKDOWN_CHAR_LIMIT","MARKDOWN_PARSE_LIMIT","MARKDOWN_CACHE_LIMIT","MARKDOWN_CACHE_MAX_CHARS","markdownCache","getCachedMarkdown","cached","setCachedMarkdown","oldest","installHooks","toSanitizedMarkdownHtml","markdown","escapeHtml","sanitized","rendered","COPIED_FOR_MS","ERROR_FOR_MS","COPY_LABEL","COPIED_LABEL","ERROR_LABEL","copyTextToClipboard","setButtonLabel","button","createCopyButton","idleLabel","btn","copied","renderCopyAsMarkdownButton","TOOL_DISPLAY_CONFIG","rawConfig","FALLBACK","TOOL_MAP","normalizeToolName","defaultTitle","normalizeVerb","coerceDisplayValue","firstLine","preview","lookupValueByPath","segment","resolveDetailFromKeys","keys","display","resolveReadDetail","offset","resolveWriteDetail","resolveActionSpec","spec","action","resolveToolDisplay","icon","actionRaw","actionSpec","verb","detail","detailKeys","shortenHomeInString","formatToolDetail","TOOL_INLINE_THRESHOLD","PREVIEW_MAX_LINES","PREVIEW_MAX_CHARS","formatToolOutputForSidebar","getTruncatedPreview","allLines","extractToolCards","normalizeContent","cards","kind","coerceArgs","extractToolText","card","renderToolCardSidebar","onOpenSidebar","hasText","canClick","handleClick","info","isShort","showCollapsed","showInline","isEmpty","nothing","renderReadingIndicatorGroup","assistant","renderAvatar","renderStreamingGroup","startedAt","renderGroupedMessage","renderMessageGroup","group","normalizedRole","assistantName","who","roleClass","assistantAvatar","initial","className","isAvatarUrl","isToolResult","toolCards","hasToolCards","extractedText","extractedThinking","markdownBase","reasoningMarkdown","canCopyMarkdown","bubbleClasses","unsafeHTML","renderMarkdownSidebar","props","ResizableDivider","LitElement","containerWidth","deltaRatio","newRatio","css","__decorateClass","customElement","renderCompactionIndicator","renderChat","canCompose","isBusy","canAbort","reasoningLevel","row","showReasoning","assistantIdentity","composePlaceholder","splitRatio","sidebarOpen","thread","repeat","buildChatItems","CHAT_HISTORY_RENDER_LIMIT","groupMessages","items","currentGroup","history","tools","historyStart","messageKey","messageId","schemaType","schema","defaultValue","pathKey","hintForPath","hints","direct","hintKey","hint","hintSegments","humanize","isSensitivePath","META_KEYS","isAnySchema","jsonValue","renderNode","unsupported","disabled","onPatch","showLabel","type","help","nonNull","extractLiteral","literals","allLiterals","resolvedValue","lit","renderSelect","primitiveTypes","variant","normalizedTypes","hasString","hasNumber","renderTextInput","opt","renderObject","renderArray","displayValue","renderNumberInput","inputType","isSensitive","placeholder","numValue","currentIndex","unset","val","sorted","orderA","orderB","reserved","additional","allowExtra","propKey","renderMapField","itemsSchema","arr","reservedKeys","anySchema","entryValue","valuePath","sectionIcons","SECTION_META","getSectionIcon","matchesSearch","query","schemaMatches","propSchema","unions","renderConfigForm","properties","searchQuery","activeSection","activeSubsection","filteredEntries","subsectionContext","sectionSchema","sectionKey","subsectionKey","description","sectionValue","scopedValue","normalizeEnum","filtered","nullable","enumValues","analyzeConfigSchema","normalizeSchemaNode","pathLabel","union","normalizeUnion","enumNullable","normalizedProps","remaining","unique","sidebarIcons","SECTIONS","ALL_SUBSECTION","resolveSectionMeta","resolveSubsections","uiHints","subKey","order","computeDiff","original","changes","compare","orig","curr","origObj","currObj","allKeys","truncateValue","maxLen","str","renderConfig","validity","analysis","formUnsafe","schemaProps","availableSections","knownKeys","extraSections","allSections","activeSectionSchema","activeSectionMeta","subsections","allowSubnav","isAllSubsection","effectiveSubsection","hasRawChanges","hasChanges","canSaveForm","canSave","canApply","canUpdate","section","change","formatDuration","channelEnabled","channels","channelStatus","running","connected","accountActive","account","getChannelAccountCount","channelAccounts","renderChannelAccountCount","count","resolveSchemaNode","resolveChannelValue","config","channelId","fromChannels","renderChannelConfigForm","configValue","renderChannelConfigSection","renderDiscordCard","discord","accountCountLabel","renderGoogleChatCard","googleChat","renderIMessageCard","imessage","isFormDirty","renderNostrProfileForm","callbacks","accountId","isDirty","renderField","field","inputId","renderPicturePreview","picture","img","createNostrProfileFormState","profile","truncatePubkey","pubkey","renderNostrCard","nostr","nostrAccounts","profileFormState","profileFormCallbacks","onEditProfile","primaryAccount","summaryConfigured","summaryRunning","summaryPublicKey","summaryLastStartAt","summaryLastError","hasMultipleAccounts","showingForm","renderAccountCard","displayName","renderProfileSection","about","nip05","hasAnyProfileData","renderSignalCard","signal","renderSlackCard","slack","renderTelegramCard","telegram","telegramAccounts","botUsername","renderWhatsAppCard","whatsapp","renderChannels","orderedChannels","resolveChannelOrder","channel","renderChannel","showForm","renderGenericChannelCard","resolveChannelLabel","lastError","accounts","renderGenericAccount","resolveChannelMetaMap","RECENT_ACTIVITY_THRESHOLD_MS","hasRecentActivity","deriveRunningStatus","deriveConnectedStatus","runningStatus","connectedStatus","formatPresenceSummary","ip","version","formatPresenceAge","ts","formatNextRun","formatSessionTokens","total","ctx","formatEventPayload","formatCronState","last","formatCronSchedule","formatCronPayload","buildChannelOptions","seen","renderCron","channelOptions","renderScheduleFields","renderJob","renderRun","itemClass","renderDebug","evt","renderInstances","renderEntry","lastInput","roles","scopesLabel","formatTime","date","matchesFilter","needle","renderLogs","levelFiltered","exportLabel","renderNodes","bindingState","resolveBindingsState","approvalsState","resolveExecApprovalsState","renderExecApprovals","renderBindings","renderDevices","list","pending","paired","req","renderPendingDevice","device","renderPairedDevice","age","repair","tokens","renderTokenRow","deviceId","when","EXEC_APPROVALS_DEFAULT_SCOPE","SECURITY_OPTIONS","ASK_OPTIONS","nodes","resolveExecNodes","defaultBinding","agents","resolveAgentBindings","ready","normalizeSecurity","normalizeAsk","resolveExecApprovalsDefaults","resolveConfigAgents","agentsNode","isDefault","resolveExecApprovalsAgents","configAgents","approvalsAgents","merged","agent","aLabel","bLabel","resolveExecApprovalsScope","selected","targetNodes","resolveExecApprovalsNodes","targetNodeId","selectedScope","selectedAgent","allowlist","supportsBinding","renderAgentBinding","targetReady","renderExecApprovalsTarget","renderExecApprovalsTabs","renderExecApprovalsPolicy","renderExecApprovalsAllowlist","hasNodes","nodeValue","first","isDefaults","agentSecurity","agentAsk","agentAskFallback","securityValue","askValue","askFallbackValue","autoOverride","autoEffective","autoIsDefault","option","allowlistPath","renderAllowlistEntry","lastUsed","lastCommand","lastPath","bindingValue","cmd","fallbackAgent","exec","execEntry","binding","caps","commands","renderOverview","uptime","tick","authHint","hasToken","hasPassword","insecureContextHint","THINK_LEVELS","BINARY_THINK_LEVELS","VERBOSE_LEVELS","REASONING_LEVELS","normalizeProviderId","provider","isBinaryThinkingProvider","resolveThinkLevelOptions","resolveThinkLevelDisplay","isBinary","resolveThinkLevelPatchValue","renderSessions","rows","renderRow","onDelete","rawThinking","isBinaryThinking","thinking","thinkLevels","verbose","reasoning","canLink","chatUrl","formatRemaining","totalSeconds","minutes","renderMetaRow","renderExecApprovalPrompt","active","request","remainingMs","queueCount","renderSkills","skills","filter","skill","renderSkill","busy","canInstall","missing","reasons","renderTab","href","renderChatControls","sessionOptions","resolveSessionOptions","disableThinkingToggle","disableFocusToggle","showThinking","focusActive","refreshIcon","focusIcon","sessions","resolvedCurrent","THEME_ORDER","renderThemeToggle","renderMonitorIcon","renderSunIcon","renderMoonIcon","AVATAR_DATA_RE","AVATAR_HTTP_RE","resolveAssistantAvatarUrl","renderApp","presenceCount","sessionsCount","cronNext","chatDisabledReason","isChat","chatFocus","assistantAvatarUrl","chatAvatarUrl","isGroupCollapsed","hasActiveTab","agentIndex","ratio","DEFAULT_LOG_LEVEL_FILTERS","DEFAULT_CRON_FORM","loadAgents","GATEWAY_CLIENT_IDS","GATEWAY_CLIENT_NAMES","GATEWAY_CLIENT_MODES","buildDeviceAuthPayload","CONNECT_FAILED_CLOSE_CODE","GatewayBrowserClient","ev","reason","delay","isSecureContext","deviceIdentity","canFallbackToShared","authToken","storedToken","auth","signedAtMs","nonce","signature","hello","frame","seq","method","resolve","reject","isRecord","parseExecApprovalRequested","command","createdAtMs","expiresAtMs","parseExecApprovalResolved","pruneExecApprovalQueue","queue","addExecApproval","removeExecApproval","loadAssistantIdentity","normalizeSessionKeyForDefaults","mainSessionKey","mainKey","defaultAgentId","applySessionDefaults","resolvedSessionKey","resolvedSettingsSessionKey","resolvedLastActiveSessionKey","nextSessionKey","nextSettings","shouldUpdateSettings","connectGateway","applySnapshot","code","handleGatewayEvent","expected","received","handleGatewayEventUnsafe","handleConnected","handleFirstUpdated","handleDisconnected","handleUpdated","changed","forcedByTab","forcedByLoad","handleWhatsAppStart","handleWhatsAppWait","handleWhatsAppLogout","handleChannelConfigSave","handleChannelConfigReload","parseValidationErrors","details","errors","rawField","resolveNostrAccountId","buildNostrProfileUrl","handleNostrProfileEdit","handleNostrProfileCancel","handleNostrProfileFieldChange","handleNostrProfileToggleAdvanced","handleNostrProfileSave","response","errorMessage","handleNostrProfileImport","nextValues","showAdvanced","injectedAssistantIdentity","resolveOnboardingMode","ClawdbotApp","onPopStateInternal","connectGatewayInternal","handleChatScrollInternal","handleLogsScrollInternal","exportLogsInternal","resetToolStreamInternal","resetChatScrollInternal","loadAssistantIdentityInternal","applySettingsInternal","setTabInternal","setThemeInternal","loadOverviewInternal","loadCronInternal","handleAbortChatInternal","removeQueuedMessageInternal","handleSendChatInternal","handleWhatsAppStartInternal","handleWhatsAppWaitInternal","handleWhatsAppLogoutInternal","handleChannelConfigSaveInternal","handleChannelConfigReloadInternal","handleNostrProfileEditInternal","handleNostrProfileCancelInternal","handleNostrProfileFieldChangeInternal","handleNostrProfileSaveInternal","handleNostrProfileImportInternal","handleNostrProfileToggleAdvancedInternal","decision"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,26,39,40,41,43,44,45]} \ No newline at end of file diff --git a/dist/control-ui/index.html b/dist/control-ui/index.html deleted file mode 100644 index 9407eea99..000000000 --- a/dist/control-ui/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Clawdbot Control - - - - - - - - - diff --git a/src/canvas-host/a2ui/a2ui.bundle.js b/src/canvas-host/a2ui/a2ui.bundle.js deleted file mode 100644 index c29280acd..000000000 --- a/src/canvas-host/a2ui/a2ui.bundle.js +++ /dev/null @@ -1,17768 +0,0 @@ -var __defProp$1 = Object.defineProperty; -var __exportAll = (all, symbols) => { - let target = {}; - for (var name in all) { - __defProp$1(target, name, { - get: all[name], - enumerable: true - }); - } - if (symbols) { - __defProp$1(target, Symbol.toStringTag, { value: "Module" }); - } - return target; -}; - -/** -* @license -* Copyright 2019 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -const t$6 = globalThis, e$13 = t$6.ShadowRoot && (void 0 === t$6.ShadyCSS || t$6.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, s$8 = Symbol(), o$14 = new WeakMap(); -var n$12 = class { - constructor(t$7, e$14, o$15) { - if (this._$cssResult$ = !0, o$15 !== s$8) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); - this.cssText = t$7, this.t = e$14; - } - get styleSheet() { - let t$7 = this.o; - const s$9 = this.t; - if (e$13 && void 0 === t$7) { - const e$14 = void 0 !== s$9 && 1 === s$9.length; - e$14 && (t$7 = o$14.get(s$9)), void 0 === t$7 && ((this.o = t$7 = new CSSStyleSheet()).replaceSync(this.cssText), e$14 && o$14.set(s$9, t$7)); - } - return t$7; - } - toString() { - return this.cssText; - } -}; -const r$11 = (t$7) => new n$12("string" == typeof t$7 ? t$7 : t$7 + "", void 0, s$8), i$9 = (t$7, ...e$14) => { - const o$15 = 1 === t$7.length ? t$7[0] : e$14.reduce((e$15, s$9, o$16) => e$15 + ((t$8) => { - if (!0 === t$8._$cssResult$) return t$8.cssText; - if ("number" == typeof t$8) return t$8; - throw Error("Value passed to 'css' function must be a 'css' function result: " + t$8 + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security."); - })(s$9) + t$7[o$16 + 1], t$7[0]); - return new n$12(o$15, t$7, s$8); -}, S$1 = (s$9, o$15) => { - if (e$13) s$9.adoptedStyleSheets = o$15.map((t$7) => t$7 instanceof CSSStyleSheet ? t$7 : t$7.styleSheet); - else for (const e$14 of o$15) { - const o$16 = document.createElement("style"), n$13 = t$6.litNonce; - void 0 !== n$13 && o$16.setAttribute("nonce", n$13), o$16.textContent = e$14.cssText, s$9.appendChild(o$16); - } -}, c$6 = e$13 ? (t$7) => t$7 : (t$7) => t$7 instanceof CSSStyleSheet ? ((t$8) => { - let e$14 = ""; - for (const s$9 of t$8.cssRules) e$14 += s$9.cssText; - return r$11(e$14); -})(t$7) : t$7; - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ const { is: i$8, defineProperty: e$12, getOwnPropertyDescriptor: h$6, getOwnPropertyNames: r$10, getOwnPropertySymbols: o$13, getPrototypeOf: n$11 } = Object, a$1 = globalThis, c$5 = a$1.trustedTypes, l$4 = c$5 ? c$5.emptyScript : "", p$2 = a$1.reactiveElementPolyfillSupport, d$2 = (t$7, s$9) => t$7, u$3 = { - toAttribute(t$7, s$9) { - switch (s$9) { - case Boolean: - t$7 = t$7 ? l$4 : null; - break; - case Object: - case Array: t$7 = null == t$7 ? t$7 : JSON.stringify(t$7); - } - return t$7; - }, - fromAttribute(t$7, s$9) { - let i$10 = t$7; - switch (s$9) { - case Boolean: - i$10 = null !== t$7; - break; - case Number: - i$10 = null === t$7 ? null : Number(t$7); - break; - case Object: - case Array: try { - i$10 = JSON.parse(t$7); - } catch (t$8) { - i$10 = null; - } - } - return i$10; - } -}, f$3 = (t$7, s$9) => !i$8(t$7, s$9), b$1 = { - attribute: !0, - type: String, - converter: u$3, - reflect: !1, - useDefault: !1, - hasChanged: f$3 -}; -Symbol.metadata ??= Symbol("metadata"), a$1.litPropertyMetadata ??= new WeakMap(); -var y$1 = class extends HTMLElement { - static addInitializer(t$7) { - this._$Ei(), (this.l ??= []).push(t$7); - } - static get observedAttributes() { - return this.finalize(), this._$Eh && [...this._$Eh.keys()]; - } - static createProperty(t$7, s$9 = b$1) { - if (s$9.state && (s$9.attribute = !1), this._$Ei(), this.prototype.hasOwnProperty(t$7) && ((s$9 = Object.create(s$9)).wrapped = !0), this.elementProperties.set(t$7, s$9), !s$9.noAccessor) { - const i$10 = Symbol(), h$7 = this.getPropertyDescriptor(t$7, i$10, s$9); - void 0 !== h$7 && e$12(this.prototype, t$7, h$7); - } - } - static getPropertyDescriptor(t$7, s$9, i$10) { - const { get: e$14, set: r$12 } = h$6(this.prototype, t$7) ?? { - get() { - return this[s$9]; - }, - set(t$8) { - this[s$9] = t$8; - } - }; - return { - get: e$14, - set(s$10) { - const h$7 = e$14?.call(this); - r$12?.call(this, s$10), this.requestUpdate(t$7, h$7, i$10); - }, - configurable: !0, - enumerable: !0 - }; - } - static getPropertyOptions(t$7) { - return this.elementProperties.get(t$7) ?? b$1; - } - static _$Ei() { - if (this.hasOwnProperty(d$2("elementProperties"))) return; - const t$7 = n$11(this); - t$7.finalize(), void 0 !== t$7.l && (this.l = [...t$7.l]), this.elementProperties = new Map(t$7.elementProperties); - } - static finalize() { - if (this.hasOwnProperty(d$2("finalized"))) return; - if (this.finalized = !0, this._$Ei(), this.hasOwnProperty(d$2("properties"))) { - const t$8 = this.properties, s$9 = [...r$10(t$8), ...o$13(t$8)]; - for (const i$10 of s$9) this.createProperty(i$10, t$8[i$10]); - } - const t$7 = this[Symbol.metadata]; - if (null !== t$7) { - const s$9 = litPropertyMetadata.get(t$7); - if (void 0 !== s$9) for (const [t$8, i$10] of s$9) this.elementProperties.set(t$8, i$10); - } - this._$Eh = new Map(); - for (const [t$8, s$9] of this.elementProperties) { - const i$10 = this._$Eu(t$8, s$9); - void 0 !== i$10 && this._$Eh.set(i$10, t$8); - } - this.elementStyles = this.finalizeStyles(this.styles); - } - static finalizeStyles(s$9) { - const i$10 = []; - if (Array.isArray(s$9)) { - const e$14 = new Set(s$9.flat(1 / 0).reverse()); - for (const s$10 of e$14) i$10.unshift(c$6(s$10)); - } else void 0 !== s$9 && i$10.push(c$6(s$9)); - return i$10; - } - static _$Eu(t$7, s$9) { - const i$10 = s$9.attribute; - return !1 === i$10 ? void 0 : "string" == typeof i$10 ? i$10 : "string" == typeof t$7 ? t$7.toLowerCase() : void 0; - } - constructor() { - super(), this._$Ep = void 0, this.isUpdatePending = !1, this.hasUpdated = !1, this._$Em = null, this._$Ev(); - } - _$Ev() { - this._$ES = new Promise((t$7) => this.enableUpdating = t$7), this._$AL = new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t$7) => t$7(this)); - } - addController(t$7) { - (this._$EO ??= new Set()).add(t$7), void 0 !== this.renderRoot && this.isConnected && t$7.hostConnected?.(); - } - removeController(t$7) { - this._$EO?.delete(t$7); - } - _$E_() { - const t$7 = new Map(), s$9 = this.constructor.elementProperties; - for (const i$10 of s$9.keys()) this.hasOwnProperty(i$10) && (t$7.set(i$10, this[i$10]), delete this[i$10]); - t$7.size > 0 && (this._$Ep = t$7); - } - createRenderRoot() { - const t$7 = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions); - return S$1(t$7, this.constructor.elementStyles), t$7; - } - connectedCallback() { - this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(!0), this._$EO?.forEach((t$7) => t$7.hostConnected?.()); - } - enableUpdating(t$7) {} - disconnectedCallback() { - this._$EO?.forEach((t$7) => t$7.hostDisconnected?.()); - } - attributeChangedCallback(t$7, s$9, i$10) { - this._$AK(t$7, i$10); - } - _$ET(t$7, s$9) { - const i$10 = this.constructor.elementProperties.get(t$7), e$14 = this.constructor._$Eu(t$7, i$10); - if (void 0 !== e$14 && !0 === i$10.reflect) { - const h$7 = (void 0 !== i$10.converter?.toAttribute ? i$10.converter : u$3).toAttribute(s$9, i$10.type); - this._$Em = t$7, null == h$7 ? this.removeAttribute(e$14) : this.setAttribute(e$14, h$7), this._$Em = null; - } - } - _$AK(t$7, s$9) { - const i$10 = this.constructor, e$14 = i$10._$Eh.get(t$7); - if (void 0 !== e$14 && this._$Em !== e$14) { - const t$8 = i$10.getPropertyOptions(e$14), h$7 = "function" == typeof t$8.converter ? { fromAttribute: t$8.converter } : void 0 !== t$8.converter?.fromAttribute ? t$8.converter : u$3; - this._$Em = e$14; - const r$12 = h$7.fromAttribute(s$9, t$8.type); - this[e$14] = r$12 ?? this._$Ej?.get(e$14) ?? r$12, this._$Em = null; - } - } - requestUpdate(t$7, s$9, i$10, e$14 = !1, h$7) { - if (void 0 !== t$7) { - const r$12 = this.constructor; - if (!1 === e$14 && (h$7 = this[t$7]), i$10 ??= r$12.getPropertyOptions(t$7), !((i$10.hasChanged ?? f$3)(h$7, s$9) || i$10.useDefault && i$10.reflect && h$7 === this._$Ej?.get(t$7) && !this.hasAttribute(r$12._$Eu(t$7, i$10)))) return; - this.C(t$7, s$9, i$10); - } - !1 === this.isUpdatePending && (this._$ES = this._$EP()); - } - C(t$7, s$9, { useDefault: i$10, reflect: e$14, wrapped: h$7 }, r$12) { - i$10 && !(this._$Ej ??= new Map()).has(t$7) && (this._$Ej.set(t$7, r$12 ?? s$9 ?? this[t$7]), !0 !== h$7 || void 0 !== r$12) || (this._$AL.has(t$7) || (this.hasUpdated || i$10 || (s$9 = void 0), this._$AL.set(t$7, s$9)), !0 === e$14 && this._$Em !== t$7 && (this._$Eq ??= new Set()).add(t$7)); - } - async _$EP() { - this.isUpdatePending = !0; - try { - await this._$ES; - } catch (t$8) { - Promise.reject(t$8); - } - const t$7 = this.scheduleUpdate(); - return null != t$7 && await t$7, !this.isUpdatePending; - } - scheduleUpdate() { - return this.performUpdate(); - } - performUpdate() { - if (!this.isUpdatePending) return; - if (!this.hasUpdated) { - if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) { - for (const [t$9, s$10] of this._$Ep) this[t$9] = s$10; - this._$Ep = void 0; - } - const t$8 = this.constructor.elementProperties; - if (t$8.size > 0) for (const [s$10, i$10] of t$8) { - const { wrapped: t$9 } = i$10, e$14 = this[s$10]; - !0 !== t$9 || this._$AL.has(s$10) || void 0 === e$14 || this.C(s$10, void 0, i$10, e$14); - } - } - let t$7 = !1; - const s$9 = this._$AL; - try { - t$7 = this.shouldUpdate(s$9), t$7 ? (this.willUpdate(s$9), this._$EO?.forEach((t$8) => t$8.hostUpdate?.()), this.update(s$9)) : this._$EM(); - } catch (s$10) { - throw t$7 = !1, this._$EM(), s$10; - } - t$7 && this._$AE(s$9); - } - willUpdate(t$7) {} - _$AE(t$7) { - this._$EO?.forEach((t$8) => t$8.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = !0, this.firstUpdated(t$7)), this.updated(t$7); - } - _$EM() { - this._$AL = new Map(), this.isUpdatePending = !1; - } - get updateComplete() { - return this.getUpdateComplete(); - } - getUpdateComplete() { - return this._$ES; - } - shouldUpdate(t$7) { - return !0; - } - update(t$7) { - this._$Eq &&= this._$Eq.forEach((t$8) => this._$ET(t$8, this[t$8])), this._$EM(); - } - updated(t$7) {} - firstUpdated(t$7) {} -}; -y$1.elementStyles = [], y$1.shadowRootOptions = { mode: "open" }, y$1[d$2("elementProperties")] = new Map(), y$1[d$2("finalized")] = new Map(), p$2?.({ ReactiveElement: y$1 }), (a$1.reactiveElementVersions ??= []).push("2.1.2"); - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -const t$5 = globalThis, i$7 = (t$7) => t$7, s$7 = t$5.trustedTypes, e$11 = s$7 ? s$7.createPolicy("lit-html", { createHTML: (t$7) => t$7 }) : void 0, h$5 = "$lit$", o$12 = `lit$${Math.random().toFixed(9).slice(2)}$`, n$10 = "?" + o$12, r$9 = `<${n$10}>`, l$3 = document, c$4 = () => l$3.createComment(""), a = (t$7) => null === t$7 || "object" != typeof t$7 && "function" != typeof t$7, u$2 = Array.isArray, d$1 = (t$7) => u$2(t$7) || "function" == typeof t$7?.[Symbol.iterator], f$2 = "[ \n\f\r]", v$1 = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, _ = /-->/g, m$2 = />/g, p$1 = RegExp(`>|${f$2}(?:([^\\s"'>=/]+)(${f$2}*=${f$2}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`, "g"), g = /'/g, $ = /"/g, y = /^(?:script|style|textarea|title)$/i, x = (t$7) => (i$10, ...s$9) => ({ - _$litType$: t$7, - strings: i$10, - values: s$9 -}), b = x(1), w = x(2), T = x(3), E = Symbol.for("lit-noChange"), A = Symbol.for("lit-nothing"), C = new WeakMap(), P = l$3.createTreeWalker(l$3, 129); -function V(t$7, i$10) { - if (!u$2(t$7) || !t$7.hasOwnProperty("raw")) throw Error("invalid template strings array"); - return void 0 !== e$11 ? e$11.createHTML(i$10) : i$10; -} -const N = (t$7, i$10) => { - const s$9 = t$7.length - 1, e$14 = []; - let n$13, l$5 = 2 === i$10 ? "" : 3 === i$10 ? "" : "", c$7 = v$1; - for (let i$11 = 0; i$11 < s$9; i$11++) { - const s$10 = t$7[i$11]; - let a, u$4, d$3 = -1, f$4 = 0; - for (; f$4 < s$10.length && (c$7.lastIndex = f$4, u$4 = c$7.exec(s$10), null !== u$4);) f$4 = c$7.lastIndex, c$7 === v$1 ? "!--" === u$4[1] ? c$7 = _ : void 0 !== u$4[1] ? c$7 = m$2 : void 0 !== u$4[2] ? (y.test(u$4[2]) && (n$13 = RegExp("" === u$4[0] ? (c$7 = n$13 ?? v$1, d$3 = -1) : void 0 === u$4[1] ? d$3 = -2 : (d$3 = c$7.lastIndex - u$4[2].length, a = u$4[1], c$7 = void 0 === u$4[3] ? p$1 : "\"" === u$4[3] ? $ : g) : c$7 === $ || c$7 === g ? c$7 = p$1 : c$7 === _ || c$7 === m$2 ? c$7 = v$1 : (c$7 = p$1, n$13 = void 0); - const x = c$7 === p$1 && t$7[i$11 + 1].startsWith("/>") ? " " : ""; - l$5 += c$7 === v$1 ? s$10 + r$9 : d$3 >= 0 ? (e$14.push(a), s$10.slice(0, d$3) + h$5 + s$10.slice(d$3) + o$12 + x) : s$10 + o$12 + (-2 === d$3 ? i$11 : x); - } - return [V(t$7, l$5 + (t$7[s$9] || "") + (2 === i$10 ? "" : 3 === i$10 ? "" : "")), e$14]; -}; -var S = class S { - constructor({ strings: t$7, _$litType$: i$10 }, e$14) { - let r$12; - this.parts = []; - let l$5 = 0, a = 0; - const u$4 = t$7.length - 1, d$3 = this.parts, [f$4, v$2] = N(t$7, i$10); - if (this.el = S.createElement(f$4, e$14), P.currentNode = this.el.content, 2 === i$10 || 3 === i$10) { - const t$8 = this.el.content.firstChild; - t$8.replaceWith(...t$8.childNodes); - } - for (; null !== (r$12 = P.nextNode()) && d$3.length < u$4;) { - if (1 === r$12.nodeType) { - if (r$12.hasAttributes()) for (const t$8 of r$12.getAttributeNames()) if (t$8.endsWith(h$5)) { - const i$11 = v$2[a++], s$9 = r$12.getAttribute(t$8).split(o$12), e$15 = /([.?@])?(.*)/.exec(i$11); - d$3.push({ - type: 1, - index: l$5, - name: e$15[2], - strings: s$9, - ctor: "." === e$15[1] ? I : "?" === e$15[1] ? L : "@" === e$15[1] ? z : H - }), r$12.removeAttribute(t$8); - } else t$8.startsWith(o$12) && (d$3.push({ - type: 6, - index: l$5 - }), r$12.removeAttribute(t$8)); - if (y.test(r$12.tagName)) { - const t$8 = r$12.textContent.split(o$12), i$11 = t$8.length - 1; - if (i$11 > 0) { - r$12.textContent = s$7 ? s$7.emptyScript : ""; - for (let s$9 = 0; s$9 < i$11; s$9++) r$12.append(t$8[s$9], c$4()), P.nextNode(), d$3.push({ - type: 2, - index: ++l$5 - }); - r$12.append(t$8[i$11], c$4()); - } - } - } else if (8 === r$12.nodeType) if (r$12.data === n$10) d$3.push({ - type: 2, - index: l$5 - }); - else { - let t$8 = -1; - for (; -1 !== (t$8 = r$12.data.indexOf(o$12, t$8 + 1));) d$3.push({ - type: 7, - index: l$5 - }), t$8 += o$12.length - 1; - } - l$5++; - } - } - static createElement(t$7, i$10) { - const s$9 = l$3.createElement("template"); - return s$9.innerHTML = t$7, s$9; - } -}; -function M$1(t$7, i$10, s$9 = t$7, e$14) { - if (i$10 === E) return i$10; - let h$7 = void 0 !== e$14 ? s$9._$Co?.[e$14] : s$9._$Cl; - const o$15 = a(i$10) ? void 0 : i$10._$litDirective$; - return h$7?.constructor !== o$15 && (h$7?._$AO?.(!1), void 0 === o$15 ? h$7 = void 0 : (h$7 = new o$15(t$7), h$7._$AT(t$7, s$9, e$14)), void 0 !== e$14 ? (s$9._$Co ??= [])[e$14] = h$7 : s$9._$Cl = h$7), void 0 !== h$7 && (i$10 = M$1(t$7, h$7._$AS(t$7, i$10.values), h$7, e$14)), i$10; -} -var R = class { - constructor(t$7, i$10) { - this._$AV = [], this._$AN = void 0, this._$AD = t$7, this._$AM = i$10; - } - get parentNode() { - return this._$AM.parentNode; - } - get _$AU() { - return this._$AM._$AU; - } - u(t$7) { - const { el: { content: i$10 }, parts: s$9 } = this._$AD, e$14 = (t$7?.creationScope ?? l$3).importNode(i$10, !0); - P.currentNode = e$14; - let h$7 = P.nextNode(), o$15 = 0, n$13 = 0, r$12 = s$9[0]; - for (; void 0 !== r$12;) { - if (o$15 === r$12.index) { - let i$11; - 2 === r$12.type ? i$11 = new k(h$7, h$7.nextSibling, this, t$7) : 1 === r$12.type ? i$11 = new r$12.ctor(h$7, r$12.name, r$12.strings, this, t$7) : 6 === r$12.type && (i$11 = new Z(h$7, this, t$7)), this._$AV.push(i$11), r$12 = s$9[++n$13]; - } - o$15 !== r$12?.index && (h$7 = P.nextNode(), o$15++); - } - return P.currentNode = l$3, e$14; - } - p(t$7) { - let i$10 = 0; - for (const s$9 of this._$AV) void 0 !== s$9 && (void 0 !== s$9.strings ? (s$9._$AI(t$7, s$9, i$10), i$10 += s$9.strings.length - 2) : s$9._$AI(t$7[i$10])), i$10++; - } -}; -var k = class k { - get _$AU() { - return this._$AM?._$AU ?? this._$Cv; - } - constructor(t$7, i$10, s$9, e$14) { - this.type = 2, this._$AH = A, this._$AN = void 0, this._$AA = t$7, this._$AB = i$10, this._$AM = s$9, this.options = e$14, this._$Cv = e$14?.isConnected ?? !0; - } - get parentNode() { - let t$7 = this._$AA.parentNode; - const i$10 = this._$AM; - return void 0 !== i$10 && 11 === t$7?.nodeType && (t$7 = i$10.parentNode), t$7; - } - get startNode() { - return this._$AA; - } - get endNode() { - return this._$AB; - } - _$AI(t$7, i$10 = this) { - t$7 = M$1(this, t$7, i$10), a(t$7) ? t$7 === A || null == t$7 || "" === t$7 ? (this._$AH !== A && this._$AR(), this._$AH = A) : t$7 !== this._$AH && t$7 !== E && this._(t$7) : void 0 !== t$7._$litType$ ? this.$(t$7) : void 0 !== t$7.nodeType ? this.T(t$7) : d$1(t$7) ? this.k(t$7) : this._(t$7); - } - O(t$7) { - return this._$AA.parentNode.insertBefore(t$7, this._$AB); - } - T(t$7) { - this._$AH !== t$7 && (this._$AR(), this._$AH = this.O(t$7)); - } - _(t$7) { - this._$AH !== A && a(this._$AH) ? this._$AA.nextSibling.data = t$7 : this.T(l$3.createTextNode(t$7)), this._$AH = t$7; - } - $(t$7) { - const { values: i$10, _$litType$: s$9 } = t$7, e$14 = "number" == typeof s$9 ? this._$AC(t$7) : (void 0 === s$9.el && (s$9.el = S.createElement(V(s$9.h, s$9.h[0]), this.options)), s$9); - if (this._$AH?._$AD === e$14) this._$AH.p(i$10); - else { - const t$8 = new R(e$14, this), s$10 = t$8.u(this.options); - t$8.p(i$10), this.T(s$10), this._$AH = t$8; - } - } - _$AC(t$7) { - let i$10 = C.get(t$7.strings); - return void 0 === i$10 && C.set(t$7.strings, i$10 = new S(t$7)), i$10; - } - k(t$7) { - u$2(this._$AH) || (this._$AH = [], this._$AR()); - const i$10 = this._$AH; - let s$9, e$14 = 0; - for (const h$7 of t$7) e$14 === i$10.length ? i$10.push(s$9 = new k(this.O(c$4()), this.O(c$4()), this, this.options)) : s$9 = i$10[e$14], s$9._$AI(h$7), e$14++; - e$14 < i$10.length && (this._$AR(s$9 && s$9._$AB.nextSibling, e$14), i$10.length = e$14); - } - _$AR(t$7 = this._$AA.nextSibling, s$9) { - for (this._$AP?.(!1, !0, s$9); t$7 !== this._$AB;) { - const s$10 = i$7(t$7).nextSibling; - i$7(t$7).remove(), t$7 = s$10; - } - } - setConnected(t$7) { - void 0 === this._$AM && (this._$Cv = t$7, this._$AP?.(t$7)); - } -}; -var H = class { - get tagName() { - return this.element.tagName; - } - get _$AU() { - return this._$AM._$AU; - } - constructor(t$7, i$10, s$9, e$14, h$7) { - this.type = 1, this._$AH = A, this._$AN = void 0, this.element = t$7, this.name = i$10, this._$AM = e$14, this.options = h$7, s$9.length > 2 || "" !== s$9[0] || "" !== s$9[1] ? (this._$AH = Array(s$9.length - 1).fill(new String()), this.strings = s$9) : this._$AH = A; - } - _$AI(t$7, i$10 = this, s$9, e$14) { - const h$7 = this.strings; - let o$15 = !1; - if (void 0 === h$7) t$7 = M$1(this, t$7, i$10, 0), o$15 = !a(t$7) || t$7 !== this._$AH && t$7 !== E, o$15 && (this._$AH = t$7); - else { - const e$15 = t$7; - let n$13, r$12; - for (t$7 = h$7[0], n$13 = 0; n$13 < h$7.length - 1; n$13++) r$12 = M$1(this, e$15[s$9 + n$13], i$10, n$13), r$12 === E && (r$12 = this._$AH[n$13]), o$15 ||= !a(r$12) || r$12 !== this._$AH[n$13], r$12 === A ? t$7 = A : t$7 !== A && (t$7 += (r$12 ?? "") + h$7[n$13 + 1]), this._$AH[n$13] = r$12; - } - o$15 && !e$14 && this.j(t$7); - } - j(t$7) { - t$7 === A ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t$7 ?? ""); - } -}; -var I = class extends H { - constructor() { - super(...arguments), this.type = 3; - } - j(t$7) { - this.element[this.name] = t$7 === A ? void 0 : t$7; - } -}; -var L = class extends H { - constructor() { - super(...arguments), this.type = 4; - } - j(t$7) { - this.element.toggleAttribute(this.name, !!t$7 && t$7 !== A); - } -}; -var z = class extends H { - constructor(t$7, i$10, s$9, e$14, h$7) { - super(t$7, i$10, s$9, e$14, h$7), this.type = 5; - } - _$AI(t$7, i$10 = this) { - if ((t$7 = M$1(this, t$7, i$10, 0) ?? A) === E) return; - const s$9 = this._$AH, e$14 = t$7 === A && s$9 !== A || t$7.capture !== s$9.capture || t$7.once !== s$9.once || t$7.passive !== s$9.passive, h$7 = t$7 !== A && (s$9 === A || e$14); - e$14 && this.element.removeEventListener(this.name, this, s$9), h$7 && this.element.addEventListener(this.name, this, t$7), this._$AH = t$7; - } - handleEvent(t$7) { - "function" == typeof this._$AH ? this._$AH.call(this.options?.host ?? this.element, t$7) : this._$AH.handleEvent(t$7); - } -}; -var Z = class { - constructor(t$7, i$10, s$9) { - this.element = t$7, this.type = 6, this._$AN = void 0, this._$AM = i$10, this.options = s$9; - } - get _$AU() { - return this._$AM._$AU; - } - _$AI(t$7) { - M$1(this, t$7); - } -}; -const j$1 = { - M: h$5, - P: o$12, - A: n$10, - C: 1, - L: N, - R, - D: d$1, - V: M$1, - I: k, - H, - N: L, - U: z, - B: I, - F: Z -}, B = t$5.litHtmlPolyfillSupport; -B?.(S, k), (t$5.litHtmlVersions ??= []).push("3.3.2"); -const D = (t$7, i$10, s$9) => { - const e$14 = s$9?.renderBefore ?? i$10; - let h$7 = e$14._$litPart$; - if (void 0 === h$7) { - const t$8 = s$9?.renderBefore ?? null; - e$14._$litPart$ = h$7 = new k(i$10.insertBefore(c$4(), t$8), t$8, void 0, s$9 ?? {}); - } - return h$7._$AI(t$7), h$7; -}; - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ const s$6 = globalThis; -var i$6 = class extends y$1 { - constructor() { - super(...arguments), this.renderOptions = { host: this }, this._$Do = void 0; - } - createRenderRoot() { - const t$7 = super.createRenderRoot(); - return this.renderOptions.renderBefore ??= t$7.firstChild, t$7; - } - update(t$7) { - const r$12 = this.render(); - this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t$7), this._$Do = D(r$12, this.renderRoot, this.renderOptions); - } - connectedCallback() { - super.connectedCallback(), this._$Do?.setConnected(!0); - } - disconnectedCallback() { - super.disconnectedCallback(), this._$Do?.setConnected(!1); - } - render() { - return E; - } -}; -i$6._$litElement$ = !0, i$6["finalized"] = !0, s$6.litElementHydrateSupport?.({ LitElement: i$6 }); -const o$11 = s$6.litElementPolyfillSupport; -o$11?.({ LitElement: i$6 }); -const n$9 = { - _$AK: (t$7, e$14, r$12) => { - t$7._$AK(e$14, r$12); - }, - _$AL: (t$7) => t$7._$AL -}; -(s$6.litElementVersions ??= []).push("4.2.2"); - -/** -* @license -* Copyright 2022 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -const o$10 = !1; - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -const t$4 = { - ATTRIBUTE: 1, - CHILD: 2, - PROPERTY: 3, - BOOLEAN_ATTRIBUTE: 4, - EVENT: 5, - ELEMENT: 6 -}, e$10 = (t$7) => (...e$14) => ({ - _$litDirective$: t$7, - values: e$14 -}); -var i$5 = class { - constructor(t$7) {} - get _$AU() { - return this._$AM._$AU; - } - _$AT(t$7, e$14, i$10) { - this._$Ct = t$7, this._$AM = e$14, this._$Ci = i$10; - } - _$AS(t$7, e$14) { - return this.update(t$7, e$14); - } - update(t$7, e$14) { - return this.render(...e$14); - } -}; - -/** -* @license -* Copyright 2020 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ const { I: t$3 } = j$1, i$4 = (o$15) => o$15, n$8 = (o$15) => null === o$15 || "object" != typeof o$15 && "function" != typeof o$15, e$9 = { - HTML: 1, - SVG: 2, - MATHML: 3 -}, l$2 = (o$15, t$7) => void 0 === t$7 ? void 0 !== o$15?._$litType$ : o$15?._$litType$ === t$7, d = (o$15) => null != o$15?._$litType$?.h, c$3 = (o$15) => void 0 !== o$15?._$litDirective$, f$1 = (o$15) => o$15?._$litDirective$, r$8 = (o$15) => void 0 === o$15.strings, s$5 = () => document.createComment(""), v = (o$15, n$13, e$14) => { - const l$5 = o$15._$AA.parentNode, d = void 0 === n$13 ? o$15._$AB : n$13._$AA; - if (void 0 === e$14) { - const i$10 = l$5.insertBefore(s$5(), d), n$14 = l$5.insertBefore(s$5(), d); - e$14 = new t$3(i$10, n$14, o$15, o$15.options); - } else { - const t$7 = e$14._$AB.nextSibling, n$14 = e$14._$AM, c$7 = n$14 !== o$15; - if (c$7) { - let t$8; - e$14._$AQ?.(o$15), e$14._$AM = o$15, void 0 !== e$14._$AP && (t$8 = o$15._$AU) !== n$14._$AU && e$14._$AP(t$8); - } - if (t$7 !== d || c$7) { - let o$16 = e$14._$AA; - for (; o$16 !== t$7;) { - const t$8 = i$4(o$16).nextSibling; - i$4(l$5).insertBefore(o$16, d), o$16 = t$8; - } - } - } - return e$14; -}, u$1 = (o$15, t$7, i$10 = o$15) => (o$15._$AI(t$7, i$10), o$15), m$1 = {}, p = (o$15, t$7 = m$1) => o$15._$AH = t$7, M = (o$15) => o$15._$AH, h$4 = (o$15) => { - o$15._$AR(), o$15._$AA.remove(); -}, j = (o$15) => { - o$15._$AR(); -}; - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -const u = (e$14, s$9, t$7) => { - const r$12 = new Map(); - for (let l$5 = s$9; l$5 <= t$7; l$5++) r$12.set(e$14[l$5], l$5); - return r$12; -}, c$2 = e$10(class extends i$5 { - constructor(e$14) { - if (super(e$14), e$14.type !== t$4.CHILD) throw Error("repeat() can only be used in text expressions"); - } - dt(e$14, s$9, t$7) { - let r$12; - void 0 === t$7 ? t$7 = s$9 : void 0 !== s$9 && (r$12 = s$9); - const l$5 = [], o$15 = []; - let i$10 = 0; - for (const s$10 of e$14) l$5[i$10] = r$12 ? r$12(s$10, i$10) : i$10, o$15[i$10] = t$7(s$10, i$10), i$10++; - return { - values: o$15, - keys: l$5 - }; - } - render(e$14, s$9, t$7) { - return this.dt(e$14, s$9, t$7).values; - } - update(s$9, [t$7, r$12, c$7]) { - const d$3 = M(s$9), { values: p$3, keys: a$2 } = this.dt(t$7, r$12, c$7); - if (!Array.isArray(d$3)) return this.ut = a$2, p$3; - const h$7 = this.ut ??= [], v$2 = []; - let m$3, y$2, x$1 = 0, j$2 = d$3.length - 1, k$1 = 0, w$1 = p$3.length - 1; - for (; x$1 <= j$2 && k$1 <= w$1;) if (null === d$3[x$1]) x$1++; - else if (null === d$3[j$2]) j$2--; - else if (h$7[x$1] === a$2[k$1]) v$2[k$1] = u$1(d$3[x$1], p$3[k$1]), x$1++, k$1++; - else if (h$7[j$2] === a$2[w$1]) v$2[w$1] = u$1(d$3[j$2], p$3[w$1]), j$2--, w$1--; - else if (h$7[x$1] === a$2[w$1]) v$2[w$1] = u$1(d$3[x$1], p$3[w$1]), v(s$9, v$2[w$1 + 1], d$3[x$1]), x$1++, w$1--; - else if (h$7[j$2] === a$2[k$1]) v$2[k$1] = u$1(d$3[j$2], p$3[k$1]), v(s$9, d$3[x$1], d$3[j$2]), j$2--, k$1++; - else if (void 0 === m$3 && (m$3 = u(a$2, k$1, w$1), y$2 = u(h$7, x$1, j$2)), m$3.has(h$7[x$1])) if (m$3.has(h$7[j$2])) { - const e$14 = y$2.get(a$2[k$1]), t$8 = void 0 !== e$14 ? d$3[e$14] : null; - if (null === t$8) { - const e$15 = v(s$9, d$3[x$1]); - u$1(e$15, p$3[k$1]), v$2[k$1] = e$15; - } else v$2[k$1] = u$1(t$8, p$3[k$1]), v(s$9, d$3[x$1], t$8), d$3[e$14] = null; - k$1++; - } else h$4(d$3[j$2]), j$2--; - else h$4(d$3[x$1]), x$1++; - for (; k$1 <= w$1;) { - const e$14 = v(s$9, v$2[w$1 + 1]); - u$1(e$14, p$3[k$1]), v$2[k$1++] = e$14; - } - for (; x$1 <= j$2;) { - const e$14 = d$3[x$1++]; - null !== e$14 && h$4(e$14); - } - return this.ut = a$2, p(s$9, v$2), E; - } -}); - -/** -* @license -* Copyright 2021 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -var s$4 = class extends Event { - constructor(s$9, t$7, e$14, o$15) { - super("context-request", { - bubbles: !0, - composed: !0 - }), this.context = s$9, this.contextTarget = t$7, this.callback = e$14, this.subscribe = o$15 ?? !1; - } -}; - -/** -* @license -* Copyright 2021 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -function n$7(n$13) { - return n$13; -} - -/** -* @license -* Copyright 2021 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ var s$3 = class { - constructor(t$7, s$9, i$10, h$7) { - if (this.subscribe = !1, this.provided = !1, this.value = void 0, this.t = (t$8, s$10) => { - this.unsubscribe && (this.unsubscribe !== s$10 && (this.provided = !1, this.unsubscribe()), this.subscribe || this.unsubscribe()), this.value = t$8, this.host.requestUpdate(), this.provided && !this.subscribe || (this.provided = !0, this.callback && this.callback(t$8, s$10)), this.unsubscribe = s$10; - }, this.host = t$7, void 0 !== s$9.context) { - const t$8 = s$9; - this.context = t$8.context, this.callback = t$8.callback, this.subscribe = t$8.subscribe ?? !1; - } else this.context = s$9, this.callback = i$10, this.subscribe = h$7 ?? !1; - this.host.addController(this); - } - hostConnected() { - this.dispatchRequest(); - } - hostDisconnected() { - this.unsubscribe && (this.unsubscribe(), this.unsubscribe = void 0); - } - dispatchRequest() { - this.host.dispatchEvent(new s$4(this.context, this.host, this.t, this.subscribe)); - } -}; - -/** -* @license -* Copyright 2021 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -var s$2 = class { - get value() { - return this.o; - } - set value(s$9) { - this.setValue(s$9); - } - setValue(s$9, t$7 = !1) { - const i$10 = t$7 || !Object.is(s$9, this.o); - this.o = s$9, i$10 && this.updateObservers(); - } - constructor(s$9) { - this.subscriptions = new Map(), this.updateObservers = () => { - for (const [s$10, { disposer: t$7 }] of this.subscriptions) s$10(this.o, t$7); - }, void 0 !== s$9 && (this.value = s$9); - } - addCallback(s$9, t$7, i$10) { - if (!i$10) return void s$9(this.value); - this.subscriptions.has(s$9) || this.subscriptions.set(s$9, { - disposer: () => { - this.subscriptions.delete(s$9); - }, - consumerHost: t$7 - }); - const { disposer: h$7 } = this.subscriptions.get(s$9); - s$9(this.value, h$7); - } - clearCallbacks() { - this.subscriptions.clear(); - } -}; - -/** -* @license -* Copyright 2021 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ var e$8 = class extends Event { - constructor(t$7, s$9) { - super("context-provider", { - bubbles: !0, - composed: !0 - }), this.context = t$7, this.contextTarget = s$9; - } -}; -var i$3 = class extends s$2 { - constructor(s$9, e$14, i$10) { - super(void 0 !== e$14.context ? e$14.initialValue : i$10), this.onContextRequest = (t$7) => { - if (t$7.context !== this.context) return; - const s$10 = t$7.contextTarget ?? t$7.composedPath()[0]; - s$10 !== this.host && (t$7.stopPropagation(), this.addCallback(t$7.callback, s$10, t$7.subscribe)); - }, this.onProviderRequest = (s$10) => { - if (s$10.context !== this.context) return; - if ((s$10.contextTarget ?? s$10.composedPath()[0]) === this.host) return; - const e$15 = new Set(); - for (const [s$11, { consumerHost: i$11 }] of this.subscriptions) e$15.has(s$11) || (e$15.add(s$11), i$11.dispatchEvent(new s$4(this.context, i$11, s$11, !0))); - s$10.stopPropagation(); - }, this.host = s$9, void 0 !== e$14.context ? this.context = e$14.context : this.context = e$14, this.attachListeners(), this.host.addController?.(this); - } - attachListeners() { - this.host.addEventListener("context-request", this.onContextRequest), this.host.addEventListener("context-provider", this.onProviderRequest); - } - hostConnected() { - this.host.dispatchEvent(new e$8(this.context, this.host)); - } -}; - -/** -* @license -* Copyright 2021 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ var t$2 = class { - constructor() { - this.pendingContextRequests = new Map(), this.onContextProvider = (t$7) => { - const s$9 = this.pendingContextRequests.get(t$7.context); - if (void 0 === s$9) return; - this.pendingContextRequests.delete(t$7.context); - const { requests: o$15 } = s$9; - for (const { elementRef: s$10, callbackRef: n$13 } of o$15) { - const o$16 = s$10.deref(), c$7 = n$13.deref(); - void 0 === o$16 || void 0 === c$7 || o$16.dispatchEvent(new s$4(t$7.context, o$16, c$7, !0)); - } - }, this.onContextRequest = (e$14) => { - if (!0 !== e$14.subscribe) return; - const t$7 = e$14.contextTarget ?? e$14.composedPath()[0], s$9 = e$14.callback; - let o$15 = this.pendingContextRequests.get(e$14.context); - void 0 === o$15 && this.pendingContextRequests.set(e$14.context, o$15 = { - callbacks: new WeakMap(), - requests: [] - }); - let n$13 = o$15.callbacks.get(t$7); - void 0 === n$13 && o$15.callbacks.set(t$7, n$13 = new WeakSet()), n$13.has(s$9) || (n$13.add(s$9), o$15.requests.push({ - elementRef: new WeakRef(t$7), - callbackRef: new WeakRef(s$9) - })); - }; - } - attach(e$14) { - e$14.addEventListener("context-request", this.onContextRequest), e$14.addEventListener("context-provider", this.onContextProvider); - } - detach(e$14) { - e$14.removeEventListener("context-request", this.onContextRequest), e$14.removeEventListener("context-provider", this.onContextProvider); - } -}; - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ function e$7({ context: e$14 }) { - return (n$13, i$10) => { - const r$12 = new WeakMap(); - if ("object" == typeof i$10) return { - get() { - return n$13.get.call(this); - }, - set(t$7) { - return r$12.get(this).setValue(t$7), n$13.set.call(this, t$7); - }, - init(n$14) { - return r$12.set(this, new i$3(this, { - context: e$14, - initialValue: n$14 - })), n$14; - } - }; - { - n$13.constructor.addInitializer(((n$14) => { - r$12.set(n$14, new i$3(n$14, { context: e$14 })); - })); - const o$15 = Object.getOwnPropertyDescriptor(n$13, i$10); - let s$9; - if (void 0 === o$15) { - const t$7 = new WeakMap(); - s$9 = { - get() { - return t$7.get(this); - }, - set(e$15) { - r$12.get(this).setValue(e$15), t$7.set(this, e$15); - }, - configurable: !0, - enumerable: !0 - }; - } else { - const t$7 = o$15.set; - s$9 = { - ...o$15, - set(e$15) { - r$12.get(this).setValue(e$15), t$7?.call(this, e$15); - } - }; - } - return void Object.defineProperty(n$13, i$10, s$9); - } - }; -} - -/** -* @license -* Copyright 2022 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ function c$1({ context: c$7, subscribe: e$14 }) { - return (o$15, n$13) => { - "object" == typeof n$13 ? n$13.addInitializer((function() { - new s$3(this, { - context: c$7, - callback: (t$7) => { - o$15.set.call(this, t$7); - }, - subscribe: e$14 - }); - })) : o$15.constructor.addInitializer(((o$16) => { - new s$3(o$16, { - context: c$7, - callback: (t$7) => { - o$16[n$13] = t$7; - }, - subscribe: e$14 - }); - })); - }; -} - -const eventInit = { - bubbles: true, - cancelable: true, - composed: true -}; -var StateEvent = class StateEvent extends CustomEvent { - static { - this.eventName = "a2uiaction"; - } - constructor(payload) { - super(StateEvent.eventName, { - detail: payload, - ...eventInit - }); - this.payload = payload; - } -}; - -const opacityBehavior = ` - &:not([disabled]) { - cursor: pointer; - opacity: var(--opacity, 0); - transition: opacity var(--speed, 0.2s) cubic-bezier(0, 0, 0.3, 1); - - &:hover, - &:focus { - opacity: 1; - } - }`; -const behavior = ` - ${new Array(21).fill(0).map((_$1, idx) => { - return `.behavior-ho-${idx * 5} { - --opacity: ${idx / 20}; - ${opacityBehavior} - }`; -}).join("\n")} - - .behavior-o-s { - overflow: scroll; - } - - .behavior-o-a { - overflow: auto; - } - - .behavior-o-h { - overflow: hidden; - } - - .behavior-sw-n { - scrollbar-width: none; - } -`; - -const grid = 4; - -const border = ` - ${new Array(25).fill(0).map((_$1, idx) => { - return ` - .border-bw-${idx} { border-width: ${idx}px; } - .border-btw-${idx} { border-top-width: ${idx}px; } - .border-bbw-${idx} { border-bottom-width: ${idx}px; } - .border-blw-${idx} { border-left-width: ${idx}px; } - .border-brw-${idx} { border-right-width: ${idx}px; } - - .border-ow-${idx} { outline-width: ${idx}px; } - .border-br-${idx} { border-radius: ${idx * grid}px; overflow: hidden;}`; -}).join("\n")} - - .border-br-50pc { - border-radius: 50%; - } - - .border-bs-s { - border-style: solid; - } -`; - -const shades = [ - 0, - 5, - 10, - 15, - 20, - 25, - 30, - 35, - 40, - 50, - 60, - 70, - 80, - 90, - 95, - 98, - 99, - 100 -]; - -function merge(...classes) { - const styles = {}; - for (const clazz of classes) { - for (const [key, val] of Object.entries(clazz)) { - const prefix = key.split("-").with(-1, "").join("-"); - const existingKeys = Object.keys(styles).filter((key$1) => key$1.startsWith(prefix)); - for (const existingKey of existingKeys) { - delete styles[existingKey]; - } - styles[key] = val; - } - } - return styles; -} -function appendToAll(target, exclusions, ...classes) { - const updatedTarget = structuredClone(target); - for (const clazz of classes) { - for (const key of Object.keys(clazz)) { - const prefix = key.split("-").with(-1, "").join("-"); - for (const [tagName, classesToAdd] of Object.entries(updatedTarget)) { - if (exclusions.includes(tagName)) { - continue; - } - let found = false; - for (let t$7 = 0; t$7 < classesToAdd.length; t$7++) { - if (classesToAdd[t$7].startsWith(prefix)) { - found = true; - classesToAdd[t$7] = key; - } - } - if (!found) { - classesToAdd.push(key); - } - } - } - } - return updatedTarget; -} -function createThemeStyles(palettes) { - const styles = {}; - for (const palette of Object.values(palettes)) { - for (const [key, val] of Object.entries(palette)) { - const prop = toProp(key); - styles[prop] = val; - } - } - return styles; -} -function toProp(key) { - if (key.startsWith("nv")) { - return `--nv-${key.slice(2)}`; - } - return `--${key[0]}-${key.slice(1)}`; -} - -const color = (src) => ` - ${src.map((key) => { - const inverseKey = getInverseKey(key); - return `.color-bc-${key} { border-color: light-dark(var(${toProp(key)}), var(${toProp(inverseKey)})); }`; -}).join("\n")} - - ${src.map((key) => { - const inverseKey = getInverseKey(key); - const vals = [`.color-bgc-${key} { background-color: light-dark(var(${toProp(key)}), var(${toProp(inverseKey)})); }`, `.color-bbgc-${key}::backdrop { background-color: light-dark(var(${toProp(key)}), var(${toProp(inverseKey)})); }`]; - for (let o$15 = .1; o$15 < 1; o$15 += .1) { - vals.push(`.color-bbgc-${key}_${(o$15 * 100).toFixed(0)}::backdrop { - background-color: light-dark(oklch(from var(${toProp(key)}) l c h / calc(alpha * ${o$15.toFixed(1)})), oklch(from var(${toProp(inverseKey)}) l c h / calc(alpha * ${o$15.toFixed(1)})) ); - } - `); - } - return vals.join("\n"); -}).join("\n")} - - ${src.map((key) => { - const inverseKey = getInverseKey(key); - return `.color-c-${key} { color: light-dark(var(${toProp(key)}), var(${toProp(inverseKey)})); }`; -}).join("\n")} - `; -const getInverseKey = (key) => { - const match = key.match(/^([a-z]+)(\d+)$/); - if (!match) return key; - const [, prefix, shadeStr] = match; - const shade = parseInt(shadeStr, 10); - const target = 100 - shade; - const inverseShade = shades.reduce((prev, curr) => Math.abs(curr - target) < Math.abs(prev - target) ? curr : prev); - return `${prefix}${inverseShade}`; -}; -const keyFactory = (prefix) => { - return shades.map((v$2) => `${prefix}${v$2}`); -}; -const colors = [ - color(keyFactory("p")), - color(keyFactory("s")), - color(keyFactory("t")), - color(keyFactory("n")), - color(keyFactory("nv")), - color(keyFactory("e")), - ` - .color-bgc-transparent { - background-color: transparent; - } - - :host { - color-scheme: var(--color-scheme); - } - ` -]; - -/** -* CSS classes for Google Symbols. -* -* Usage: -* -* ```html -* pen_spark -* ``` -*/ -const icons = ` - .g-icon { - font-family: "Material Symbols Outlined", "Google Symbols"; - font-weight: normal; - font-style: normal; - font-display: optional; - font-size: 20px; - width: 1em; - height: 1em; - user-select: none; - line-height: 1; - letter-spacing: normal; - text-transform: none; - display: inline-block; - white-space: nowrap; - word-wrap: normal; - direction: ltr; - -webkit-font-feature-settings: "liga"; - -webkit-font-smoothing: antialiased; - overflow: hidden; - - font-variation-settings: "FILL" 0, "wght" 300, "GRAD" 0, "opsz" 48, - "ROND" 100; - - &.filled { - font-variation-settings: "FILL" 1, "wght" 300, "GRAD" 0, "opsz" 48, - "ROND" 100; - } - - &.filled-heavy { - font-variation-settings: "FILL" 1, "wght" 700, "GRAD" 0, "opsz" 48, - "ROND" 100; - } - } -`; - -const layout = ` - :host { - ${new Array(16).fill(0).map((_$1, idx) => { - return `--g-${idx + 1}: ${(idx + 1) * grid}px;`; -}).join("\n")} - } - - ${new Array(49).fill(0).map((_$1, index) => { - const idx = index - 24; - const lbl = idx < 0 ? `n${Math.abs(idx)}` : idx.toString(); - return ` - .layout-p-${lbl} { --padding: ${idx * grid}px; padding: var(--padding); } - .layout-pt-${lbl} { padding-top: ${idx * grid}px; } - .layout-pr-${lbl} { padding-right: ${idx * grid}px; } - .layout-pb-${lbl} { padding-bottom: ${idx * grid}px; } - .layout-pl-${lbl} { padding-left: ${idx * grid}px; } - - .layout-m-${lbl} { --margin: ${idx * grid}px; margin: var(--margin); } - .layout-mt-${lbl} { margin-top: ${idx * grid}px; } - .layout-mr-${lbl} { margin-right: ${idx * grid}px; } - .layout-mb-${lbl} { margin-bottom: ${idx * grid}px; } - .layout-ml-${lbl} { margin-left: ${idx * grid}px; } - - .layout-t-${lbl} { top: ${idx * grid}px; } - .layout-r-${lbl} { right: ${idx * grid}px; } - .layout-b-${lbl} { bottom: ${idx * grid}px; } - .layout-l-${lbl} { left: ${idx * grid}px; }`; -}).join("\n")} - - ${new Array(25).fill(0).map((_$1, idx) => { - return ` - .layout-g-${idx} { gap: ${idx * grid}px; }`; -}).join("\n")} - - ${new Array(8).fill(0).map((_$1, idx) => { - return ` - .layout-grd-col${idx + 1} { grid-template-columns: ${"1fr ".repeat(idx + 1).trim()}; }`; -}).join("\n")} - - .layout-pos-a { - position: absolute; - } - - .layout-pos-rel { - position: relative; - } - - .layout-dsp-none { - display: none; - } - - .layout-dsp-block { - display: block; - } - - .layout-dsp-grid { - display: grid; - } - - .layout-dsp-iflex { - display: inline-flex; - } - - .layout-dsp-flexvert { - display: flex; - flex-direction: column; - } - - .layout-dsp-flexhor { - display: flex; - flex-direction: row; - } - - .layout-fw-w { - flex-wrap: wrap; - } - - .layout-al-fs { - align-items: start; - } - - .layout-al-fe { - align-items: end; - } - - .layout-al-c { - align-items: center; - } - - .layout-as-n { - align-self: normal; - } - - .layout-js-c { - justify-self: center; - } - - .layout-sp-c { - justify-content: center; - } - - .layout-sp-ev { - justify-content: space-evenly; - } - - .layout-sp-bt { - justify-content: space-between; - } - - .layout-sp-s { - justify-content: start; - } - - .layout-sp-e { - justify-content: end; - } - - .layout-ji-e { - justify-items: end; - } - - .layout-r-none { - resize: none; - } - - .layout-fs-c { - field-sizing: content; - } - - .layout-fs-n { - field-sizing: none; - } - - .layout-flx-0 { - flex: 0 0 auto; - } - - .layout-flx-1 { - flex: 1 0 auto; - } - - .layout-c-s { - contain: strict; - } - - /** Widths **/ - - ${new Array(10).fill(0).map((_$1, idx) => { - const weight = (idx + 1) * 10; - return `.layout-w-${weight} { width: ${weight}%; max-width: ${weight}%; }`; -}).join("\n")} - - ${new Array(16).fill(0).map((_$1, idx) => { - const weight = idx * grid; - return `.layout-wp-${idx} { width: ${weight}px; }`; -}).join("\n")} - - /** Heights **/ - - ${new Array(10).fill(0).map((_$1, idx) => { - const height = (idx + 1) * 10; - return `.layout-h-${height} { height: ${height}%; }`; -}).join("\n")} - - ${new Array(16).fill(0).map((_$1, idx) => { - const height = idx * grid; - return `.layout-hp-${idx} { height: ${height}px; }`; -}).join("\n")} - - .layout-el-cv { - & img, - & video { - width: 100%; - height: 100%; - object-fit: cover; - margin: 0; - } - } - - .layout-ar-sq { - aspect-ratio: 1 / 1; - } - - .layout-ex-fb { - margin: calc(var(--padding) * -1) 0 0 calc(var(--padding) * -1); - width: calc(100% + var(--padding) * 2); - height: calc(100% + var(--padding) * 2); - } -`; - -const opacity = ` - ${new Array(21).fill(0).map((_$1, idx) => { - return `.opacity-el-${idx * 5} { opacity: ${idx / 20}; }`; -}).join("\n")} -`; - -const type$1 = ` - :host { - --default-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - --default-font-family-mono: "Courier New", Courier, monospace; - } - - .typography-f-s { - font-family: var(--font-family, var(--default-font-family)); - font-optical-sizing: auto; - font-variation-settings: "slnt" 0, "wdth" 100, "GRAD" 0; - } - - .typography-f-sf { - font-family: var(--font-family-flex, var(--default-font-family)); - font-optical-sizing: auto; - } - - .typography-f-c { - font-family: var(--font-family-mono, var(--default-font-family)); - font-optical-sizing: auto; - font-variation-settings: "slnt" 0, "wdth" 100, "GRAD" 0; - } - - .typography-v-r { - font-variation-settings: "slnt" 0, "wdth" 100, "GRAD" 0, "ROND" 100; - } - - .typography-ta-s { - text-align: start; - } - - .typography-ta-c { - text-align: center; - } - - .typography-fs-n { - font-style: normal; - } - - .typography-fs-i { - font-style: italic; - } - - .typography-sz-ls { - font-size: 11px; - line-height: 16px; - } - - .typography-sz-lm { - font-size: 12px; - line-height: 16px; - } - - .typography-sz-ll { - font-size: 14px; - line-height: 20px; - } - - .typography-sz-bs { - font-size: 12px; - line-height: 16px; - } - - .typography-sz-bm { - font-size: 14px; - line-height: 20px; - } - - .typography-sz-bl { - font-size: 16px; - line-height: 24px; - } - - .typography-sz-ts { - font-size: 14px; - line-height: 20px; - } - - .typography-sz-tm { - font-size: 16px; - line-height: 24px; - } - - .typography-sz-tl { - font-size: 22px; - line-height: 28px; - } - - .typography-sz-hs { - font-size: 24px; - line-height: 32px; - } - - .typography-sz-hm { - font-size: 28px; - line-height: 36px; - } - - .typography-sz-hl { - font-size: 32px; - line-height: 40px; - } - - .typography-sz-ds { - font-size: 36px; - line-height: 44px; - } - - .typography-sz-dm { - font-size: 45px; - line-height: 52px; - } - - .typography-sz-dl { - font-size: 57px; - line-height: 64px; - } - - .typography-ws-p { - white-space: pre-line; - } - - .typography-ws-nw { - white-space: nowrap; - } - - .typography-td-none { - text-decoration: none; - } - - /** Weights **/ - - ${new Array(9).fill(0).map((_$1, idx) => { - const weight = (idx + 1) * 100; - return `.typography-w-${weight} { font-weight: ${weight}; }`; -}).join("\n")} -`; - -const structuralStyles$1 = [ - behavior, - border, - colors, - icons, - layout, - opacity, - type$1 -].flat(Infinity).join("\n"); - -var guards_exports = /* @__PURE__ */ __exportAll({ - isComponentArrayReference: () => isComponentArrayReference, - isObject: () => isObject$1, - isPath: () => isPath, - isResolvedAudioPlayer: () => isResolvedAudioPlayer, - isResolvedButton: () => isResolvedButton, - isResolvedCard: () => isResolvedCard, - isResolvedCheckbox: () => isResolvedCheckbox, - isResolvedColumn: () => isResolvedColumn, - isResolvedDateTimeInput: () => isResolvedDateTimeInput, - isResolvedDivider: () => isResolvedDivider, - isResolvedIcon: () => isResolvedIcon, - isResolvedImage: () => isResolvedImage, - isResolvedList: () => isResolvedList, - isResolvedModal: () => isResolvedModal, - isResolvedMultipleChoice: () => isResolvedMultipleChoice, - isResolvedRow: () => isResolvedRow, - isResolvedSlider: () => isResolvedSlider, - isResolvedTabs: () => isResolvedTabs, - isResolvedText: () => isResolvedText, - isResolvedTextField: () => isResolvedTextField, - isResolvedVideo: () => isResolvedVideo, - isValueMap: () => isValueMap -}); -function isValueMap(value) { - return isObject$1(value) && "key" in value; -} -function isPath(key, value) { - return key === "path" && typeof value === "string"; -} -function isObject$1(value) { - return typeof value === "object" && value !== null && !Array.isArray(value); -} -function isComponentArrayReference(value) { - if (!isObject$1(value)) return false; - return "explicitList" in value || "template" in value; -} -function isStringValue(value) { - return isObject$1(value) && ("path" in value || "literal" in value && typeof value.literal === "string" || "literalString" in value); -} -function isNumberValue(value) { - return isObject$1(value) && ("path" in value || "literal" in value && typeof value.literal === "number" || "literalNumber" in value); -} -function isBooleanValue(value) { - return isObject$1(value) && ("path" in value || "literal" in value && typeof value.literal === "boolean" || "literalBoolean" in value); -} -function isAnyComponentNode(value) { - if (!isObject$1(value)) return false; - const hasBaseKeys = "id" in value && "type" in value && "properties" in value; - if (!hasBaseKeys) return false; - return true; -} -function isResolvedAudioPlayer(props) { - return isObject$1(props) && "url" in props && isStringValue(props.url); -} -function isResolvedButton(props) { - return isObject$1(props) && "child" in props && isAnyComponentNode(props.child) && "action" in props; -} -function isResolvedCard(props) { - if (!isObject$1(props)) return false; - if (!("child" in props)) { - if (!("children" in props)) { - return false; - } else { - return Array.isArray(props.children) && props.children.every(isAnyComponentNode); - } - } - return isAnyComponentNode(props.child); -} -function isResolvedCheckbox(props) { - return isObject$1(props) && "label" in props && isStringValue(props.label) && "value" in props && isBooleanValue(props.value); -} -function isResolvedColumn(props) { - return isObject$1(props) && "children" in props && Array.isArray(props.children) && props.children.every(isAnyComponentNode); -} -function isResolvedDateTimeInput(props) { - return isObject$1(props) && "value" in props && isStringValue(props.value); -} -function isResolvedDivider(props) { - return isObject$1(props); -} -function isResolvedImage(props) { - return isObject$1(props) && "url" in props && isStringValue(props.url); -} -function isResolvedIcon(props) { - return isObject$1(props) && "name" in props && isStringValue(props.name); -} -function isResolvedList(props) { - return isObject$1(props) && "children" in props && Array.isArray(props.children) && props.children.every(isAnyComponentNode); -} -function isResolvedModal(props) { - return isObject$1(props) && "entryPointChild" in props && isAnyComponentNode(props.entryPointChild) && "contentChild" in props && isAnyComponentNode(props.contentChild); -} -function isResolvedMultipleChoice(props) { - return isObject$1(props) && "selections" in props; -} -function isResolvedRow(props) { - return isObject$1(props) && "children" in props && Array.isArray(props.children) && props.children.every(isAnyComponentNode); -} -function isResolvedSlider(props) { - return isObject$1(props) && "value" in props && isNumberValue(props.value); -} -function isResolvedTabItem(item) { - return isObject$1(item) && "title" in item && isStringValue(item.title) && "child" in item && isAnyComponentNode(item.child); -} -function isResolvedTabs(props) { - return isObject$1(props) && "tabItems" in props && Array.isArray(props.tabItems) && props.tabItems.every(isResolvedTabItem); -} -function isResolvedText(props) { - return isObject$1(props) && "text" in props && isStringValue(props.text); -} -function isResolvedTextField(props) { - return isObject$1(props) && "label" in props && isStringValue(props.label); -} -function isResolvedVideo(props) { - return isObject$1(props) && "url" in props && isStringValue(props.url); -} - -/** -* Processes and consolidates A2UIProtocolMessage objects into a structured, -* hierarchical model of UI surfaces. -*/ -var A2uiMessageProcessor = class A2uiMessageProcessor { - static { - this.DEFAULT_SURFACE_ID = "@default"; - } - #mapCtor = Map; - #arrayCtor = Array; - #setCtor = Set; - #objCtor = Object; - #surfaces; - constructor(opts = { - mapCtor: Map, - arrayCtor: Array, - setCtor: Set, - objCtor: Object - }) { - this.opts = opts; - this.#arrayCtor = opts.arrayCtor; - this.#mapCtor = opts.mapCtor; - this.#setCtor = opts.setCtor; - this.#objCtor = opts.objCtor; - this.#surfaces = new opts.mapCtor(); - } - getSurfaces() { - return this.#surfaces; - } - clearSurfaces() { - this.#surfaces.clear(); - } - processMessages(messages) { - for (const message of messages) { - if (message.beginRendering) { - this.#handleBeginRendering(message.beginRendering, message.beginRendering.surfaceId); - } - if (message.surfaceUpdate) { - this.#handleSurfaceUpdate(message.surfaceUpdate, message.surfaceUpdate.surfaceId); - } - if (message.dataModelUpdate) { - this.#handleDataModelUpdate(message.dataModelUpdate, message.dataModelUpdate.surfaceId); - } - if (message.deleteSurface) { - this.#handleDeleteSurface(message.deleteSurface); - } - } - } - /** - * Retrieves the data for a given component node and a relative path string. - * This correctly handles the special `.` path, which refers to the node's - * own data context. - */ - getData(node, relativePath, surfaceId = A2uiMessageProcessor.DEFAULT_SURFACE_ID) { - const surface = this.#getOrCreateSurface(surfaceId); - if (!surface) return null; - let finalPath; - if (relativePath === "." || relativePath === "") { - finalPath = node.dataContextPath ?? "/"; - } else { - finalPath = this.resolvePath(relativePath, node.dataContextPath); - } - return this.#getDataByPath(surface.dataModel, finalPath); - } - setData(node, relativePath, value, surfaceId = A2uiMessageProcessor.DEFAULT_SURFACE_ID) { - if (!node) { - console.warn("No component node set"); - return; - } - const surface = this.#getOrCreateSurface(surfaceId); - if (!surface) return; - let finalPath; - if (relativePath === "." || relativePath === "") { - finalPath = node.dataContextPath ?? "/"; - } else { - finalPath = this.resolvePath(relativePath, node.dataContextPath); - } - this.#setDataByPath(surface.dataModel, finalPath, value); - } - resolvePath(path, dataContextPath) { - if (path.startsWith("/")) { - return path; - } - if (dataContextPath && dataContextPath !== "/") { - return dataContextPath.endsWith("/") ? `${dataContextPath}${path}` : `${dataContextPath}/${path}`; - } - return `/${path}`; - } - #parseIfJsonString(value) { - if (typeof value !== "string") { - return value; - } - const trimmedValue = value.trim(); - if (trimmedValue.startsWith("{") && trimmedValue.endsWith("}") || trimmedValue.startsWith("[") && trimmedValue.endsWith("]")) { - try { - return JSON.parse(value); - } catch (e$14) { - console.warn(`Failed to parse potential JSON string: "${value.substring(0, 50)}..."`, e$14); - return value; - } - } - return value; - } - /** - * Converts a specific array format [{key: "...", value_string: "..."}, ...] - * into a standard Map. It also attempts to parse any string values that - * appear to be stringified JSON. - */ - #convertKeyValueArrayToMap(arr) { - const map$1 = new this.#mapCtor(); - for (const item of arr) { - if (!isObject$1(item) || !("key" in item)) continue; - const key = item.key; - const valueKey = this.#findValueKey(item); - if (!valueKey) continue; - let value = item[valueKey]; - if (valueKey === "valueMap" && Array.isArray(value)) { - value = this.#convertKeyValueArrayToMap(value); - } else if (typeof value === "string") { - value = this.#parseIfJsonString(value); - } - this.#setDataByPath(map$1, key, value); - } - return map$1; - } - #setDataByPath(root, path, value) { - if (Array.isArray(value) && (value.length === 0 || isObject$1(value[0]) && "key" in value[0])) { - if (value.length === 1 && isObject$1(value[0]) && value[0].key === ".") { - const item = value[0]; - const valueKey = this.#findValueKey(item); - if (valueKey) { - value = item[valueKey]; - if (valueKey === "valueMap" && Array.isArray(value)) { - value = this.#convertKeyValueArrayToMap(value); - } else if (typeof value === "string") { - value = this.#parseIfJsonString(value); - } - } else { - value = this.#convertKeyValueArrayToMap(value); - } - } else { - value = this.#convertKeyValueArrayToMap(value); - } - } - const segments = this.#normalizePath(path).split("/").filter((s$9) => s$9); - if (segments.length === 0) { - if (value instanceof Map || isObject$1(value)) { - if (!(value instanceof Map) && isObject$1(value)) { - value = new this.#mapCtor(Object.entries(value)); - } - root.clear(); - for (const [key, v$2] of value.entries()) { - root.set(key, v$2); - } - } else { - console.error("Cannot set root of DataModel to a non-Map value."); - } - return; - } - let current = root; - for (let i$10 = 0; i$10 < segments.length - 1; i$10++) { - const segment = segments[i$10]; - let target; - if (current instanceof Map) { - target = current.get(segment); - } else if (Array.isArray(current) && /^\d+$/.test(segment)) { - target = current[parseInt(segment, 10)]; - } - if (target === undefined || typeof target !== "object" || target === null) { - target = new this.#mapCtor(); - if (current instanceof this.#mapCtor) { - current.set(segment, target); - } else if (Array.isArray(current)) { - current[parseInt(segment, 10)] = target; - } - } - current = target; - } - const finalSegment = segments[segments.length - 1]; - const storedValue = value; - if (current instanceof this.#mapCtor) { - current.set(finalSegment, storedValue); - } else if (Array.isArray(current) && /^\d+$/.test(finalSegment)) { - current[parseInt(finalSegment, 10)] = storedValue; - } - } - /** - * Normalizes a path string into a consistent, slash-delimited format. - * Converts bracket notation and dot notation in a two-pass. - * e.g., "bookRecommendations[0].title" -> "/bookRecommendations/0/title" - * e.g., "book.0.title" -> "/book/0/title" - */ - #normalizePath(path) { - const dotPath = path.replace(/\[(\d+)\]/g, ".$1"); - const segments = dotPath.split("."); - return "/" + segments.filter((s$9) => s$9.length > 0).join("/"); - } - #getDataByPath(root, path) { - const segments = this.#normalizePath(path).split("/").filter((s$9) => s$9); - let current = root; - for (const segment of segments) { - if (current === undefined || current === null) return null; - if (current instanceof Map) { - current = current.get(segment); - } else if (Array.isArray(current) && /^\d+$/.test(segment)) { - current = current[parseInt(segment, 10)]; - } else if (isObject$1(current)) { - current = current[segment]; - } else { - return null; - } - } - return current; - } - #getOrCreateSurface(surfaceId) { - let surface = this.#surfaces.get(surfaceId); - if (!surface) { - surface = new this.#objCtor({ - rootComponentId: null, - componentTree: null, - dataModel: new this.#mapCtor(), - components: new this.#mapCtor(), - styles: new this.#objCtor() - }); - this.#surfaces.set(surfaceId, surface); - } - return surface; - } - #handleBeginRendering(message, surfaceId) { - const surface = this.#getOrCreateSurface(surfaceId); - surface.rootComponentId = message.root; - surface.styles = message.styles ?? {}; - this.#rebuildComponentTree(surface); - } - #handleSurfaceUpdate(message, surfaceId) { - const surface = this.#getOrCreateSurface(surfaceId); - for (const component of message.components) { - surface.components.set(component.id, component); - } - this.#rebuildComponentTree(surface); - } - #handleDataModelUpdate(message, surfaceId) { - const surface = this.#getOrCreateSurface(surfaceId); - const path = message.path ?? "/"; - this.#setDataByPath(surface.dataModel, path, message.contents); - this.#rebuildComponentTree(surface); - } - #handleDeleteSurface(message) { - this.#surfaces.delete(message.surfaceId); - } - /** - * Starts at the root component of the surface and builds out the tree - * recursively. This process involves resolving all properties of the child - * components, and expanding on any explicit children lists or templates - * found in the structure. - * - * @param surface The surface to be built. - */ - #rebuildComponentTree(surface) { - if (!surface.rootComponentId) { - surface.componentTree = null; - return; - } - const visited = new this.#setCtor(); - surface.componentTree = this.#buildNodeRecursive(surface.rootComponentId, surface, visited, "/", ""); - } - /** Finds a value key in a map. */ - #findValueKey(value) { - return Object.keys(value).find((k$1) => k$1.startsWith("value")); - } - /** - * Builds out the nodes recursively. - */ - #buildNodeRecursive(baseComponentId, surface, visited, dataContextPath, idSuffix = "") { - const fullId = `${baseComponentId}${idSuffix}`; - const { components } = surface; - if (!components.has(baseComponentId)) { - return null; - } - if (visited.has(fullId)) { - throw new Error(`Circular dependency for component "${fullId}".`); - } - visited.add(fullId); - const componentData = components.get(baseComponentId); - const componentProps = componentData.component ?? {}; - const componentType = Object.keys(componentProps)[0]; - const unresolvedProperties = componentProps[componentType]; - const resolvedProperties = new this.#objCtor(); - if (isObject$1(unresolvedProperties)) { - for (const [key, value] of Object.entries(unresolvedProperties)) { - resolvedProperties[key] = this.#resolvePropertyValue(value, surface, visited, dataContextPath, idSuffix, key); - } - } - visited.delete(fullId); - const baseNode = { - id: fullId, - dataContextPath, - weight: componentData.weight ?? "initial" - }; - switch (componentType) { - case "Text": - if (!isResolvedText(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Text", - properties: resolvedProperties - }); - case "Image": - if (!isResolvedImage(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Image", - properties: resolvedProperties - }); - case "Icon": - if (!isResolvedIcon(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Icon", - properties: resolvedProperties - }); - case "Video": - if (!isResolvedVideo(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Video", - properties: resolvedProperties - }); - case "AudioPlayer": - if (!isResolvedAudioPlayer(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "AudioPlayer", - properties: resolvedProperties - }); - case "Row": - if (!isResolvedRow(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Row", - properties: resolvedProperties - }); - case "Column": - if (!isResolvedColumn(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Column", - properties: resolvedProperties - }); - case "List": - if (!isResolvedList(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "List", - properties: resolvedProperties - }); - case "Card": - if (!isResolvedCard(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Card", - properties: resolvedProperties - }); - case "Tabs": - if (!isResolvedTabs(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Tabs", - properties: resolvedProperties - }); - case "Divider": - if (!isResolvedDivider(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Divider", - properties: resolvedProperties - }); - case "Modal": - if (!isResolvedModal(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Modal", - properties: resolvedProperties - }); - case "Button": - if (!isResolvedButton(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Button", - properties: resolvedProperties - }); - case "CheckBox": - if (!isResolvedCheckbox(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "CheckBox", - properties: resolvedProperties - }); - case "TextField": - if (!isResolvedTextField(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "TextField", - properties: resolvedProperties - }); - case "DateTimeInput": - if (!isResolvedDateTimeInput(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "DateTimeInput", - properties: resolvedProperties - }); - case "MultipleChoice": - if (!isResolvedMultipleChoice(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "MultipleChoice", - properties: resolvedProperties - }); - case "Slider": - if (!isResolvedSlider(resolvedProperties)) { - throw new Error(`Invalid data; expected ${componentType}`); - } - return new this.#objCtor({ - ...baseNode, - type: "Slider", - properties: resolvedProperties - }); - default: return new this.#objCtor({ - ...baseNode, - type: componentType, - properties: resolvedProperties - }); - } - } - /** - * Recursively resolves an individual property value. If a property indicates - * a child node (a string that matches a component ID), an explicitList of - * children, or a template, these will be built out here. - */ - #resolvePropertyValue(value, surface, visited, dataContextPath, idSuffix = "", propertyKey = null) { - const isComponentIdReferenceKey = (key) => key === "child" || key.endsWith("Child"); - if (typeof value === "string" && propertyKey && isComponentIdReferenceKey(propertyKey) && surface.components.has(value)) { - return this.#buildNodeRecursive(value, surface, visited, dataContextPath, idSuffix); - } - if (isComponentArrayReference(value)) { - if (value.explicitList) { - return value.explicitList.map((id) => this.#buildNodeRecursive(id, surface, visited, dataContextPath, idSuffix)); - } - if (value.template) { - const fullDataPath = this.resolvePath(value.template.dataBinding, dataContextPath); - const data = this.#getDataByPath(surface.dataModel, fullDataPath); - const template = value.template; - if (Array.isArray(data)) { - return data.map((_$1, index) => { - const parentIndices = dataContextPath.split("/").filter((segment) => /^\d+$/.test(segment)); - const newIndices = [...parentIndices, index]; - const newSuffix = `:${newIndices.join(":")}`; - const childDataContextPath = `${fullDataPath}/${index}`; - return this.#buildNodeRecursive(template.componentId, surface, visited, childDataContextPath, newSuffix); - }); - } - const mapCtor = this.#mapCtor; - if (data instanceof mapCtor) { - return Array.from(data.keys(), (key) => { - const newSuffix = `:${key}`; - const childDataContextPath = `${fullDataPath}/${key}`; - return this.#buildNodeRecursive(template.componentId, surface, visited, childDataContextPath, newSuffix); - }); - } - return new this.#arrayCtor(); - } - } - if (Array.isArray(value)) { - return value.map((item) => this.#resolvePropertyValue(item, surface, visited, dataContextPath, idSuffix, propertyKey)); - } - if (isObject$1(value)) { - const newObj = new this.#objCtor(); - for (const [key, propValue] of Object.entries(value)) { - let propertyValue = propValue; - if (isPath(key, propValue) && dataContextPath !== "/") { - propertyValue = propValue.replace(/^\.?\/item/, "").replace(/^\.?\/text/, "").replace(/^\.?\/label/, "").replace(/^\.?\//, ""); - newObj[key] = propertyValue; - continue; - } - newObj[key] = this.#resolvePropertyValue(propertyValue, surface, visited, dataContextPath, idSuffix, key); - } - return newObj; - } - return value; - } -}; - -var __defProp = Object.defineProperty; -var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { - enumerable: true, - configurable: true, - writable: true, - value -}) : obj[key] = value; -var __publicField = (obj, key, value) => { - __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); - return value; -}; -var __accessCheck = (obj, member, msg) => { - if (!member.has(obj)) throw TypeError("Cannot " + msg); -}; -var __privateIn = (member, obj) => { - if (Object(obj) !== obj) throw TypeError("Cannot use the \"in\" operator on this value"); - return member.has(obj); -}; -var __privateAdd = (obj, member, value) => { - if (member.has(obj)) throw TypeError("Cannot add the same private member more than once"); - member instanceof WeakSet ? member.add(obj) : member.set(obj, value); -}; -var __privateMethod = (obj, member, method) => { - __accessCheck(obj, member, "access private method"); - return method; -}; -/** -* @license -* Copyright Google LLC All Rights Reserved. -* -* Use of this source code is governed by an MIT-style license that can be -* found in the LICENSE file at https://angular.io/license -*/ -function defaultEquals(a$2, b$2) { - return Object.is(a$2, b$2); -} -/** -* @license -* Copyright Google LLC All Rights Reserved. -* -* Use of this source code is governed by an MIT-style license that can be -* found in the LICENSE file at https://angular.io/license -*/ -let activeConsumer = null; -let inNotificationPhase = false; -let epoch = 1; -const SIGNAL = /* @__PURE__ */ Symbol("SIGNAL"); -function setActiveConsumer(consumer) { - const prev = activeConsumer; - activeConsumer = consumer; - return prev; -} -function getActiveConsumer() { - return activeConsumer; -} -function isInNotificationPhase() { - return inNotificationPhase; -} -const REACTIVE_NODE = { - version: 0, - lastCleanEpoch: 0, - dirty: false, - producerNode: void 0, - producerLastReadVersion: void 0, - producerIndexOfThis: void 0, - nextProducerIndex: 0, - liveConsumerNode: void 0, - liveConsumerIndexOfThis: void 0, - consumerAllowSignalWrites: false, - consumerIsAlwaysLive: false, - producerMustRecompute: () => false, - producerRecomputeValue: () => {}, - consumerMarkedDirty: () => {}, - consumerOnSignalRead: () => {} -}; -function producerAccessed(node) { - if (inNotificationPhase) { - throw new Error(typeof ngDevMode !== "undefined" && ngDevMode ? `Assertion error: signal read during notification phase` : ""); - } - if (activeConsumer === null) { - return; - } - activeConsumer.consumerOnSignalRead(node); - const idx = activeConsumer.nextProducerIndex++; - assertConsumerNode(activeConsumer); - if (idx < activeConsumer.producerNode.length && activeConsumer.producerNode[idx] !== node) { - if (consumerIsLive(activeConsumer)) { - const staleProducer = activeConsumer.producerNode[idx]; - producerRemoveLiveConsumerAtIndex(staleProducer, activeConsumer.producerIndexOfThis[idx]); - } - } - if (activeConsumer.producerNode[idx] !== node) { - activeConsumer.producerNode[idx] = node; - activeConsumer.producerIndexOfThis[idx] = consumerIsLive(activeConsumer) ? producerAddLiveConsumer(node, activeConsumer, idx) : 0; - } - activeConsumer.producerLastReadVersion[idx] = node.version; -} -function producerIncrementEpoch() { - epoch++; -} -function producerUpdateValueVersion(node) { - if (!node.dirty && node.lastCleanEpoch === epoch) { - return; - } - if (!node.producerMustRecompute(node) && !consumerPollProducersForChange(node)) { - node.dirty = false; - node.lastCleanEpoch = epoch; - return; - } - node.producerRecomputeValue(node); - node.dirty = false; - node.lastCleanEpoch = epoch; -} -function producerNotifyConsumers(node) { - if (node.liveConsumerNode === void 0) { - return; - } - const prev = inNotificationPhase; - inNotificationPhase = true; - try { - for (const consumer of node.liveConsumerNode) { - if (!consumer.dirty) { - consumerMarkDirty(consumer); - } - } - } finally { - inNotificationPhase = prev; - } -} -function producerUpdatesAllowed() { - return (activeConsumer == null ? void 0 : activeConsumer.consumerAllowSignalWrites) !== false; -} -function consumerMarkDirty(node) { - var _a$1; - node.dirty = true; - producerNotifyConsumers(node); - (_a$1 = node.consumerMarkedDirty) == null ? void 0 : _a$1.call(node.wrapper ?? node); -} -function consumerBeforeComputation(node) { - node && (node.nextProducerIndex = 0); - return setActiveConsumer(node); -} -function consumerAfterComputation(node, prevConsumer) { - setActiveConsumer(prevConsumer); - if (!node || node.producerNode === void 0 || node.producerIndexOfThis === void 0 || node.producerLastReadVersion === void 0) { - return; - } - if (consumerIsLive(node)) { - for (let i$10 = node.nextProducerIndex; i$10 < node.producerNode.length; i$10++) { - producerRemoveLiveConsumerAtIndex(node.producerNode[i$10], node.producerIndexOfThis[i$10]); - } - } - while (node.producerNode.length > node.nextProducerIndex) { - node.producerNode.pop(); - node.producerLastReadVersion.pop(); - node.producerIndexOfThis.pop(); - } -} -function consumerPollProducersForChange(node) { - assertConsumerNode(node); - for (let i$10 = 0; i$10 < node.producerNode.length; i$10++) { - const producer = node.producerNode[i$10]; - const seenVersion = node.producerLastReadVersion[i$10]; - if (seenVersion !== producer.version) { - return true; - } - producerUpdateValueVersion(producer); - if (seenVersion !== producer.version) { - return true; - } - } - return false; -} -function producerAddLiveConsumer(node, consumer, indexOfThis) { - var _a$1; - assertProducerNode(node); - assertConsumerNode(node); - if (node.liveConsumerNode.length === 0) { - (_a$1 = node.watched) == null ? void 0 : _a$1.call(node.wrapper); - for (let i$10 = 0; i$10 < node.producerNode.length; i$10++) { - node.producerIndexOfThis[i$10] = producerAddLiveConsumer(node.producerNode[i$10], node, i$10); - } - } - node.liveConsumerIndexOfThis.push(indexOfThis); - return node.liveConsumerNode.push(consumer) - 1; -} -function producerRemoveLiveConsumerAtIndex(node, idx) { - var _a$1; - assertProducerNode(node); - assertConsumerNode(node); - if (typeof ngDevMode !== "undefined" && ngDevMode && idx >= node.liveConsumerNode.length) { - throw new Error(`Assertion error: active consumer index ${idx} is out of bounds of ${node.liveConsumerNode.length} consumers)`); - } - if (node.liveConsumerNode.length === 1) { - (_a$1 = node.unwatched) == null ? void 0 : _a$1.call(node.wrapper); - for (let i$10 = 0; i$10 < node.producerNode.length; i$10++) { - producerRemoveLiveConsumerAtIndex(node.producerNode[i$10], node.producerIndexOfThis[i$10]); - } - } - const lastIdx = node.liveConsumerNode.length - 1; - node.liveConsumerNode[idx] = node.liveConsumerNode[lastIdx]; - node.liveConsumerIndexOfThis[idx] = node.liveConsumerIndexOfThis[lastIdx]; - node.liveConsumerNode.length--; - node.liveConsumerIndexOfThis.length--; - if (idx < node.liveConsumerNode.length) { - const idxProducer = node.liveConsumerIndexOfThis[idx]; - const consumer = node.liveConsumerNode[idx]; - assertConsumerNode(consumer); - consumer.producerIndexOfThis[idxProducer] = idx; - } -} -function consumerIsLive(node) { - var _a$1; - return node.consumerIsAlwaysLive || (((_a$1 = node == null ? void 0 : node.liveConsumerNode) == null ? void 0 : _a$1.length) ?? 0) > 0; -} -function assertConsumerNode(node) { - node.producerNode ?? (node.producerNode = []); - node.producerIndexOfThis ?? (node.producerIndexOfThis = []); - node.producerLastReadVersion ?? (node.producerLastReadVersion = []); -} -function assertProducerNode(node) { - node.liveConsumerNode ?? (node.liveConsumerNode = []); - node.liveConsumerIndexOfThis ?? (node.liveConsumerIndexOfThis = []); -} -/** -* @license -* Copyright Google LLC All Rights Reserved. -* -* Use of this source code is governed by an MIT-style license that can be -* found in the LICENSE file at https://angular.io/license -*/ -function computedGet(node) { - producerUpdateValueVersion(node); - producerAccessed(node); - if (node.value === ERRORED) { - throw node.error; - } - return node.value; -} -function createComputed(computation) { - const node = Object.create(COMPUTED_NODE); - node.computation = computation; - const computed = () => computedGet(node); - computed[SIGNAL] = node; - return computed; -} -const UNSET = /* @__PURE__ */ Symbol("UNSET"); -const COMPUTING = /* @__PURE__ */ Symbol("COMPUTING"); -const ERRORED = /* @__PURE__ */ Symbol("ERRORED"); -const COMPUTED_NODE = /* @__PURE__ */ (() => { - return { - ...REACTIVE_NODE, - value: UNSET, - dirty: true, - error: null, - equal: defaultEquals, - producerMustRecompute(node) { - return node.value === UNSET || node.value === COMPUTING; - }, - producerRecomputeValue(node) { - if (node.value === COMPUTING) { - throw new Error("Detected cycle in computations."); - } - const oldValue = node.value; - node.value = COMPUTING; - const prevConsumer = consumerBeforeComputation(node); - let newValue; - let wasEqual = false; - try { - newValue = node.computation.call(node.wrapper); - const oldOk = oldValue !== UNSET && oldValue !== ERRORED; - wasEqual = oldOk && node.equal.call(node.wrapper, oldValue, newValue); - } catch (err) { - newValue = ERRORED; - node.error = err; - } finally { - consumerAfterComputation(node, prevConsumer); - } - if (wasEqual) { - node.value = oldValue; - return; - } - node.value = newValue; - node.version++; - } - }; -})(); -/** -* @license -* Copyright Google LLC All Rights Reserved. -* -* Use of this source code is governed by an MIT-style license that can be -* found in the LICENSE file at https://angular.io/license -*/ -function defaultThrowError() { - throw new Error(); -} -let throwInvalidWriteToSignalErrorFn = defaultThrowError; -function throwInvalidWriteToSignalError() { - throwInvalidWriteToSignalErrorFn(); -} -/** -* @license -* Copyright Google LLC All Rights Reserved. -* -* Use of this source code is governed by an MIT-style license that can be -* found in the LICENSE file at https://angular.io/license -*/ -function createSignal(initialValue) { - const node = Object.create(SIGNAL_NODE); - node.value = initialValue; - const getter = () => { - producerAccessed(node); - return node.value; - }; - getter[SIGNAL] = node; - return getter; -} -function signalGetFn() { - producerAccessed(this); - return this.value; -} -function signalSetFn(node, newValue) { - if (!producerUpdatesAllowed()) { - throwInvalidWriteToSignalError(); - } - if (!node.equal.call(node.wrapper, node.value, newValue)) { - node.value = newValue; - signalValueChanged(node); - } -} -const SIGNAL_NODE = /* @__PURE__ */ (() => { - return { - ...REACTIVE_NODE, - equal: defaultEquals, - value: void 0 - }; -})(); -function signalValueChanged(node) { - node.version++; - producerIncrementEpoch(); - producerNotifyConsumers(node); -} -/** -* @license -* Copyright 2024 Bloomberg Finance L.P. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -const NODE = Symbol("node"); -var Signal; -((Signal2) => { - var _a$1, _brand, brand_fn, _b, _brand2, brand_fn2; - class State { - constructor(initialValue, options = {}) { - __privateAdd(this, _brand); - __publicField(this, _a$1); - const ref = createSignal(initialValue); - const node = ref[SIGNAL]; - this[NODE] = node; - node.wrapper = this; - if (options) { - const equals = options.equals; - if (equals) { - node.equal = equals; - } - node.watched = options[Signal2.subtle.watched]; - node.unwatched = options[Signal2.subtle.unwatched]; - } - } - get() { - if (!(0, Signal2.isState)(this)) throw new TypeError("Wrong receiver type for Signal.State.prototype.get"); - return signalGetFn.call(this[NODE]); - } - set(newValue) { - if (!(0, Signal2.isState)(this)) throw new TypeError("Wrong receiver type for Signal.State.prototype.set"); - if (isInNotificationPhase()) { - throw new Error("Writes to signals not permitted during Watcher callback"); - } - const ref = this[NODE]; - signalSetFn(ref, newValue); - } - } - _a$1 = NODE; - _brand = new WeakSet(); - brand_fn = function() {}; - Signal2.isState = (s$9) => typeof s$9 === "object" && __privateIn(_brand, s$9); - Signal2.State = State; - class Computed { - constructor(computation, options) { - __privateAdd(this, _brand2); - __publicField(this, _b); - const ref = createComputed(computation); - const node = ref[SIGNAL]; - node.consumerAllowSignalWrites = true; - this[NODE] = node; - node.wrapper = this; - if (options) { - const equals = options.equals; - if (equals) { - node.equal = equals; - } - node.watched = options[Signal2.subtle.watched]; - node.unwatched = options[Signal2.subtle.unwatched]; - } - } - get() { - if (!(0, Signal2.isComputed)(this)) throw new TypeError("Wrong receiver type for Signal.Computed.prototype.get"); - return computedGet(this[NODE]); - } - } - _b = NODE; - _brand2 = new WeakSet(); - brand_fn2 = function() {}; - Signal2.isComputed = (c$7) => typeof c$7 === "object" && __privateIn(_brand2, c$7); - Signal2.Computed = Computed; - ((subtle2) => { - var _a2, _brand3, brand_fn3, _assertSignals, assertSignals_fn; - function untrack(cb) { - let output; - let prevActiveConsumer = null; - try { - prevActiveConsumer = setActiveConsumer(null); - output = cb(); - } finally { - setActiveConsumer(prevActiveConsumer); - } - return output; - } - subtle2.untrack = untrack; - function introspectSources(sink) { - var _a3; - if (!(0, Signal2.isComputed)(sink) && !(0, Signal2.isWatcher)(sink)) { - throw new TypeError("Called introspectSources without a Computed or Watcher argument"); - } - return ((_a3 = sink[NODE].producerNode) == null ? void 0 : _a3.map((n$13) => n$13.wrapper)) ?? []; - } - subtle2.introspectSources = introspectSources; - function introspectSinks(signal) { - var _a3; - if (!(0, Signal2.isComputed)(signal) && !(0, Signal2.isState)(signal)) { - throw new TypeError("Called introspectSinks without a Signal argument"); - } - return ((_a3 = signal[NODE].liveConsumerNode) == null ? void 0 : _a3.map((n$13) => n$13.wrapper)) ?? []; - } - subtle2.introspectSinks = introspectSinks; - function hasSinks(signal) { - if (!(0, Signal2.isComputed)(signal) && !(0, Signal2.isState)(signal)) { - throw new TypeError("Called hasSinks without a Signal argument"); - } - const liveConsumerNode = signal[NODE].liveConsumerNode; - if (!liveConsumerNode) return false; - return liveConsumerNode.length > 0; - } - subtle2.hasSinks = hasSinks; - function hasSources(signal) { - if (!(0, Signal2.isComputed)(signal) && !(0, Signal2.isWatcher)(signal)) { - throw new TypeError("Called hasSources without a Computed or Watcher argument"); - } - const producerNode = signal[NODE].producerNode; - if (!producerNode) return false; - return producerNode.length > 0; - } - subtle2.hasSources = hasSources; - class Watcher { - constructor(notify) { - __privateAdd(this, _brand3); - __privateAdd(this, _assertSignals); - __publicField(this, _a2); - let node = Object.create(REACTIVE_NODE); - node.wrapper = this; - node.consumerMarkedDirty = notify; - node.consumerIsAlwaysLive = true; - node.consumerAllowSignalWrites = false; - node.producerNode = []; - this[NODE] = node; - } - watch(...signals) { - if (!(0, Signal2.isWatcher)(this)) { - throw new TypeError("Called unwatch without Watcher receiver"); - } - __privateMethod(this, _assertSignals, assertSignals_fn).call(this, signals); - const node = this[NODE]; - node.dirty = false; - const prev = setActiveConsumer(node); - for (const signal of signals) { - producerAccessed(signal[NODE]); - } - setActiveConsumer(prev); - } - unwatch(...signals) { - if (!(0, Signal2.isWatcher)(this)) { - throw new TypeError("Called unwatch without Watcher receiver"); - } - __privateMethod(this, _assertSignals, assertSignals_fn).call(this, signals); - const node = this[NODE]; - assertConsumerNode(node); - for (let i$10 = node.producerNode.length - 1; i$10 >= 0; i$10--) { - if (signals.includes(node.producerNode[i$10].wrapper)) { - producerRemoveLiveConsumerAtIndex(node.producerNode[i$10], node.producerIndexOfThis[i$10]); - const lastIdx = node.producerNode.length - 1; - node.producerNode[i$10] = node.producerNode[lastIdx]; - node.producerIndexOfThis[i$10] = node.producerIndexOfThis[lastIdx]; - node.producerNode.length--; - node.producerIndexOfThis.length--; - node.nextProducerIndex--; - if (i$10 < node.producerNode.length) { - const idxConsumer = node.producerIndexOfThis[i$10]; - const producer = node.producerNode[i$10]; - assertProducerNode(producer); - producer.liveConsumerIndexOfThis[idxConsumer] = i$10; - } - } - } - } - getPending() { - if (!(0, Signal2.isWatcher)(this)) { - throw new TypeError("Called getPending without Watcher receiver"); - } - const node = this[NODE]; - return node.producerNode.filter((n$13) => n$13.dirty).map((n$13) => n$13.wrapper); - } - } - _a2 = NODE; - _brand3 = new WeakSet(); - brand_fn3 = function() {}; - _assertSignals = new WeakSet(); - assertSignals_fn = function(signals) { - for (const signal of signals) { - if (!(0, Signal2.isComputed)(signal) && !(0, Signal2.isState)(signal)) { - throw new TypeError("Called watch/unwatch without a Computed or State argument"); - } - } - }; - Signal2.isWatcher = (w$1) => __privateIn(_brand3, w$1); - subtle2.Watcher = Watcher; - function currentComputed() { - var _a3; - return (_a3 = getActiveConsumer()) == null ? void 0 : _a3.wrapper; - } - subtle2.currentComputed = currentComputed; - subtle2.watched = Symbol("watched"); - subtle2.unwatched = Symbol("unwatched"); - })(Signal2.subtle || (Signal2.subtle = {})); -})(Signal || (Signal = {})); - -/** -* equality check here is always false so that we can dirty the storage -* via setting to _anything_ -* -* -* This is for a pattern where we don't *directly* use signals to back the values used in collections -* so that instanceof checks and getters and other native features "just work" without having -* to do nested proxying. -* -* (though, see deep.ts for nested / deep behavior) -*/ -const createStorage = (initial = null) => new Signal.State(initial, { equals: () => false }); -/** -* Just an alias for brevity -*/ -const BOUND_FUNS = new WeakMap(); -function fnCacheFor(context) { - let fnCache = BOUND_FUNS.get(context); - if (!fnCache) { - fnCache = new Map(); - BOUND_FUNS.set(context, fnCache); - } - return fnCache; -} - -const ARRAY_GETTER_METHODS = new Set([ - Symbol.iterator, - "concat", - "entries", - "every", - "filter", - "find", - "findIndex", - "flat", - "flatMap", - "forEach", - "includes", - "indexOf", - "join", - "keys", - "lastIndexOf", - "map", - "reduce", - "reduceRight", - "slice", - "some", - "values" -]); -const ARRAY_WRITE_THEN_READ_METHODS = new Set([ - "fill", - "push", - "unshift" -]); -function convertToInt(prop) { - if (typeof prop === "symbol") return null; - const num = Number(prop); - if (isNaN(num)) return null; - return num % 1 === 0 ? num : null; -} -var SignalArray = class SignalArray { - /** - * Creates an array from an iterable object. - * @param iterable An iterable object to convert to an array. - */ - /** - * Creates an array from an iterable object. - * @param iterable An iterable object to convert to an array. - * @param mapfn A mapping function to call on every element of the array. - * @param thisArg Value of 'this' used to invoke the mapfn. - */ - static from(iterable, mapfn, thisArg) { - return mapfn ? new SignalArray(Array.from(iterable, mapfn, thisArg)) : new SignalArray(Array.from(iterable)); - } - static of(...arr) { - return new SignalArray(arr); - } - constructor(arr = []) { - let clone = arr.slice(); - let self = this; - let boundFns = new Map(); - /** - Flag to track whether we have *just* intercepted a call to `.push()` or - `.unshift()`, since in those cases (and only those cases!) the `Array` - itself checks `.length` to return from the function call. - */ - let nativelyAccessingLengthFromPushOrUnshift = false; - return new Proxy(clone, { - get(target, prop) { - let index = convertToInt(prop); - if (index !== null) { - self.#readStorageFor(index); - self.#collection.get(); - return target[index]; - } - if (prop === "length") { - if (nativelyAccessingLengthFromPushOrUnshift) { - nativelyAccessingLengthFromPushOrUnshift = false; - } else { - self.#collection.get(); - } - return target[prop]; - } - if (ARRAY_WRITE_THEN_READ_METHODS.has(prop)) { - nativelyAccessingLengthFromPushOrUnshift = true; - } - if (ARRAY_GETTER_METHODS.has(prop)) { - let fn = boundFns.get(prop); - if (fn === undefined) { - fn = (...args) => { - self.#collection.get(); - return target[prop](...args); - }; - boundFns.set(prop, fn); - } - return fn; - } - return target[prop]; - }, - set(target, prop, value) { - target[prop] = value; - let index = convertToInt(prop); - if (index !== null) { - self.#dirtyStorageFor(index); - self.#collection.set(null); - } else if (prop === "length") { - self.#collection.set(null); - } - return true; - }, - getPrototypeOf() { - return SignalArray.prototype; - } - }); - } - #collection = createStorage(); - #storages = new Map(); - #readStorageFor(index) { - let storage = this.#storages.get(index); - if (storage === undefined) { - storage = createStorage(); - this.#storages.set(index, storage); - } - storage.get(); - } - #dirtyStorageFor(index) { - const storage = this.#storages.get(index); - if (storage) { - storage.set(null); - } - } -}; -Object.setPrototypeOf(SignalArray.prototype, Array.prototype); -function signalArray(x$1) { - return new SignalArray(x$1); -} - -var SignalMap = class { - collection = createStorage(); - storages = new Map(); - vals; - readStorageFor(key) { - const { storages } = this; - let storage = storages.get(key); - if (storage === undefined) { - storage = createStorage(); - storages.set(key, storage); - } - storage.get(); - } - dirtyStorageFor(key) { - const storage = this.storages.get(key); - if (storage) { - storage.set(null); - } - } - constructor(existing) { - this.vals = existing ? new Map(existing) : new Map(); - } - get(key) { - this.readStorageFor(key); - return this.vals.get(key); - } - has(key) { - this.readStorageFor(key); - return this.vals.has(key); - } - entries() { - this.collection.get(); - return this.vals.entries(); - } - keys() { - this.collection.get(); - return this.vals.keys(); - } - values() { - this.collection.get(); - return this.vals.values(); - } - forEach(fn) { - this.collection.get(); - this.vals.forEach(fn); - } - get size() { - this.collection.get(); - return this.vals.size; - } - [Symbol.iterator]() { - this.collection.get(); - return this.vals[Symbol.iterator](); - } - get [Symbol.toStringTag]() { - return this.vals[Symbol.toStringTag]; - } - set(key, value) { - this.dirtyStorageFor(key); - this.collection.set(null); - this.vals.set(key, value); - return this; - } - delete(key) { - this.dirtyStorageFor(key); - this.collection.set(null); - return this.vals.delete(key); - } - clear() { - this.storages.forEach((s$9) => s$9.set(null)); - this.collection.set(null); - this.vals.clear(); - } -}; -Object.setPrototypeOf(SignalMap.prototype, Map.prototype); - -/** -* Implementation based of tracked-built-ins' TrackedObject -* https://github.com/tracked-tools/tracked-built-ins/blob/master/addon/src/-private/object.js -*/ -var SignalObjectImpl = class SignalObjectImpl { - static fromEntries(entries) { - return new SignalObjectImpl(Object.fromEntries(entries)); - } - #storages = new Map(); - #collection = createStorage(); - constructor(obj = {}) { - let proto = Object.getPrototypeOf(obj); - let descs = Object.getOwnPropertyDescriptors(obj); - let clone = Object.create(proto); - for (let prop in descs) { - Object.defineProperty(clone, prop, descs[prop]); - } - let self = this; - return new Proxy(clone, { - get(target, prop, receiver) { - self.#readStorageFor(prop); - return Reflect.get(target, prop, receiver); - }, - has(target, prop) { - self.#readStorageFor(prop); - return prop in target; - }, - ownKeys(target) { - self.#collection.get(); - return Reflect.ownKeys(target); - }, - set(target, prop, value, receiver) { - let result = Reflect.set(target, prop, value, receiver); - self.#dirtyStorageFor(prop); - self.#dirtyCollection(); - return result; - }, - deleteProperty(target, prop) { - if (prop in target) { - delete target[prop]; - self.#dirtyStorageFor(prop); - self.#dirtyCollection(); - } - return true; - }, - getPrototypeOf() { - return SignalObjectImpl.prototype; - } - }); - } - #readStorageFor(key) { - let storage = this.#storages.get(key); - if (storage === undefined) { - storage = createStorage(); - this.#storages.set(key, storage); - } - storage.get(); - } - #dirtyStorageFor(key) { - const storage = this.#storages.get(key); - if (storage) { - storage.set(null); - } - } - #dirtyCollection() { - this.#collection.set(null); - } -}; -/** -* Create a reactive Object, backed by Signals, using a Proxy. -* This allows dynamic creation and deletion of signals using the object primitive -* APIs that most folks are familiar with -- the only difference is instantiation. -* ```js -* const obj = new SignalObject({ foo: 123 }); -* -* obj.foo // 123 -* obj.foo = 456 -* obj.foo // 456 -* obj.bar = 2 -* obj.bar // 2 -* ``` -*/ -const SignalObject = SignalObjectImpl; -function signalObject(obj) { - return new SignalObject(obj); -} - -var SignalSet = class { - collection = createStorage(); - storages = new Map(); - vals; - storageFor(key) { - const storages = this.storages; - let storage = storages.get(key); - if (storage === undefined) { - storage = createStorage(); - storages.set(key, storage); - } - return storage; - } - dirtyStorageFor(key) { - const storage = this.storages.get(key); - if (storage) { - storage.set(null); - } - } - constructor(existing) { - this.vals = new Set(existing); - } - has(value) { - this.storageFor(value).get(); - return this.vals.has(value); - } - entries() { - this.collection.get(); - return this.vals.entries(); - } - keys() { - this.collection.get(); - return this.vals.keys(); - } - values() { - this.collection.get(); - return this.vals.values(); - } - forEach(fn) { - this.collection.get(); - this.vals.forEach(fn); - } - get size() { - this.collection.get(); - return this.vals.size; - } - [Symbol.iterator]() { - this.collection.get(); - return this.vals[Symbol.iterator](); - } - get [Symbol.toStringTag]() { - return this.vals[Symbol.toStringTag]; - } - add(value) { - this.dirtyStorageFor(value); - this.collection.set(null); - this.vals.add(value); - return this; - } - delete(value) { - this.dirtyStorageFor(value); - this.collection.set(null); - return this.vals.delete(value); - } - clear() { - this.storages.forEach((s$9) => s$9.set(null)); - this.collection.set(null); - this.vals.clear(); - } -}; -Object.setPrototypeOf(SignalSet.prototype, Set.prototype); - -function create() { - return new A2uiMessageProcessor({ - arrayCtor: SignalArray, - mapCtor: SignalMap, - objCtor: SignalObject, - setCtor: SignalSet - }); -} - -var server_to_client_with_standard_catalog_default = { - title: "A2UI Message Schema", - description: "Describes a JSON payload for an A2UI (Agent to UI) message, which is used to dynamically construct and update user interfaces. A message MUST contain exactly ONE of the action properties: 'beginRendering', 'surfaceUpdate', 'dataModelUpdate', or 'deleteSurface'.", - type: "object", - additionalProperties: false, - properties: { - "beginRendering": { - "type": "object", - "description": "Signals the client to begin rendering a surface with a root component and specific styles.", - "additionalProperties": false, - "properties": { - "surfaceId": { - "type": "string", - "description": "The unique identifier for the UI surface to be rendered." - }, - "root": { - "type": "string", - "description": "The ID of the root component to render." - }, - "styles": { - "type": "object", - "description": "Styling information for the UI.", - "additionalProperties": false, - "properties": { - "font": { - "type": "string", - "description": "The primary font for the UI." - }, - "primaryColor": { - "type": "string", - "description": "The primary UI color as a hexadecimal code (e.g., '#00BFFF').", - "pattern": "^#[0-9a-fA-F]{6}$" - } - } - } - }, - "required": ["root", "surfaceId"] - }, - "surfaceUpdate": { - "type": "object", - "description": "Updates a surface with a new set of components.", - "additionalProperties": false, - "properties": { - "surfaceId": { - "type": "string", - "description": "The unique identifier for the UI surface to be updated. If you are adding a new surface this *must* be a new, unique identified that has never been used for any existing surfaces shown." - }, - "components": { - "type": "array", - "description": "A list containing all UI components for the surface.", - "minItems": 1, - "items": { - "type": "object", - "description": "Represents a *single* component in a UI widget tree. This component could be one of many supported types.", - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "description": "The unique identifier for this component." - }, - "weight": { - "type": "number", - "description": "The relative weight of this component within a Row or Column. This corresponds to the CSS 'flex-grow' property. Note: this may ONLY be set when the component is a direct descendant of a Row or Column." - }, - "component": { - "type": "object", - "description": "A wrapper object that MUST contain exactly one key, which is the name of the component type (e.g., 'Heading'). The value is an object containing the properties for that specific component.", - "additionalProperties": false, - "properties": { - "Text": { - "type": "object", - "additionalProperties": false, - "properties": { - "text": { - "type": "object", - "description": "The text content to display. This can be a literal string or a reference to a value in the data model ('path', e.g., '/doc/title'). While simple Markdown formatting is supported (i.e. without HTML, images, or links), utilizing dedicated UI components is generally preferred for a richer and more structured presentation.", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - }, - "usageHint": { - "type": "string", - "description": "A hint for the base text style. One of:\n- `h1`: Largest heading.\n- `h2`: Second largest heading.\n- `h3`: Third largest heading.\n- `h4`: Fourth largest heading.\n- `h5`: Fifth largest heading.\n- `caption`: Small text for captions.\n- `body`: Standard body text.", - "enum": [ - "h1", - "h2", - "h3", - "h4", - "h5", - "caption", - "body" - ] - } - }, - "required": ["text"] - }, - "Image": { - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "object", - "description": "The URL of the image to display. This can be a literal string ('literal') or a reference to a value in the data model ('path', e.g. '/thumbnail/url').", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - }, - "fit": { - "type": "string", - "description": "Specifies how the image should be resized to fit its container. This corresponds to the CSS 'object-fit' property.", - "enum": [ - "contain", - "cover", - "fill", - "none", - "scale-down" - ] - }, - "usageHint": { - "type": "string", - "description": "A hint for the image size and style. One of:\n- `icon`: Small square icon.\n- `avatar`: Circular avatar image.\n- `smallFeature`: Small feature image.\n- `mediumFeature`: Medium feature image.\n- `largeFeature`: Large feature image.\n- `header`: Full-width, full bleed, header image.", - "enum": [ - "icon", - "avatar", - "smallFeature", - "mediumFeature", - "largeFeature", - "header" - ] - } - }, - "required": ["url"] - }, - "Icon": { - "type": "object", - "additionalProperties": false, - "properties": { "name": { - "type": "object", - "description": "The name of the icon to display. This can be a literal string or a reference to a value in the data model ('path', e.g. '/form/submit').", - "additionalProperties": false, - "properties": { - "literalString": { - "type": "string", - "enum": [ - "accountCircle", - "add", - "arrowBack", - "arrowForward", - "attachFile", - "calendarToday", - "call", - "camera", - "check", - "close", - "delete", - "download", - "edit", - "event", - "error", - "favorite", - "favoriteOff", - "folder", - "help", - "home", - "info", - "locationOn", - "lock", - "lockOpen", - "mail", - "menu", - "moreVert", - "moreHoriz", - "notificationsOff", - "notifications", - "payment", - "person", - "phone", - "photo", - "print", - "refresh", - "search", - "send", - "settings", - "share", - "shoppingCart", - "star", - "starHalf", - "starOff", - "upload", - "visibility", - "visibilityOff", - "warning" - ] - }, - "path": { "type": "string" } - } - } }, - "required": ["name"] - }, - "Video": { - "type": "object", - "additionalProperties": false, - "properties": { "url": { - "type": "object", - "description": "The URL of the video to display. This can be a literal string or a reference to a value in the data model ('path', e.g. '/video/url').", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - } }, - "required": ["url"] - }, - "AudioPlayer": { - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "object", - "description": "The URL of the audio to be played. This can be a literal string ('literal') or a reference to a value in the data model ('path', e.g. '/song/url').", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - }, - "description": { - "type": "object", - "description": "A description of the audio, such as a title or summary. This can be a literal string or a reference to a value in the data model ('path', e.g. '/song/title').", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - } - }, - "required": ["url"] - }, - "Row": { - "type": "object", - "additionalProperties": false, - "properties": { - "children": { - "type": "object", - "description": "Defines the children. Use 'explicitList' for a fixed set of children, or 'template' to generate children from a data list.", - "additionalProperties": false, - "properties": { - "explicitList": { - "type": "array", - "items": { "type": "string" } - }, - "template": { - "type": "object", - "description": "A template for generating a dynamic list of children from a data model list. `componentId` is the component to use as a template, and `dataBinding` is the path to the map of components in the data model. Values in the map will define the list of children.", - "additionalProperties": false, - "properties": { - "componentId": { "type": "string" }, - "dataBinding": { "type": "string" } - }, - "required": ["componentId", "dataBinding"] - } - } - }, - "distribution": { - "type": "string", - "description": "Defines the arrangement of children along the main axis (horizontally). This corresponds to the CSS 'justify-content' property.", - "enum": [ - "center", - "end", - "spaceAround", - "spaceBetween", - "spaceEvenly", - "start" - ] - }, - "alignment": { - "type": "string", - "description": "Defines the alignment of children along the cross axis (vertically). This corresponds to the CSS 'align-items' property.", - "enum": [ - "start", - "center", - "end", - "stretch" - ] - } - }, - "required": ["children"] - }, - "Column": { - "type": "object", - "additionalProperties": false, - "properties": { - "children": { - "type": "object", - "description": "Defines the children. Use 'explicitList' for a fixed set of children, or 'template' to generate children from a data list.", - "additionalProperties": false, - "properties": { - "explicitList": { - "type": "array", - "items": { "type": "string" } - }, - "template": { - "type": "object", - "description": "A template for generating a dynamic list of children from a data model list. `componentId` is the component to use as a template, and `dataBinding` is the path to the map of components in the data model. Values in the map will define the list of children.", - "additionalProperties": false, - "properties": { - "componentId": { "type": "string" }, - "dataBinding": { "type": "string" } - }, - "required": ["componentId", "dataBinding"] - } - } - }, - "distribution": { - "type": "string", - "description": "Defines the arrangement of children along the main axis (vertically). This corresponds to the CSS 'justify-content' property.", - "enum": [ - "start", - "center", - "end", - "spaceBetween", - "spaceAround", - "spaceEvenly" - ] - }, - "alignment": { - "type": "string", - "description": "Defines the alignment of children along the cross axis (horizontally). This corresponds to the CSS 'align-items' property.", - "enum": [ - "center", - "end", - "start", - "stretch" - ] - } - }, - "required": ["children"] - }, - "List": { - "type": "object", - "additionalProperties": false, - "properties": { - "children": { - "type": "object", - "description": "Defines the children. Use 'explicitList' for a fixed set of children, or 'template' to generate children from a data list.", - "additionalProperties": false, - "properties": { - "explicitList": { - "type": "array", - "items": { "type": "string" } - }, - "template": { - "type": "object", - "description": "A template for generating a dynamic list of children from a data model list. `componentId` is the component to use as a template, and `dataBinding` is the path to the map of components in the data model. Values in the map will define the list of children.", - "additionalProperties": false, - "properties": { - "componentId": { "type": "string" }, - "dataBinding": { "type": "string" } - }, - "required": ["componentId", "dataBinding"] - } - } - }, - "direction": { - "type": "string", - "description": "The direction in which the list items are laid out.", - "enum": ["vertical", "horizontal"] - }, - "alignment": { - "type": "string", - "description": "Defines the alignment of children along the cross axis.", - "enum": [ - "start", - "center", - "end", - "stretch" - ] - } - }, - "required": ["children"] - }, - "Card": { - "type": "object", - "additionalProperties": false, - "properties": { "child": { - "type": "string", - "description": "The ID of the component to be rendered inside the card." - } }, - "required": ["child"] - }, - "Tabs": { - "type": "object", - "additionalProperties": false, - "properties": { "tabItems": { - "type": "array", - "description": "An array of objects, where each object defines a tab with a title and a child component.", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "title": { - "type": "object", - "description": "The tab title. Defines the value as either a literal value or a path to data model value (e.g. '/options/title').", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - }, - "child": { "type": "string" } - }, - "required": ["title", "child"] - } - } }, - "required": ["tabItems"] - }, - "Divider": { - "type": "object", - "additionalProperties": false, - "properties": { "axis": { - "type": "string", - "description": "The orientation of the divider.", - "enum": ["horizontal", "vertical"] - } } - }, - "Modal": { - "type": "object", - "additionalProperties": false, - "properties": { - "entryPointChild": { - "type": "string", - "description": "The ID of the component that opens the modal when interacted with (e.g., a button)." - }, - "contentChild": { - "type": "string", - "description": "The ID of the component to be displayed inside the modal." - } - }, - "required": ["entryPointChild", "contentChild"] - }, - "Button": { - "type": "object", - "additionalProperties": false, - "properties": { - "child": { - "type": "string", - "description": "The ID of the component to display in the button, typically a Text component." - }, - "primary": { - "type": "boolean", - "description": "Indicates if this button should be styled as the primary action." - }, - "action": { - "type": "object", - "description": "The client-side action to be dispatched when the button is clicked. It includes the action's name and an optional context payload.", - "additionalProperties": false, - "properties": { - "name": { "type": "string" }, - "context": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "key": { "type": "string" }, - "value": { - "type": "object", - "description": "Defines the value to be included in the context as either a literal value or a path to a data model value (e.g. '/user/name').", - "additionalProperties": false, - "properties": { - "path": { "type": "string" }, - "literalString": { "type": "string" }, - "literalNumber": { "type": "number" }, - "literalBoolean": { "type": "boolean" } - } - } - }, - "required": ["key", "value"] - } - } - }, - "required": ["name"] - } - }, - "required": ["child", "action"] - }, - "CheckBox": { - "type": "object", - "additionalProperties": false, - "properties": { - "label": { - "type": "object", - "description": "The text to display next to the checkbox. Defines the value as either a literal value or a path to data model ('path', e.g. '/option/label').", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - }, - "value": { - "type": "object", - "description": "The current state of the checkbox (true for checked, false for unchecked). This can be a literal boolean ('literalBoolean') or a reference to a value in the data model ('path', e.g. '/filter/open').", - "additionalProperties": false, - "properties": { - "literalBoolean": { "type": "boolean" }, - "path": { "type": "string" } - } - } - }, - "required": ["label", "value"] - }, - "TextField": { - "type": "object", - "additionalProperties": false, - "properties": { - "label": { - "type": "object", - "description": "The text label for the input field. This can be a literal string or a reference to a value in the data model ('path, e.g. '/user/name').", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - }, - "text": { - "type": "object", - "description": "The value of the text field. This can be a literal string or a reference to a value in the data model ('path', e.g. '/user/name').", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - }, - "textFieldType": { - "type": "string", - "description": "The type of input field to display.", - "enum": [ - "date", - "longText", - "number", - "shortText", - "obscured" - ] - }, - "validationRegexp": { - "type": "string", - "description": "A regular expression used for client-side validation of the input." - } - }, - "required": ["label"] - }, - "DateTimeInput": { - "type": "object", - "additionalProperties": false, - "properties": { - "value": { - "type": "object", - "description": "The selected date and/or time value. This can be a literal string ('literalString') or a reference to a value in the data model ('path', e.g. '/user/dob').", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - }, - "enableDate": { - "type": "boolean", - "description": "If true, allows the user to select a date." - }, - "enableTime": { - "type": "boolean", - "description": "If true, allows the user to select a time." - }, - "outputFormat": { - "type": "string", - "description": "The desired format for the output string after a date or time is selected." - } - }, - "required": ["value"] - }, - "MultipleChoice": { - "type": "object", - "additionalProperties": false, - "properties": { - "selections": { - "type": "object", - "description": "The currently selected values for the component. This can be a literal array of strings or a path to an array in the data model('path', e.g. '/hotel/options').", - "additionalProperties": false, - "properties": { - "literalArray": { - "type": "array", - "items": { "type": "string" } - }, - "path": { "type": "string" } - } - }, - "options": { - "type": "array", - "description": "An array of available options for the user to choose from.", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "label": { - "type": "object", - "description": "The text to display for this option. This can be a literal string or a reference to a value in the data model (e.g. '/option/label').", - "additionalProperties": false, - "properties": { - "literalString": { "type": "string" }, - "path": { "type": "string" } - } - }, - "value": { - "type": "string", - "description": "The value to be associated with this option when selected." - } - }, - "required": ["label", "value"] - } - }, - "maxAllowedSelections": { - "type": "integer", - "description": "The maximum number of options that the user is allowed to select." - } - }, - "required": ["selections", "options"] - }, - "Slider": { - "type": "object", - "additionalProperties": false, - "properties": { - "value": { - "type": "object", - "description": "The current value of the slider. This can be a literal number ('literalNumber') or a reference to a value in the data model ('path', e.g. '/restaurant/cost').", - "additionalProperties": false, - "properties": { - "literalNumber": { "type": "number" }, - "path": { "type": "string" } - } - }, - "minValue": { - "type": "number", - "description": "The minimum value of the slider." - }, - "maxValue": { - "type": "number", - "description": "The maximum value of the slider." - } - }, - "required": ["value"] - } - } - } - }, - "required": ["id", "component"] - } - } - }, - "required": ["surfaceId", "components"] - }, - "dataModelUpdate": { - "type": "object", - "description": "Updates the data model for a surface.", - "additionalProperties": false, - "properties": { - "surfaceId": { - "type": "string", - "description": "The unique identifier for the UI surface this data model update applies to." - }, - "path": { - "type": "string", - "description": "An optional path to a location within the data model (e.g., '/user/name'). If omitted, or set to '/', the entire data model will be replaced." - }, - "contents": { - "type": "array", - "description": "An array of data entries. Each entry must contain a 'key' and exactly one corresponding typed 'value*' property.", - "items": { - "type": "object", - "description": "A single data entry. Exactly one 'value*' property should be provided alongside the key.", - "additionalProperties": false, - "properties": { - "key": { - "type": "string", - "description": "The key for this data entry." - }, - "valueString": { "type": "string" }, - "valueNumber": { "type": "number" }, - "valueBoolean": { "type": "boolean" }, - "valueMap": { - "description": "Represents a map as an adjacency list.", - "type": "array", - "items": { - "type": "object", - "description": "One entry in the map. Exactly one 'value*' property should be provided alongside the key.", - "additionalProperties": false, - "properties": { - "key": { "type": "string" }, - "valueString": { "type": "string" }, - "valueNumber": { "type": "number" }, - "valueBoolean": { "type": "boolean" } - }, - "required": ["key"] - } - } - }, - "required": ["key"] - } - } - }, - "required": ["contents", "surfaceId"] - }, - "deleteSurface": { - "type": "object", - "description": "Signals the client to delete the surface identified by 'surfaceId'.", - "additionalProperties": false, - "properties": { "surfaceId": { - "type": "string", - "description": "The unique identifier for the UI surface to be deleted." - } }, - "required": ["surfaceId"] - } - } -}; - -const Data = { - createSignalA2uiMessageProcessor: create, - A2uiMessageProcessor, - Guards: guards_exports -}; -const Schemas = { A2UIClientEventMessage: server_to_client_with_standard_catalog_default }; - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -const t$1 = (t$7) => (e$14, o$15) => { - void 0 !== o$15 ? o$15.addInitializer(() => { - customElements.define(t$7, e$14); - }) : customElements.define(t$7, e$14); -}; - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ const o$9 = { - attribute: !0, - type: String, - converter: u$3, - reflect: !1, - hasChanged: f$3 -}, r$7 = (t$7 = o$9, e$14, r$12) => { - const { kind: n$13, metadata: i$10 } = r$12; - let s$9 = globalThis.litPropertyMetadata.get(i$10); - if (void 0 === s$9 && globalThis.litPropertyMetadata.set(i$10, s$9 = new Map()), "setter" === n$13 && ((t$7 = Object.create(t$7)).wrapped = !0), s$9.set(r$12.name, t$7), "accessor" === n$13) { - const { name: o$15 } = r$12; - return { - set(r$13) { - const n$14 = e$14.get.call(this); - e$14.set.call(this, r$13), this.requestUpdate(o$15, n$14, t$7, !0, r$13); - }, - init(e$15) { - return void 0 !== e$15 && this.C(o$15, void 0, t$7, e$15), e$15; - } - }; - } - if ("setter" === n$13) { - const { name: o$15 } = r$12; - return function(r$13) { - const n$14 = this[o$15]; - e$14.call(this, r$13), this.requestUpdate(o$15, n$14, t$7, !0, r$13); - }; - } - throw Error("Unsupported decorator location: " + n$13); -}; -function n$6(t$7) { - return (e$14, o$15) => "object" == typeof o$15 ? r$7(t$7, e$14, o$15) : ((t$8, e$15, o$16) => { - const r$12 = e$15.hasOwnProperty(o$16); - return e$15.constructor.createProperty(o$16, t$8), r$12 ? Object.getOwnPropertyDescriptor(e$15, o$16) : void 0; - })(t$7, e$14, o$15); -} - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ function r$6(r$12) { - return n$6({ - ...r$12, - state: !0, - attribute: !1 - }); -} - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -function t(t) { - return (n$13, o$15) => { - const c$7 = "function" == typeof n$13 ? n$13 : n$13[o$15]; - Object.assign(c$7, t); - }; -} - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -const e$6 = (e$14, t$7, c$7) => (c$7.configurable = !0, c$7.enumerable = !0, Reflect.decorate && "object" != typeof t$7 && Object.defineProperty(e$14, t$7, c$7), c$7); - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ function e$5(e$14, r$12) { - return (n$13, s$9, i$10) => { - const o$15 = (t$7) => t$7.renderRoot?.querySelector(e$14) ?? null; - if (r$12) { - const { get: e$15, set: r$13 } = "object" == typeof s$9 ? n$13 : i$10 ?? (() => { - const t$7 = Symbol(); - return { - get() { - return this[t$7]; - }, - set(e$16) { - this[t$7] = e$16; - } - }; - })(); - return e$6(n$13, s$9, { get() { - let t$7 = e$15.call(this); - return void 0 === t$7 && (t$7 = o$15(this), (null !== t$7 || this.hasUpdated) && r$13.call(this, t$7)), t$7; - } }); - } - return e$6(n$13, s$9, { get() { - return o$15(this); - } }); - }; -} - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -let e$4; -function r$5(r$12) { - return (n$13, o$15) => e$6(n$13, o$15, { get() { - return (this.renderRoot ?? (e$4 ??= document.createDocumentFragment())).querySelectorAll(r$12); - } }); -} - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -function r$4(r$12) { - return (n$13, e$14) => e$6(n$13, e$14, { async get() { - return await this.updateComplete, this.renderRoot?.querySelector(r$12) ?? null; - } }); -} - -/** -* @license -* Copyright 2021 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ function o$8(o$15) { - return (e$14, n$13) => { - const { slot: r$12, selector: s$9 } = o$15 ?? {}, c$7 = "slot" + (r$12 ? `[name=${r$12}]` : ":not([name])"); - return e$6(e$14, n$13, { get() { - const t$7 = this.renderRoot?.querySelector(c$7), e$15 = t$7?.assignedElements(o$15) ?? []; - return void 0 === s$9 ? e$15 : e$15.filter((t$8) => t$8.matches(s$9)); - } }); - }; -} - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ function n$5(n$13) { - return (o$15, r$12) => { - const { slot: e$14 } = n$13 ?? {}, s$9 = "slot" + (e$14 ? `[name=${e$14}]` : ":not([name])"); - return e$6(o$15, r$12, { get() { - const t$7 = this.renderRoot?.querySelector(s$9); - return t$7?.assignedNodes(n$13) ?? []; - } }); - }; -} - -/** -* @license -* Copyright 2023 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ let i$2 = !1; -const s$1 = new Signal.subtle.Watcher(() => { - i$2 || (i$2 = !0, queueMicrotask(() => { - i$2 = !1; - for (const t$7 of s$1.getPending()) t$7.get(); - s$1.watch(); - })); -}), h$3 = Symbol("SignalWatcherBrand"), e$3 = new FinalizationRegistry((i$10) => { - i$10.unwatch(...Signal.subtle.introspectSources(i$10)); -}), n$4 = new WeakMap(); -function o$7(i$10) { - return !0 === i$10[h$3] ? (console.warn("SignalWatcher should not be applied to the same class more than once."), i$10) : class extends i$10 { - constructor() { - super(...arguments), this._$St = new Map(), this._$So = new Signal.State(0), this._$Si = !1; - } - _$Sl() { - var t$7, i$11; - const s$9 = [], h$7 = []; - this._$St.forEach((t$8, i$12) => { - ((null == t$8 ? void 0 : t$8.beforeUpdate) ? s$9 : h$7).push(i$12); - }); - const e$14 = null === (t$7 = this.h) || void 0 === t$7 ? void 0 : t$7.getPending().filter((t$8) => t$8 !== this._$Su && !this._$St.has(t$8)); - s$9.forEach((t$8) => t$8.get()), null === (i$11 = this._$Su) || void 0 === i$11 || i$11.get(), e$14.forEach((t$8) => t$8.get()), h$7.forEach((t$8) => t$8.get()); - } - _$Sv() { - this.isUpdatePending || queueMicrotask(() => { - this.isUpdatePending || this._$Sl(); - }); - } - _$S_() { - if (void 0 !== this.h) return; - this._$Su = new Signal.Computed(() => { - this._$So.get(), super.performUpdate(); - }); - const i$11 = this.h = new Signal.subtle.Watcher(function() { - const t$7 = n$4.get(this); - void 0 !== t$7 && (!1 === t$7._$Si && (new Set(this.getPending()).has(t$7._$Su) ? t$7.requestUpdate() : t$7._$Sv()), this.watch()); - }); - n$4.set(i$11, this), e$3.register(this, i$11), i$11.watch(this._$Su), i$11.watch(...Array.from(this._$St).map(([t$7]) => t$7)); - } - _$Sp() { - if (void 0 === this.h) return; - let i$11 = !1; - this.h.unwatch(...Signal.subtle.introspectSources(this.h).filter((t$7) => { - var s$9; - const h$7 = !0 !== (null === (s$9 = this._$St.get(t$7)) || void 0 === s$9 ? void 0 : s$9.manualDispose); - return h$7 && this._$St.delete(t$7), i$11 || (i$11 = !h$7), h$7; - })), i$11 || (this._$Su = void 0, this.h = void 0, this._$St.clear()); - } - updateEffect(i$11, s$9) { - var h$7; - this._$S_(); - const e$14 = new Signal.Computed(() => { - i$11(); - }); - return this.h.watch(e$14), this._$St.set(e$14, s$9), null !== (h$7 = null == s$9 ? void 0 : s$9.beforeUpdate) && void 0 !== h$7 && h$7 ? Signal.subtle.untrack(() => e$14.get()) : this.updateComplete.then(() => Signal.subtle.untrack(() => e$14.get())), () => { - this._$St.delete(e$14), this.h.unwatch(e$14), !1 === this.isConnected && this._$Sp(); - }; - } - performUpdate() { - this.isUpdatePending && (this._$S_(), this._$Si = !0, this._$So.set(this._$So.get() + 1), this._$Si = !1, this._$Sl()); - } - connectedCallback() { - super.connectedCallback(), this.requestUpdate(); - } - disconnectedCallback() { - super.disconnectedCallback(), queueMicrotask(() => { - !1 === this.isConnected && this._$Sp(); - }); - } - }; -} - -/** -* @license -* Copyright 2017 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ const s = (i$10, t$7) => { - const e$14 = i$10._$AN; - if (void 0 === e$14) return !1; - for (const i$11 of e$14) i$11._$AO?.(t$7, !1), s(i$11, t$7); - return !0; -}, o$6 = (i$10) => { - let t$7, e$14; - do { - if (void 0 === (t$7 = i$10._$AM)) break; - e$14 = t$7._$AN, e$14.delete(i$10), i$10 = t$7; - } while (0 === e$14?.size); -}, r$3 = (i$10) => { - for (let t$7; t$7 = i$10._$AM; i$10 = t$7) { - let e$14 = t$7._$AN; - if (void 0 === e$14) t$7._$AN = e$14 = new Set(); - else if (e$14.has(i$10)) break; - e$14.add(i$10), c(t$7); - } -}; -function h$2(i$10) { - void 0 !== this._$AN ? (o$6(this), this._$AM = i$10, r$3(this)) : this._$AM = i$10; -} -function n$3(i$10, t$7 = !1, e$14 = 0) { - const r$12 = this._$AH, h$7 = this._$AN; - if (void 0 !== h$7 && 0 !== h$7.size) if (t$7) if (Array.isArray(r$12)) for (let i$11 = e$14; i$11 < r$12.length; i$11++) s(r$12[i$11], !1), o$6(r$12[i$11]); - else null != r$12 && (s(r$12, !1), o$6(r$12)); - else s(this, i$10); -} -const c = (i$10) => { - i$10.type == t$4.CHILD && (i$10._$AP ??= n$3, i$10._$AQ ??= h$2); -}; -var f = class extends i$5 { - constructor() { - super(...arguments), this._$AN = void 0; - } - _$AT(i$10, t$7, e$14) { - super._$AT(i$10, t$7, e$14), r$3(this), this.isConnected = i$10._$AU; - } - _$AO(i$10, t$7 = !0) { - i$10 !== this.isConnected && (this.isConnected = i$10, i$10 ? this.reconnected?.() : this.disconnected?.()), t$7 && (s(this, i$10), o$6(this)); - } - setValue(t$7) { - if (r$8(this._$Ct)) this._$Ct._$AI(t$7, this); - else { - const i$10 = [...this._$Ct._$AH]; - i$10[this._$Ci] = t$7, this._$Ct._$AI(i$10, this, 0); - } - } - disconnected() {} - reconnected() {} -}; - -/** -* @license -* Copyright 2023 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -let o$5 = !1; -const n$2 = new Signal.subtle.Watcher(async () => { - o$5 || (o$5 = !0, queueMicrotask(() => { - o$5 = !1; - for (const i$10 of n$2.getPending()) i$10.get(); - n$2.watch(); - })); -}); -var r$2 = class extends f { - _$S_() { - var i$10, t$7; - void 0 === this._$Sm && (this._$Sj = new Signal.Computed(() => { - var i$11; - const t$8 = null === (i$11 = this._$SW) || void 0 === i$11 ? void 0 : i$11.get(); - return this.setValue(t$8), t$8; - }), this._$Sm = null !== (t$7 = null === (i$10 = this._$Sk) || void 0 === i$10 ? void 0 : i$10.h) && void 0 !== t$7 ? t$7 : n$2, this._$Sm.watch(this._$Sj), Signal.subtle.untrack(() => { - var i$11; - return null === (i$11 = this._$Sj) || void 0 === i$11 ? void 0 : i$11.get(); - })); - } - _$Sp() { - void 0 !== this._$Sm && (this._$Sm.unwatch(this._$SW), this._$Sm = void 0); - } - render(i$10) { - return Signal.subtle.untrack(() => i$10.get()); - } - update(i$10, [t$7]) { - var o$15, n$13; - return null !== (o$15 = this._$Sk) && void 0 !== o$15 || (this._$Sk = null === (n$13 = i$10.options) || void 0 === n$13 ? void 0 : n$13.host), t$7 !== this._$SW && void 0 !== this._$SW && this._$Sp(), this._$SW = t$7, this._$S_(), Signal.subtle.untrack(() => this._$SW.get()); - } - disconnected() { - this._$Sp(); - } - reconnected() { - this._$S_(); - } -}; -const h$1 = e$10(r$2); - -/** -* @license -* Copyright 2023 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ const m = (o$15) => (t$7, ...m) => o$15(t$7, ...m.map((o$16) => o$16 instanceof Signal.State || o$16 instanceof Signal.Computed ? h$1(o$16) : o$16)), l$1 = m(b), r$1 = m(w); - -/** -* @license -* Copyright 2023 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ const l = Signal.State, o$4 = Signal.Computed, r = (l, o$15) => new Signal.State(l, o$15), i$1 = (l, o$15) => new Signal.Computed(l, o$15); - -/** -* @license -* Copyright 2021 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ -function* o$3(o$15, f$4) { - if (void 0 !== o$15) { - let i$10 = 0; - for (const t$7 of o$15) yield f$4(t$7, i$10++); - } -} - -let pending = false; -let watcher = new Signal.subtle.Watcher(() => { - if (!pending) { - pending = true; - queueMicrotask(() => { - pending = false; - flushPending(); - }); - } -}); -function flushPending() { - for (const signal of watcher.getPending()) { - signal.get(); - } - watcher.watch(); -} -/** -* ⚠️ WARNING: Nothing unwatches ⚠️ -* This will produce a memory leak. -*/ -function effect(cb) { - let c$7 = new Signal.Computed(() => cb()); - watcher.watch(c$7); - c$7.get(); - return () => { - watcher.unwatch(c$7); - }; -} - -const themeContext = n$7("A2UITheme"); - -const structuralStyles = r$11(structuralStyles$1); - -var ComponentRegistry = class { - constructor() { - this.registry = new Map(); - } - register(typeName, constructor, tagName) { - if (!/^[a-zA-Z0-9]+$/.test(typeName)) { - throw new Error(`[Registry] Invalid typeName '${typeName}'. Must be alphanumeric.`); - } - this.registry.set(typeName, constructor); - const actualTagName = tagName || `a2ui-custom-${typeName.toLowerCase()}`; - const existingName = customElements.getName(constructor); - if (existingName) { - if (existingName !== actualTagName) { - throw new Error(`Component ${typeName} is already registered as ${existingName}, but requested as ${actualTagName}.`); - } - return; - } - if (!customElements.get(actualTagName)) { - customElements.define(actualTagName, constructor); - } - } - get(typeName) { - return this.registry.get(typeName); - } -}; -const componentRegistry = new ComponentRegistry(); - -var __runInitializers$19 = void 0 && (void 0).__runInitializers || function(thisArg, initializers, value) { - var useValue = arguments.length > 2; - for (var i$10 = 0; i$10 < initializers.length; i$10++) { - value = useValue ? initializers[i$10].call(thisArg, value) : initializers[i$10].call(thisArg); - } - return useValue ? value : void 0; -}; -var __esDecorate$19 = void 0 && (void 0).__esDecorate || function(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { - function accept(f$4) { - if (f$4 !== void 0 && typeof f$4 !== "function") throw new TypeError("Function expected"); - return f$4; - } - var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; - var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; - var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); - var _$1, done = false; - for (var i$10 = decorators.length - 1; i$10 >= 0; i$10--) { - var context = {}; - for (var p$3 in contextIn) context[p$3] = p$3 === "access" ? {} : contextIn[p$3]; - for (var p$3 in contextIn.access) context.access[p$3] = contextIn.access[p$3]; - context.addInitializer = function(f$4) { - if (done) throw new TypeError("Cannot add initializers after decoration has completed"); - extraInitializers.push(accept(f$4 || null)); - }; - var result = (0, decorators[i$10])(kind === "accessor" ? { - get: descriptor.get, - set: descriptor.set - } : descriptor[key], context); - if (kind === "accessor") { - if (result === void 0) continue; - if (result === null || typeof result !== "object") throw new TypeError("Object expected"); - if (_$1 = accept(result.get)) descriptor.get = _$1; - if (_$1 = accept(result.set)) descriptor.set = _$1; - if (_$1 = accept(result.init)) initializers.unshift(_$1); - } else if (_$1 = accept(result)) { - if (kind === "field") initializers.unshift(_$1); - else descriptor[key] = _$1; - } - } - if (target) Object.defineProperty(target, contextIn.name, descriptor); - done = true; -}; -let Root = (() => { - let _classDecorators = [t$1("a2ui-root")]; - let _classDescriptor; - let _classExtraInitializers = []; - let _classThis; - let _classSuper = o$7(i$6); - let _instanceExtraInitializers = []; - let _surfaceId_decorators; - let _surfaceId_initializers = []; - let _surfaceId_extraInitializers = []; - let _component_decorators; - let _component_initializers = []; - let _component_extraInitializers = []; - let _theme_decorators; - let _theme_initializers = []; - let _theme_extraInitializers = []; - let _childComponents_decorators; - let _childComponents_initializers = []; - let _childComponents_extraInitializers = []; - let _processor_decorators; - let _processor_initializers = []; - let _processor_extraInitializers = []; - let _dataContextPath_decorators; - let _dataContextPath_initializers = []; - let _dataContextPath_extraInitializers = []; - let _enableCustomElements_decorators; - let _enableCustomElements_initializers = []; - let _enableCustomElements_extraInitializers = []; - let _set_weight_decorators; - var Root = class extends _classSuper { - static { - _classThis = this; - } - static { - const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; - _surfaceId_decorators = [n$6()]; - _component_decorators = [n$6()]; - _theme_decorators = [c$1({ context: themeContext })]; - _childComponents_decorators = [n$6({ attribute: false })]; - _processor_decorators = [n$6({ attribute: false })]; - _dataContextPath_decorators = [n$6()]; - _enableCustomElements_decorators = [n$6()]; - _set_weight_decorators = [n$6()]; - __esDecorate$19(this, null, _surfaceId_decorators, { - kind: "accessor", - name: "surfaceId", - static: false, - private: false, - access: { - has: (obj) => "surfaceId" in obj, - get: (obj) => obj.surfaceId, - set: (obj, value) => { - obj.surfaceId = value; - } - }, - metadata: _metadata - }, _surfaceId_initializers, _surfaceId_extraInitializers); - __esDecorate$19(this, null, _component_decorators, { - kind: "accessor", - name: "component", - static: false, - private: false, - access: { - has: (obj) => "component" in obj, - get: (obj) => obj.component, - set: (obj, value) => { - obj.component = value; - } - }, - metadata: _metadata - }, _component_initializers, _component_extraInitializers); - __esDecorate$19(this, null, _theme_decorators, { - kind: "accessor", - name: "theme", - static: false, - private: false, - access: { - has: (obj) => "theme" in obj, - get: (obj) => obj.theme, - set: (obj, value) => { - obj.theme = value; - } - }, - metadata: _metadata - }, _theme_initializers, _theme_extraInitializers); - __esDecorate$19(this, null, _childComponents_decorators, { - kind: "accessor", - name: "childComponents", - static: false, - private: false, - access: { - has: (obj) => "childComponents" in obj, - get: (obj) => obj.childComponents, - set: (obj, value) => { - obj.childComponents = value; - } - }, - metadata: _metadata - }, _childComponents_initializers, _childComponents_extraInitializers); - __esDecorate$19(this, null, _processor_decorators, { - kind: "accessor", - name: "processor", - static: false, - private: false, - access: { - has: (obj) => "processor" in obj, - get: (obj) => obj.processor, - set: (obj, value) => { - obj.processor = value; - } - }, - metadata: _metadata - }, _processor_initializers, _processor_extraInitializers); - __esDecorate$19(this, null, _dataContextPath_decorators, { - kind: "accessor", - name: "dataContextPath", - static: false, - private: false, - access: { - has: (obj) => "dataContextPath" in obj, - get: (obj) => obj.dataContextPath, - set: (obj, value) => { - obj.dataContextPath = value; - } - }, - metadata: _metadata - }, _dataContextPath_initializers, _dataContextPath_extraInitializers); - __esDecorate$19(this, null, _enableCustomElements_decorators, { - kind: "accessor", - name: "enableCustomElements", - static: false, - private: false, - access: { - has: (obj) => "enableCustomElements" in obj, - get: (obj) => obj.enableCustomElements, - set: (obj, value) => { - obj.enableCustomElements = value; - } - }, - metadata: _metadata - }, _enableCustomElements_initializers, _enableCustomElements_extraInitializers); - __esDecorate$19(this, null, _set_weight_decorators, { - kind: "setter", - name: "weight", - static: false, - private: false, - access: { - has: (obj) => "weight" in obj, - set: (obj, value) => { - obj.weight = value; - } - }, - metadata: _metadata - }, null, _instanceExtraInitializers); - __esDecorate$19(null, _classDescriptor = { value: _classThis }, _classDecorators, { - kind: "class", - name: _classThis.name, - metadata: _metadata - }, null, _classExtraInitializers); - Root = _classThis = _classDescriptor.value; - if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { - enumerable: true, - configurable: true, - writable: true, - value: _metadata - }); - } - #surfaceId_accessor_storage = (__runInitializers$19(this, _instanceExtraInitializers), __runInitializers$19(this, _surfaceId_initializers, null)); - get surfaceId() { - return this.#surfaceId_accessor_storage; - } - set surfaceId(value) { - this.#surfaceId_accessor_storage = value; - } - #component_accessor_storage = (__runInitializers$19(this, _surfaceId_extraInitializers), __runInitializers$19(this, _component_initializers, null)); - get component() { - return this.#component_accessor_storage; - } - set component(value) { - this.#component_accessor_storage = value; - } - #theme_accessor_storage = (__runInitializers$19(this, _component_extraInitializers), __runInitializers$19(this, _theme_initializers, void 0)); - get theme() { - return this.#theme_accessor_storage; - } - set theme(value) { - this.#theme_accessor_storage = value; - } - #childComponents_accessor_storage = (__runInitializers$19(this, _theme_extraInitializers), __runInitializers$19(this, _childComponents_initializers, null)); - get childComponents() { - return this.#childComponents_accessor_storage; - } - set childComponents(value) { - this.#childComponents_accessor_storage = value; - } - #processor_accessor_storage = (__runInitializers$19(this, _childComponents_extraInitializers), __runInitializers$19(this, _processor_initializers, null)); - get processor() { - return this.#processor_accessor_storage; - } - set processor(value) { - this.#processor_accessor_storage = value; - } - #dataContextPath_accessor_storage = (__runInitializers$19(this, _processor_extraInitializers), __runInitializers$19(this, _dataContextPath_initializers, "")); - get dataContextPath() { - return this.#dataContextPath_accessor_storage; - } - set dataContextPath(value) { - this.#dataContextPath_accessor_storage = value; - } - #enableCustomElements_accessor_storage = (__runInitializers$19(this, _dataContextPath_extraInitializers), __runInitializers$19(this, _enableCustomElements_initializers, false)); - get enableCustomElements() { - return this.#enableCustomElements_accessor_storage; - } - set enableCustomElements(value) { - this.#enableCustomElements_accessor_storage = value; - } - set weight(weight) { - this.#weight = weight; - this.style.setProperty("--weight", `${weight}`); - } - get weight() { - return this.#weight; - } - #weight = (__runInitializers$19(this, _enableCustomElements_extraInitializers), 1); - static { - this.styles = [structuralStyles, i$9` - :host { - display: flex; - flex-direction: column; - gap: 8px; - max-height: 80%; - } - `]; - } - /** - * Holds the cleanup function for our effect. - * We need this to stop the effect when the component is disconnected. - */ - #lightDomEffectDisposer = null; - willUpdate(changedProperties) { - if (changedProperties.has("childComponents")) { - if (this.#lightDomEffectDisposer) { - this.#lightDomEffectDisposer(); - } - this.#lightDomEffectDisposer = effect(() => { - const allChildren = this.childComponents ?? null; - const lightDomTemplate = this.renderComponentTree(allChildren); - D(lightDomTemplate, this, { host: this }); - }); - } - } - /** - * Clean up the effect when the component is removed from the DOM. - */ - disconnectedCallback() { - super.disconnectedCallback(); - if (this.#lightDomEffectDisposer) { - this.#lightDomEffectDisposer(); - } - } - /** - * Turns the SignalMap into a renderable TemplateResult for Lit. - */ - renderComponentTree(components) { - if (!components) { - return A; - } - if (!Array.isArray(components)) { - return A; - } - return b` ${o$3(components, (component) => { - if (this.enableCustomElements) { - const registeredCtor = componentRegistry.get(component.type); - const elCtor = registeredCtor || customElements.get(component.type); - if (elCtor) { - const node = component; - const el = new elCtor(); - el.id = node.id; - if (node.slotName) { - el.slot = node.slotName; - } - el.component = node; - el.weight = node.weight ?? "initial"; - el.processor = this.processor; - el.surfaceId = this.surfaceId; - el.dataContextPath = node.dataContextPath ?? "/"; - for (const [prop, val] of Object.entries(component.properties)) { - el[prop] = val; - } - return b`${el}`; - } - } - switch (component.type) { - case "List": { - const node = component; - const childComponents = node.properties.children; - return b``; - } - case "Card": { - const node = component; - let childComponents = node.properties.children; - if (!childComponents && node.properties.child) { - childComponents = [node.properties.child]; - } - return b``; - } - case "Column": { - const node = component; - return b``; - } - case "Row": { - const node = component; - return b``; - } - case "Image": { - const node = component; - return b``; - } - case "Icon": { - const node = component; - return b``; - } - case "AudioPlayer": { - const node = component; - return b``; - } - case "Button": { - const node = component; - return b``; - } - case "Text": { - const node = component; - return b``; - } - case "CheckBox": { - const node = component; - return b``; - } - case "DateTimeInput": { - const node = component; - return b``; - } - case "Divider": { - const node = component; - return b``; - } - case "MultipleChoice": { - const node = component; - return b``; - } - case "Slider": { - const node = component; - return b``; - } - case "TextField": { - const node = component; - return b``; - } - case "Video": { - const node = component; - return b``; - } - case "Tabs": { - const node = component; - const titles = []; - const childComponents = []; - if (node.properties.tabItems) { - for (const item of node.properties.tabItems) { - titles.push(item.title); - childComponents.push(item.child); - } - } - return b``; - } - case "Modal": { - const node = component; - const childComponents = [node.properties.entryPointChild, node.properties.contentChild]; - node.properties.entryPointChild.slotName = "entry"; - return b``; - } - default: { - return this.renderCustomComponent(component); - } - } - })}`; - } - renderCustomComponent(component) { - if (!this.enableCustomElements) { - return; - } - const node = component; - const registeredCtor = componentRegistry.get(component.type); - const elCtor = registeredCtor || customElements.get(component.type); - if (!elCtor) { - return b`Unknown element ${component.type}`; - } - const el = new elCtor(); - el.id = node.id; - if (node.slotName) { - el.slot = node.slotName; - } - el.component = node; - el.weight = node.weight ?? "initial"; - el.processor = this.processor; - el.surfaceId = this.surfaceId; - el.dataContextPath = node.dataContextPath ?? "/"; - for (const [prop, val] of Object.entries(component.properties)) { - el[prop] = val; - } - return b`${el}`; - } - render() { - return b``; - } - static { - __runInitializers$19(_classThis, _classExtraInitializers); - } - }; - return Root = _classThis; -})(); - -/** -* @license -* Copyright 2018 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ const e$2 = e$10(class extends i$5 { - constructor(t$7) { - if (super(t$7), t$7.type !== t$4.ATTRIBUTE || "class" !== t$7.name || t$7.strings?.length > 2) throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute."); - } - render(t$7) { - return " " + Object.keys(t$7).filter((s$9) => t$7[s$9]).join(" ") + " "; - } - update(s$9, [i$10]) { - if (void 0 === this.st) { - this.st = new Set(), void 0 !== s$9.strings && (this.nt = new Set(s$9.strings.join(" ").split(/\s/).filter((t$7) => "" !== t$7))); - for (const t$7 in i$10) i$10[t$7] && !this.nt?.has(t$7) && this.st.add(t$7); - return this.render(i$10); - } - const r$12 = s$9.element.classList; - for (const t$7 of this.st) t$7 in i$10 || (r$12.remove(t$7), this.st.delete(t$7)); - for (const t$7 in i$10) { - const s$10 = !!i$10[t$7]; - s$10 === this.st.has(t$7) || this.nt?.has(t$7) || (s$10 ? (r$12.add(t$7), this.st.add(t$7)) : (r$12.remove(t$7), this.st.delete(t$7))); - } - return E; - } -}); - -/** -* @license -* Copyright 2018 Google LLC -* SPDX-License-Identifier: BSD-3-Clause -*/ const n$1 = "important", i = " !" + n$1, o$2 = e$10(class extends i$5 { - constructor(t$7) { - if (super(t$7), t$7.type !== t$4.ATTRIBUTE || "style" !== t$7.name || t$7.strings?.length > 2) throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute."); - } - render(t$7) { - return Object.keys(t$7).reduce((e$14, r$12) => { - const s$9 = t$7[r$12]; - return null == s$9 ? e$14 : e$14 + `${r$12 = r$12.includes("-") ? r$12 : r$12.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g, "-$&").toLowerCase()}:${s$9};`; - }, ""); - } - update(e$14, [r$12]) { - const { style: s$9 } = e$14.element; - if (void 0 === this.ft) return this.ft = new Set(Object.keys(r$12)), this.render(r$12); - for (const t$7 of this.ft) null == r$12[t$7] && (this.ft.delete(t$7), t$7.includes("-") ? s$9.removeProperty(t$7) : s$9[t$7] = null); - for (const t$7 in r$12) { - const e$15 = r$12[t$7]; - if (null != e$15) { - this.ft.add(t$7); - const r$13 = "string" == typeof e$15 && e$15.endsWith(i); - t$7.includes("-") || r$13 ? s$9.setProperty(t$7, r$13 ? e$15.slice(0, -11) : e$15, r$13 ? n$1 : "") : s$9[t$7] = e$15; - } - } - return E; - } -}); - -var __esDecorate$18 = void 0 && (void 0).__esDecorate || function(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { - function accept(f$4) { - if (f$4 !== void 0 && typeof f$4 !== "function") throw new TypeError("Function expected"); - return f$4; - } - var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; - var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; - var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); - var _$1, done = false; - for (var i$10 = decorators.length - 1; i$10 >= 0; i$10--) { - var context = {}; - for (var p$3 in contextIn) context[p$3] = p$3 === "access" ? {} : contextIn[p$3]; - for (var p$3 in contextIn.access) context.access[p$3] = contextIn.access[p$3]; - context.addInitializer = function(f$4) { - if (done) throw new TypeError("Cannot add initializers after decoration has completed"); - extraInitializers.push(accept(f$4 || null)); - }; - var result = (0, decorators[i$10])(kind === "accessor" ? { - get: descriptor.get, - set: descriptor.set - } : descriptor[key], context); - if (kind === "accessor") { - if (result === void 0) continue; - if (result === null || typeof result !== "object") throw new TypeError("Object expected"); - if (_$1 = accept(result.get)) descriptor.get = _$1; - if (_$1 = accept(result.set)) descriptor.set = _$1; - if (_$1 = accept(result.init)) initializers.unshift(_$1); - } else if (_$1 = accept(result)) { - if (kind === "field") initializers.unshift(_$1); - else descriptor[key] = _$1; - } - } - if (target) Object.defineProperty(target, contextIn.name, descriptor); - done = true; -}; -var __runInitializers$18 = void 0 && (void 0).__runInitializers || function(thisArg, initializers, value) { - var useValue = arguments.length > 2; - for (var i$10 = 0; i$10 < initializers.length; i$10++) { - value = useValue ? initializers[i$10].call(thisArg, value) : initializers[i$10].call(thisArg); - } - return useValue ? value : void 0; -}; -let Audio = (() => { - let _classDecorators = [t$1("a2ui-audioplayer")]; - let _classDescriptor; - let _classExtraInitializers = []; - let _classThis; - let _classSuper = Root; - let _url_decorators; - let _url_initializers = []; - let _url_extraInitializers = []; - var Audio = class extends _classSuper { - static { - _classThis = this; - } - static { - const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; - _url_decorators = [n$6()]; - __esDecorate$18(this, null, _url_decorators, { - kind: "accessor", - name: "url", - static: false, - private: false, - access: { - has: (obj) => "url" in obj, - get: (obj) => obj.url, - set: (obj, value) => { - obj.url = value; - } - }, - metadata: _metadata - }, _url_initializers, _url_extraInitializers); - __esDecorate$18(null, _classDescriptor = { value: _classThis }, _classDecorators, { - kind: "class", - name: _classThis.name, - metadata: _metadata - }, null, _classExtraInitializers); - Audio = _classThis = _classDescriptor.value; - if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { - enumerable: true, - configurable: true, - writable: true, - value: _metadata - }); - } - #url_accessor_storage = __runInitializers$18(this, _url_initializers, null); - get url() { - return this.#url_accessor_storage; - } - set url(value) { - this.#url_accessor_storage = value; - } - static { - this.styles = [structuralStyles, i$9` - * { - box-sizing: border-box; - } - - :host { - display: block; - flex: var(--weight); - min-height: 0; - overflow: auto; - } - - audio { - display: block; - width: 100%; - } - `]; - } - #renderAudio() { - if (!this.url) { - return A; - } - if (this.url && typeof this.url === "object") { - if ("literalString" in this.url) { - return b`
    "; -}; -default_rules.code_block = function(tokens, idx, options, env, slf) { - const token = tokens[idx]; - return "" + escapeHtml(tokens[idx].content) + "\n"; -}; -default_rules.fence = function(tokens, idx, options, env, slf) { - const token = tokens[idx]; - const info = token.info ? unescapeAll(token.info).trim() : ""; - let langName = ""; - let langAttrs = ""; - if (info) { - const arr = info.split(/(\s+)/g); - langName = arr[0]; - langAttrs = arr.slice(2).join(""); - } - let highlighted; - if (options.highlight) { - highlighted = options.highlight(token.content, langName, langAttrs) || escapeHtml(token.content); - } else { - highlighted = escapeHtml(token.content); - } - if (highlighted.indexOf("${highlighted}
    \n`; - } - return `
    ${highlighted}
    \n`; -}; -default_rules.image = function(tokens, idx, options, env, slf) { - const token = tokens[idx]; - token.attrs[token.attrIndex("alt")][1] = slf.renderInlineAsText(token.children, options, env); - return slf.renderToken(tokens, idx, options); -}; -default_rules.hardbreak = function(tokens, idx, options) { - return options.xhtmlOut ? "
    \n" : "
    \n"; -}; -default_rules.softbreak = function(tokens, idx, options) { - return options.breaks ? options.xhtmlOut ? "
    \n" : "
    \n" : "\n"; -}; -default_rules.text = function(tokens, idx) { - return escapeHtml(tokens[idx].content); -}; -default_rules.html_block = function(tokens, idx) { - return tokens[idx].content; -}; -default_rules.html_inline = function(tokens, idx) { - return tokens[idx].content; -}; -/** -* new Renderer() -* -* Creates new [[Renderer]] instance and fill [[Renderer#rules]] with defaults. -**/ -function Renderer() { - /** - * Renderer#rules -> Object - * - * Contains render rules for tokens. Can be updated and extended. - * - * ##### Example - * - * ```javascript - * var md = require('markdown-it')(); - * - * md.renderer.rules.strong_open = function () { return ''; }; - * md.renderer.rules.strong_close = function () { return ''; }; - * - * var result = md.renderInline(...); - * ``` - * - * Each rule is called as independent static function with fixed signature: - * - * ```javascript - * function my_token_render(tokens, idx, options, env, renderer) { - * // ... - * return renderedHTML; - * } - * ``` - * - * See [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.mjs) - * for more details and examples. - **/ - this.rules = assign$1({}, default_rules); -} -/** -* Renderer.renderAttrs(token) -> String -* -* Render token attributes to string. -**/ -Renderer.prototype.renderAttrs = function renderAttrs(token) { - let i$10, l$5, result; - if (!token.attrs) { - return ""; - } - result = ""; - for (i$10 = 0, l$5 = token.attrs.length; i$10 < l$5; i$10++) { - result += " " + escapeHtml(token.attrs[i$10][0]) + "=\"" + escapeHtml(token.attrs[i$10][1]) + "\""; - } - return result; -}; -/** -* Renderer.renderToken(tokens, idx, options) -> String -* - tokens (Array): list of tokens -* - idx (Numbed): token index to render -* - options (Object): params of parser instance -* -* Default token renderer. Can be overriden by custom function -* in [[Renderer#rules]]. -**/ -Renderer.prototype.renderToken = function renderToken(tokens, idx, options) { - const token = tokens[idx]; - let result = ""; - if (token.hidden) { - return ""; - } - if (token.block && token.nesting !== -1 && idx && tokens[idx - 1].hidden) { - result += "\n"; - } - result += (token.nesting === -1 ? "\n" : ">"; - return result; -}; -/** -* Renderer.renderInline(tokens, options, env) -> String -* - tokens (Array): list on block tokens to render -* - options (Object): params of parser instance -* - env (Object): additional data from parsed input (references, for example) -* -* The same as [[Renderer.render]], but for single token of `inline` type. -**/ -Renderer.prototype.renderInline = function(tokens, options, env) { - let result = ""; - const rules = this.rules; - for (let i$10 = 0, len = tokens.length; i$10 < len; i$10++) { - const type$2 = tokens[i$10].type; - if (typeof rules[type$2] !== "undefined") { - result += rules[type$2](tokens, i$10, options, env, this); - } else { - result += this.renderToken(tokens, i$10, options); - } - } - return result; -}; -/** internal -* Renderer.renderInlineAsText(tokens, options, env) -> String -* - tokens (Array): list on block tokens to render -* - options (Object): params of parser instance -* - env (Object): additional data from parsed input (references, for example) -* -* Special kludge for image `alt` attributes to conform CommonMark spec. -* Don't try to use it! Spec requires to show `alt` content with stripped markup, -* instead of simple escaping. -**/ -Renderer.prototype.renderInlineAsText = function(tokens, options, env) { - let result = ""; - for (let i$10 = 0, len = tokens.length; i$10 < len; i$10++) { - switch (tokens[i$10].type) { - case "text": - result += tokens[i$10].content; - break; - case "image": - result += this.renderInlineAsText(tokens[i$10].children, options, env); - break; - case "html_inline": - case "html_block": - result += tokens[i$10].content; - break; - case "softbreak": - case "hardbreak": - result += "\n"; - break; - default: - } - } - return result; -}; -/** -* Renderer.render(tokens, options, env) -> String -* - tokens (Array): list on block tokens to render -* - options (Object): params of parser instance -* - env (Object): additional data from parsed input (references, for example) -* -* Takes token stream and generates HTML. Probably, you will never need to call -* this method directly. -**/ -Renderer.prototype.render = function(tokens, options, env) { - let result = ""; - const rules = this.rules; - for (let i$10 = 0, len = tokens.length; i$10 < len; i$10++) { - const type$2 = tokens[i$10].type; - if (type$2 === "inline") { - result += this.renderInline(tokens[i$10].children, options, env); - } else if (typeof rules[type$2] !== "undefined") { - result += rules[type$2](tokens, i$10, options, env, this); - } else { - result += this.renderToken(tokens, i$10, options, env); - } - } - return result; -}; -var renderer_default = Renderer; - -/** -* class Ruler -* -* Helper class, used by [[MarkdownIt#core]], [[MarkdownIt#block]] and -* [[MarkdownIt#inline]] to manage sequences of functions (rules): -* -* - keep rules in defined order -* - assign the name to each rule -* - enable/disable rules -* - add/replace rules -* - allow assign rules to additional named chains (in the same) -* - cacheing lists of active rules -* -* You will not need use this class directly until write plugins. For simple -* rules control use [[MarkdownIt.disable]], [[MarkdownIt.enable]] and -* [[MarkdownIt.use]]. -**/ -/** -* new Ruler() -**/ -function Ruler() { - this.__rules__ = []; - this.__cache__ = null; -} -Ruler.prototype.__find__ = function(name) { - for (let i$10 = 0; i$10 < this.__rules__.length; i$10++) { - if (this.__rules__[i$10].name === name) { - return i$10; - } - } - return -1; -}; -Ruler.prototype.__compile__ = function() { - const self = this; - const chains = [""]; - self.__rules__.forEach(function(rule) { - if (!rule.enabled) { - return; - } - rule.alt.forEach(function(altName) { - if (chains.indexOf(altName) < 0) { - chains.push(altName); - } - }); - }); - self.__cache__ = {}; - chains.forEach(function(chain) { - self.__cache__[chain] = []; - self.__rules__.forEach(function(rule) { - if (!rule.enabled) { - return; - } - if (chain && rule.alt.indexOf(chain) < 0) { - return; - } - self.__cache__[chain].push(rule.fn); - }); - }); -}; -/** -* Ruler.at(name, fn [, options]) -* - name (String): rule name to replace. -* - fn (Function): new rule function. -* - options (Object): new rule options (not mandatory). -* -* Replace rule by name with new function & options. Throws error if name not -* found. -* -* ##### Options: -* -* - __alt__ - array with names of "alternate" chains. -* -* ##### Example -* -* Replace existing typographer replacement rule with new one: -* -* ```javascript -* var md = require('markdown-it')(); -* -* md.core.ruler.at('replacements', function replace(state) { -* //... -* }); -* ``` -**/ -Ruler.prototype.at = function(name, fn, options) { - const index = this.__find__(name); - const opt = options || {}; - if (index === -1) { - throw new Error("Parser rule not found: " + name); - } - this.__rules__[index].fn = fn; - this.__rules__[index].alt = opt.alt || []; - this.__cache__ = null; -}; -/** -* Ruler.before(beforeName, ruleName, fn [, options]) -* - beforeName (String): new rule will be added before this one. -* - ruleName (String): name of added rule. -* - fn (Function): rule function. -* - options (Object): rule options (not mandatory). -* -* Add new rule to chain before one with given name. See also -* [[Ruler.after]], [[Ruler.push]]. -* -* ##### Options: -* -* - __alt__ - array with names of "alternate" chains. -* -* ##### Example -* -* ```javascript -* var md = require('markdown-it')(); -* -* md.block.ruler.before('paragraph', 'my_rule', function replace(state) { -* //... -* }); -* ``` -**/ -Ruler.prototype.before = function(beforeName, ruleName, fn, options) { - const index = this.__find__(beforeName); - const opt = options || {}; - if (index === -1) { - throw new Error("Parser rule not found: " + beforeName); - } - this.__rules__.splice(index, 0, { - name: ruleName, - enabled: true, - fn, - alt: opt.alt || [] - }); - this.__cache__ = null; -}; -/** -* Ruler.after(afterName, ruleName, fn [, options]) -* - afterName (String): new rule will be added after this one. -* - ruleName (String): name of added rule. -* - fn (Function): rule function. -* - options (Object): rule options (not mandatory). -* -* Add new rule to chain after one with given name. See also -* [[Ruler.before]], [[Ruler.push]]. -* -* ##### Options: -* -* - __alt__ - array with names of "alternate" chains. -* -* ##### Example -* -* ```javascript -* var md = require('markdown-it')(); -* -* md.inline.ruler.after('text', 'my_rule', function replace(state) { -* //... -* }); -* ``` -**/ -Ruler.prototype.after = function(afterName, ruleName, fn, options) { - const index = this.__find__(afterName); - const opt = options || {}; - if (index === -1) { - throw new Error("Parser rule not found: " + afterName); - } - this.__rules__.splice(index + 1, 0, { - name: ruleName, - enabled: true, - fn, - alt: opt.alt || [] - }); - this.__cache__ = null; -}; -/** -* Ruler.push(ruleName, fn [, options]) -* - ruleName (String): name of added rule. -* - fn (Function): rule function. -* - options (Object): rule options (not mandatory). -* -* Push new rule to the end of chain. See also -* [[Ruler.before]], [[Ruler.after]]. -* -* ##### Options: -* -* - __alt__ - array with names of "alternate" chains. -* -* ##### Example -* -* ```javascript -* var md = require('markdown-it')(); -* -* md.core.ruler.push('my_rule', function replace(state) { -* //... -* }); -* ``` -**/ -Ruler.prototype.push = function(ruleName, fn, options) { - const opt = options || {}; - this.__rules__.push({ - name: ruleName, - enabled: true, - fn, - alt: opt.alt || [] - }); - this.__cache__ = null; -}; -/** -* Ruler.enable(list [, ignoreInvalid]) -> Array -* - list (String|Array): list of rule names to enable. -* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found. -* -* Enable rules with given names. If any rule name not found - throw Error. -* Errors can be disabled by second param. -* -* Returns list of found rule names (if no exception happened). -* -* See also [[Ruler.disable]], [[Ruler.enableOnly]]. -**/ -Ruler.prototype.enable = function(list$1, ignoreInvalid) { - if (!Array.isArray(list$1)) { - list$1 = [list$1]; - } - const result = []; - list$1.forEach(function(name) { - const idx = this.__find__(name); - if (idx < 0) { - if (ignoreInvalid) { - return; - } - throw new Error("Rules manager: invalid rule name " + name); - } - this.__rules__[idx].enabled = true; - result.push(name); - }, this); - this.__cache__ = null; - return result; -}; -/** -* Ruler.enableOnly(list [, ignoreInvalid]) -* - list (String|Array): list of rule names to enable (whitelist). -* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found. -* -* Enable rules with given names, and disable everything else. If any rule name -* not found - throw Error. Errors can be disabled by second param. -* -* See also [[Ruler.disable]], [[Ruler.enable]]. -**/ -Ruler.prototype.enableOnly = function(list$1, ignoreInvalid) { - if (!Array.isArray(list$1)) { - list$1 = [list$1]; - } - this.__rules__.forEach(function(rule) { - rule.enabled = false; - }); - this.enable(list$1, ignoreInvalid); -}; -/** -* Ruler.disable(list [, ignoreInvalid]) -> Array -* - list (String|Array): list of rule names to disable. -* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found. -* -* Disable rules with given names. If any rule name not found - throw Error. -* Errors can be disabled by second param. -* -* Returns list of found rule names (if no exception happened). -* -* See also [[Ruler.enable]], [[Ruler.enableOnly]]. -**/ -Ruler.prototype.disable = function(list$1, ignoreInvalid) { - if (!Array.isArray(list$1)) { - list$1 = [list$1]; - } - const result = []; - list$1.forEach(function(name) { - const idx = this.__find__(name); - if (idx < 0) { - if (ignoreInvalid) { - return; - } - throw new Error("Rules manager: invalid rule name " + name); - } - this.__rules__[idx].enabled = false; - result.push(name); - }, this); - this.__cache__ = null; - return result; -}; -/** -* Ruler.getRules(chainName) -> Array -* -* Return array of active functions (rules) for given chain name. It analyzes -* rules configuration, compiles caches if not exists and returns result. -* -* Default chain name is `''` (empty string). It can't be skipped. That's -* done intentionally, to keep signature monomorphic for high speed. -**/ -Ruler.prototype.getRules = function(chainName) { - if (this.__cache__ === null) { - this.__compile__(); - } - return this.__cache__[chainName] || []; -}; -var ruler_default = Ruler; - -/** -* class Token -**/ -/** -* new Token(type, tag, nesting) -* -* Create new token and fill passed properties. -**/ -function Token(type$2, tag, nesting) { - /** - * Token#type -> String - * - * Type of the token (string, e.g. "paragraph_open") - **/ - this.type = type$2; - /** - * Token#tag -> String - * - * html tag name, e.g. "p" - **/ - this.tag = tag; - /** - * Token#attrs -> Array - * - * Html attributes. Format: `[ [ name1, value1 ], [ name2, value2 ] ]` - **/ - this.attrs = null; - /** - * Token#map -> Array - * - * Source map info. Format: `[ line_begin, line_end ]` - **/ - this.map = null; - /** - * Token#nesting -> Number - * - * Level change (number in {-1, 0, 1} set), where: - * - * - `1` means the tag is opening - * - `0` means the tag is self-closing - * - `-1` means the tag is closing - **/ - this.nesting = nesting; - /** - * Token#level -> Number - * - * nesting level, the same as `state.level` - **/ - this.level = 0; - /** - * Token#children -> Array - * - * An array of child nodes (inline and img tokens) - **/ - this.children = null; - /** - * Token#content -> String - * - * In a case of self-closing tag (code, html, fence, etc.), - * it has contents of this tag. - **/ - this.content = ""; - /** - * Token#markup -> String - * - * '*' or '_' for emphasis, fence string for fence, etc. - **/ - this.markup = ""; - /** - * Token#info -> String - * - * Additional information: - * - * - Info string for "fence" tokens - * - The value "auto" for autolink "link_open" and "link_close" tokens - * - The string value of the item marker for ordered-list "list_item_open" tokens - **/ - this.info = ""; - /** - * Token#meta -> Object - * - * A place for plugins to store an arbitrary data - **/ - this.meta = null; - /** - * Token#block -> Boolean - * - * True for block-level tokens, false for inline tokens. - * Used in renderer to calculate line breaks - **/ - this.block = false; - /** - * Token#hidden -> Boolean - * - * If it's true, ignore this element when rendering. Used for tight lists - * to hide paragraphs. - **/ - this.hidden = false; -} -/** -* Token.attrIndex(name) -> Number -* -* Search attribute index by name. -**/ -Token.prototype.attrIndex = function attrIndex(name) { - if (!this.attrs) { - return -1; - } - const attrs = this.attrs; - for (let i$10 = 0, len = attrs.length; i$10 < len; i$10++) { - if (attrs[i$10][0] === name) { - return i$10; - } - } - return -1; -}; -/** -* Token.attrPush(attrData) -* -* Add `[ name, value ]` attribute to list. Init attrs if necessary -**/ -Token.prototype.attrPush = function attrPush(attrData) { - if (this.attrs) { - this.attrs.push(attrData); - } else { - this.attrs = [attrData]; - } -}; -/** -* Token.attrSet(name, value) -* -* Set `name` attribute to `value`. Override old value if exists. -**/ -Token.prototype.attrSet = function attrSet(name, value) { - const idx = this.attrIndex(name); - const attrData = [name, value]; - if (idx < 0) { - this.attrPush(attrData); - } else { - this.attrs[idx] = attrData; - } -}; -/** -* Token.attrGet(name) -* -* Get the value of attribute `name`, or null if it does not exist. -**/ -Token.prototype.attrGet = function attrGet(name) { - const idx = this.attrIndex(name); - let value = null; - if (idx >= 0) { - value = this.attrs[idx][1]; - } - return value; -}; -/** -* Token.attrJoin(name, value) -* -* Join value to existing attribute via space. Or create new attribute if not -* exists. Useful to operate with token classes. -**/ -Token.prototype.attrJoin = function attrJoin(name, value) { - const idx = this.attrIndex(name); - if (idx < 0) { - this.attrPush([name, value]); - } else { - this.attrs[idx][1] = this.attrs[idx][1] + " " + value; - } -}; -var token_default = Token; - -function StateCore(src, md, env) { - this.src = src; - this.env = env; - this.tokens = []; - this.inlineMode = false; - this.md = md; -} -StateCore.prototype.Token = token_default; -var state_core_default = StateCore; - -const NEWLINES_RE = /\r\n?|\n/g; -const NULL_RE = /\0/g; -function normalize(state) { - let str; - str = state.src.replace(NEWLINES_RE, "\n"); - str = str.replace(NULL_RE, "�"); - state.src = str; -} - -function block(state) { - let token; - if (state.inlineMode) { - token = new state.Token("inline", "", 0); - token.content = state.src; - token.map = [0, 1]; - token.children = []; - state.tokens.push(token); - } else { - state.md.block.parse(state.src, state.md, state.env, state.tokens); - } -} - -function inline(state) { - const tokens = state.tokens; - for (let i$10 = 0, l$5 = tokens.length; i$10 < l$5; i$10++) { - const tok = tokens[i$10]; - if (tok.type === "inline") { - state.md.inline.parse(tok.content, state.md, state.env, tok.children); - } - } -} - -function isLinkOpen$1(str) { - return /^\s]/i.test(str); -} -function isLinkClose$1(str) { - return /^<\/a\s*>/i.test(str); -} -function linkify$1(state) { - const blockTokens = state.tokens; - if (!state.md.options.linkify) { - return; - } - for (let j$2 = 0, l$5 = blockTokens.length; j$2 < l$5; j$2++) { - if (blockTokens[j$2].type !== "inline" || !state.md.linkify.pretest(blockTokens[j$2].content)) { - continue; - } - let tokens = blockTokens[j$2].children; - let htmlLinkLevel = 0; - for (let i$10 = tokens.length - 1; i$10 >= 0; i$10--) { - const currentToken = tokens[i$10]; - if (currentToken.type === "link_close") { - i$10--; - while (tokens[i$10].level !== currentToken.level && tokens[i$10].type !== "link_open") { - i$10--; - } - continue; - } - if (currentToken.type === "html_inline") { - if (isLinkOpen$1(currentToken.content) && htmlLinkLevel > 0) { - htmlLinkLevel--; - } - if (isLinkClose$1(currentToken.content)) { - htmlLinkLevel++; - } - } - if (htmlLinkLevel > 0) { - continue; - } - if (currentToken.type === "text" && state.md.linkify.test(currentToken.content)) { - const text$1 = currentToken.content; - let links = state.md.linkify.match(text$1); - const nodes = []; - let level = currentToken.level; - let lastPos = 0; - if (links.length > 0 && links[0].index === 0 && i$10 > 0 && tokens[i$10 - 1].type === "text_special") { - links = links.slice(1); - } - for (let ln = 0; ln < links.length; ln++) { - const url = links[ln].url; - const fullUrl = state.md.normalizeLink(url); - if (!state.md.validateLink(fullUrl)) { - continue; - } - let urlText = links[ln].text; - if (!links[ln].schema) { - urlText = state.md.normalizeLinkText("http://" + urlText).replace(/^http:\/\//, ""); - } else if (links[ln].schema === "mailto:" && !/^mailto:/i.test(urlText)) { - urlText = state.md.normalizeLinkText("mailto:" + urlText).replace(/^mailto:/, ""); - } else { - urlText = state.md.normalizeLinkText(urlText); - } - const pos = links[ln].index; - if (pos > lastPos) { - const token = new state.Token("text", "", 0); - token.content = text$1.slice(lastPos, pos); - token.level = level; - nodes.push(token); - } - const token_o = new state.Token("link_open", "a", 1); - token_o.attrs = [["href", fullUrl]]; - token_o.level = level++; - token_o.markup = "linkify"; - token_o.info = "auto"; - nodes.push(token_o); - const token_t = new state.Token("text", "", 0); - token_t.content = urlText; - token_t.level = level; - nodes.push(token_t); - const token_c = new state.Token("link_close", "a", -1); - token_c.level = --level; - token_c.markup = "linkify"; - token_c.info = "auto"; - nodes.push(token_c); - lastPos = links[ln].lastIndex; - } - if (lastPos < text$1.length) { - const token = new state.Token("text", "", 0); - token.content = text$1.slice(lastPos); - token.level = level; - nodes.push(token); - } - blockTokens[j$2].children = tokens = arrayReplaceAt(tokens, i$10, nodes); - } - } - } -} - -const RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/; -const SCOPED_ABBR_TEST_RE = /\((c|tm|r)\)/i; -const SCOPED_ABBR_RE = /\((c|tm|r)\)/gi; -const SCOPED_ABBR = { - c: "©", - r: "®", - tm: "™" -}; -function replaceFn(match, name) { - return SCOPED_ABBR[name.toLowerCase()]; -} -function replace_scoped(inlineTokens) { - let inside_autolink = 0; - for (let i$10 = inlineTokens.length - 1; i$10 >= 0; i$10--) { - const token = inlineTokens[i$10]; - if (token.type === "text" && !inside_autolink) { - token.content = token.content.replace(SCOPED_ABBR_RE, replaceFn); - } - if (token.type === "link_open" && token.info === "auto") { - inside_autolink--; - } - if (token.type === "link_close" && token.info === "auto") { - inside_autolink++; - } - } -} -function replace_rare(inlineTokens) { - let inside_autolink = 0; - for (let i$10 = inlineTokens.length - 1; i$10 >= 0; i$10--) { - const token = inlineTokens[i$10]; - if (token.type === "text" && !inside_autolink) { - if (RARE_RE.test(token.content)) { - token.content = token.content.replace(/\+-/g, "±").replace(/\.{2,}/g, "…").replace(/([?!])…/g, "$1..").replace(/([?!]){4,}/g, "$1$1$1").replace(/,{2,}/g, ",").replace(/(^|[^-])---(?=[^-]|$)/gm, "$1—").replace(/(^|\s)--(?=\s|$)/gm, "$1–").replace(/(^|[^-\s])--(?=[^-\s]|$)/gm, "$1–"); - } - } - if (token.type === "link_open" && token.info === "auto") { - inside_autolink--; - } - if (token.type === "link_close" && token.info === "auto") { - inside_autolink++; - } - } -} -function replace(state) { - let blkIdx; - if (!state.md.options.typographer) { - return; - } - for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) { - if (state.tokens[blkIdx].type !== "inline") { - continue; - } - if (SCOPED_ABBR_TEST_RE.test(state.tokens[blkIdx].content)) { - replace_scoped(state.tokens[blkIdx].children); - } - if (RARE_RE.test(state.tokens[blkIdx].content)) { - replace_rare(state.tokens[blkIdx].children); - } - } -} - -const QUOTE_TEST_RE = /['"]/; -const QUOTE_RE = /['"]/g; -const APOSTROPHE = "’"; -function replaceAt(str, index, ch) { - return str.slice(0, index) + ch + str.slice(index + 1); -} -function process_inlines(tokens, state) { - let j$2; - const stack = []; - for (let i$10 = 0; i$10 < tokens.length; i$10++) { - const token = tokens[i$10]; - const thisLevel = tokens[i$10].level; - for (j$2 = stack.length - 1; j$2 >= 0; j$2--) { - if (stack[j$2].level <= thisLevel) { - break; - } - } - stack.length = j$2 + 1; - if (token.type !== "text") { - continue; - } - let text$1 = token.content; - let pos = 0; - let max = text$1.length; - OUTER: while (pos < max) { - QUOTE_RE.lastIndex = pos; - const t$7 = QUOTE_RE.exec(text$1); - if (!t$7) { - break; - } - let canOpen = true; - let canClose = true; - pos = t$7.index + 1; - const isSingle = t$7[0] === "'"; - let lastChar = 32; - if (t$7.index - 1 >= 0) { - lastChar = text$1.charCodeAt(t$7.index - 1); - } else { - for (j$2 = i$10 - 1; j$2 >= 0; j$2--) { - if (tokens[j$2].type === "softbreak" || tokens[j$2].type === "hardbreak") break; - if (!tokens[j$2].content) continue; - lastChar = tokens[j$2].content.charCodeAt(tokens[j$2].content.length - 1); - break; - } - } - let nextChar = 32; - if (pos < max) { - nextChar = text$1.charCodeAt(pos); - } else { - for (j$2 = i$10 + 1; j$2 < tokens.length; j$2++) { - if (tokens[j$2].type === "softbreak" || tokens[j$2].type === "hardbreak") break; - if (!tokens[j$2].content) continue; - nextChar = tokens[j$2].content.charCodeAt(0); - break; - } - } - const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar)); - const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)); - const isLastWhiteSpace = isWhiteSpace(lastChar); - const isNextWhiteSpace = isWhiteSpace(nextChar); - if (isNextWhiteSpace) { - canOpen = false; - } else if (isNextPunctChar) { - if (!(isLastWhiteSpace || isLastPunctChar)) { - canOpen = false; - } - } - if (isLastWhiteSpace) { - canClose = false; - } else if (isLastPunctChar) { - if (!(isNextWhiteSpace || isNextPunctChar)) { - canClose = false; - } - } - if (nextChar === 34 && t$7[0] === "\"") { - if (lastChar >= 48 && lastChar <= 57) { - canClose = canOpen = false; - } - } - if (canOpen && canClose) { - canOpen = isLastPunctChar; - canClose = isNextPunctChar; - } - if (!canOpen && !canClose) { - if (isSingle) { - token.content = replaceAt(token.content, t$7.index, APOSTROPHE); - } - continue; - } - if (canClose) { - for (j$2 = stack.length - 1; j$2 >= 0; j$2--) { - let item = stack[j$2]; - if (stack[j$2].level < thisLevel) { - break; - } - if (item.single === isSingle && stack[j$2].level === thisLevel) { - item = stack[j$2]; - let openQuote; - let closeQuote; - if (isSingle) { - openQuote = state.md.options.quotes[2]; - closeQuote = state.md.options.quotes[3]; - } else { - openQuote = state.md.options.quotes[0]; - closeQuote = state.md.options.quotes[1]; - } - token.content = replaceAt(token.content, t$7.index, closeQuote); - tokens[item.token].content = replaceAt(tokens[item.token].content, item.pos, openQuote); - pos += closeQuote.length - 1; - if (item.token === i$10) { - pos += openQuote.length - 1; - } - text$1 = token.content; - max = text$1.length; - stack.length = j$2; - continue OUTER; - } - } - } - if (canOpen) { - stack.push({ - token: i$10, - pos: t$7.index, - single: isSingle, - level: thisLevel - }); - } else if (canClose && isSingle) { - token.content = replaceAt(token.content, t$7.index, APOSTROPHE); - } - } - } -} -function smartquotes(state) { - if (!state.md.options.typographer) { - return; - } - for (let blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) { - if (state.tokens[blkIdx].type !== "inline" || !QUOTE_TEST_RE.test(state.tokens[blkIdx].content)) { - continue; - } - process_inlines(state.tokens[blkIdx].children, state); - } -} - -function text_join(state) { - let curr, last; - const blockTokens = state.tokens; - const l$5 = blockTokens.length; - for (let j$2 = 0; j$2 < l$5; j$2++) { - if (blockTokens[j$2].type !== "inline") continue; - const tokens = blockTokens[j$2].children; - const max = tokens.length; - for (curr = 0; curr < max; curr++) { - if (tokens[curr].type === "text_special") { - tokens[curr].type = "text"; - } - } - for (curr = last = 0; curr < max; curr++) { - if (tokens[curr].type === "text" && curr + 1 < max && tokens[curr + 1].type === "text") { - tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content; - } else { - if (curr !== last) { - tokens[last] = tokens[curr]; - } - last++; - } - } - if (curr !== last) { - tokens.length = last; - } - } -} - -/** internal -* class Core -* -* Top-level rules executor. Glues block/inline parsers and does intermediate -* transformations. -**/ -const _rules$2 = [ - ["normalize", normalize], - ["block", block], - ["inline", inline], - ["linkify", linkify$1], - ["replacements", replace], - ["smartquotes", smartquotes], - ["text_join", text_join] -]; -/** -* new Core() -**/ -function Core() { - /** - * Core#ruler -> Ruler - * - * [[Ruler]] instance. Keep configuration of core rules. - **/ - this.ruler = new ruler_default(); - for (let i$10 = 0; i$10 < _rules$2.length; i$10++) { - this.ruler.push(_rules$2[i$10][0], _rules$2[i$10][1]); - } -} -/** -* Core.process(state) -* -* Executes core chain rules. -**/ -Core.prototype.process = function(state) { - const rules = this.ruler.getRules(""); - for (let i$10 = 0, l$5 = rules.length; i$10 < l$5; i$10++) { - rules[i$10](state); - } -}; -Core.prototype.State = state_core_default; -var parser_core_default = Core; - -function StateBlock(src, md, env, tokens) { - this.src = src; - this.md = md; - this.env = env; - this.tokens = tokens; - this.bMarks = []; - this.eMarks = []; - this.tShift = []; - this.sCount = []; - this.bsCount = []; - this.blkIndent = 0; - this.line = 0; - this.lineMax = 0; - this.tight = false; - this.ddIndent = -1; - this.listIndent = -1; - this.parentType = "root"; - this.level = 0; - const s$9 = this.src; - for (let start = 0, pos = 0, indent = 0, offset = 0, len = s$9.length, indent_found = false; pos < len; pos++) { - const ch = s$9.charCodeAt(pos); - if (!indent_found) { - if (isSpace(ch)) { - indent++; - if (ch === 9) { - offset += 4 - offset % 4; - } else { - offset++; - } - continue; - } else { - indent_found = true; - } - } - if (ch === 10 || pos === len - 1) { - if (ch !== 10) { - pos++; - } - this.bMarks.push(start); - this.eMarks.push(pos); - this.tShift.push(indent); - this.sCount.push(offset); - this.bsCount.push(0); - indent_found = false; - indent = 0; - offset = 0; - start = pos + 1; - } - } - this.bMarks.push(s$9.length); - this.eMarks.push(s$9.length); - this.tShift.push(0); - this.sCount.push(0); - this.bsCount.push(0); - this.lineMax = this.bMarks.length - 1; -} -StateBlock.prototype.push = function(type$2, tag, nesting) { - const token = new token_default(type$2, tag, nesting); - token.block = true; - if (nesting < 0) this.level--; - token.level = this.level; - if (nesting > 0) this.level++; - this.tokens.push(token); - return token; -}; -StateBlock.prototype.isEmpty = function isEmpty(line) { - return this.bMarks[line] + this.tShift[line] >= this.eMarks[line]; -}; -StateBlock.prototype.skipEmptyLines = function skipEmptyLines(from) { - for (let max = this.lineMax; from < max; from++) { - if (this.bMarks[from] + this.tShift[from] < this.eMarks[from]) { - break; - } - } - return from; -}; -StateBlock.prototype.skipSpaces = function skipSpaces(pos) { - for (let max = this.src.length; pos < max; pos++) { - const ch = this.src.charCodeAt(pos); - if (!isSpace(ch)) { - break; - } - } - return pos; -}; -StateBlock.prototype.skipSpacesBack = function skipSpacesBack(pos, min) { - if (pos <= min) { - return pos; - } - while (pos > min) { - if (!isSpace(this.src.charCodeAt(--pos))) { - return pos + 1; - } - } - return pos; -}; -StateBlock.prototype.skipChars = function skipChars(pos, code$1) { - for (let max = this.src.length; pos < max; pos++) { - if (this.src.charCodeAt(pos) !== code$1) { - break; - } - } - return pos; -}; -StateBlock.prototype.skipCharsBack = function skipCharsBack(pos, code$1, min) { - if (pos <= min) { - return pos; - } - while (pos > min) { - if (code$1 !== this.src.charCodeAt(--pos)) { - return pos + 1; - } - } - return pos; -}; -StateBlock.prototype.getLines = function getLines(begin, end, indent, keepLastLF) { - if (begin >= end) { - return ""; - } - const queue = new Array(end - begin); - for (let i$10 = 0, line = begin; line < end; line++, i$10++) { - let lineIndent = 0; - const lineStart = this.bMarks[line]; - let first = lineStart; - let last; - if (line + 1 < end || keepLastLF) { - last = this.eMarks[line] + 1; - } else { - last = this.eMarks[line]; - } - while (first < last && lineIndent < indent) { - const ch = this.src.charCodeAt(first); - if (isSpace(ch)) { - if (ch === 9) { - lineIndent += 4 - (lineIndent + this.bsCount[line]) % 4; - } else { - lineIndent++; - } - } else if (first - lineStart < this.tShift[line]) { - lineIndent++; - } else { - break; - } - first++; - } - if (lineIndent > indent) { - queue[i$10] = new Array(lineIndent - indent + 1).join(" ") + this.src.slice(first, last); - } else { - queue[i$10] = this.src.slice(first, last); - } - } - return queue.join(""); -}; -StateBlock.prototype.Token = token_default; -var state_block_default = StateBlock; - -const MAX_AUTOCOMPLETED_CELLS = 65536; -function getLine(state, line) { - const pos = state.bMarks[line] + state.tShift[line]; - const max = state.eMarks[line]; - return state.src.slice(pos, max); -} -function escapedSplit(str) { - const result = []; - const max = str.length; - let pos = 0; - let ch = str.charCodeAt(pos); - let isEscaped = false; - let lastPos = 0; - let current = ""; - while (pos < max) { - if (ch === 124) { - if (!isEscaped) { - result.push(current + str.substring(lastPos, pos)); - current = ""; - lastPos = pos + 1; - } else { - current += str.substring(lastPos, pos - 1); - lastPos = pos; - } - } - isEscaped = ch === 92; - pos++; - ch = str.charCodeAt(pos); - } - result.push(current + str.substring(lastPos)); - return result; -} -function table(state, startLine, endLine, silent) { - if (startLine + 2 > endLine) { - return false; - } - let nextLine = startLine + 1; - if (state.sCount[nextLine] < state.blkIndent) { - return false; - } - if (state.sCount[nextLine] - state.blkIndent >= 4) { - return false; - } - let pos = state.bMarks[nextLine] + state.tShift[nextLine]; - if (pos >= state.eMarks[nextLine]) { - return false; - } - const firstCh = state.src.charCodeAt(pos++); - if (firstCh !== 124 && firstCh !== 45 && firstCh !== 58) { - return false; - } - if (pos >= state.eMarks[nextLine]) { - return false; - } - const secondCh = state.src.charCodeAt(pos++); - if (secondCh !== 124 && secondCh !== 45 && secondCh !== 58 && !isSpace(secondCh)) { - return false; - } - if (firstCh === 45 && isSpace(secondCh)) { - return false; - } - while (pos < state.eMarks[nextLine]) { - const ch = state.src.charCodeAt(pos); - if (ch !== 124 && ch !== 45 && ch !== 58 && !isSpace(ch)) { - return false; - } - pos++; - } - let lineText = getLine(state, startLine + 1); - let columns = lineText.split("|"); - const aligns = []; - for (let i$10 = 0; i$10 < columns.length; i$10++) { - const t$7 = columns[i$10].trim(); - if (!t$7) { - if (i$10 === 0 || i$10 === columns.length - 1) { - continue; - } else { - return false; - } - } - if (!/^:?-+:?$/.test(t$7)) { - return false; - } - if (t$7.charCodeAt(t$7.length - 1) === 58) { - aligns.push(t$7.charCodeAt(0) === 58 ? "center" : "right"); - } else if (t$7.charCodeAt(0) === 58) { - aligns.push("left"); - } else { - aligns.push(""); - } - } - lineText = getLine(state, startLine).trim(); - if (lineText.indexOf("|") === -1) { - return false; - } - if (state.sCount[startLine] - state.blkIndent >= 4) { - return false; - } - columns = escapedSplit(lineText); - if (columns.length && columns[0] === "") columns.shift(); - if (columns.length && columns[columns.length - 1] === "") columns.pop(); - const columnCount = columns.length; - if (columnCount === 0 || columnCount !== aligns.length) { - return false; - } - if (silent) { - return true; - } - const oldParentType = state.parentType; - state.parentType = "table"; - const terminatorRules = state.md.block.ruler.getRules("blockquote"); - const token_to = state.push("table_open", "table", 1); - const tableLines = [startLine, 0]; - token_to.map = tableLines; - const token_tho = state.push("thead_open", "thead", 1); - token_tho.map = [startLine, startLine + 1]; - const token_htro = state.push("tr_open", "tr", 1); - token_htro.map = [startLine, startLine + 1]; - for (let i$10 = 0; i$10 < columns.length; i$10++) { - const token_ho = state.push("th_open", "th", 1); - if (aligns[i$10]) { - token_ho.attrs = [["style", "text-align:" + aligns[i$10]]]; - } - const token_il = state.push("inline", "", 0); - token_il.content = columns[i$10].trim(); - token_il.children = []; - state.push("th_close", "th", -1); - } - state.push("tr_close", "tr", -1); - state.push("thead_close", "thead", -1); - let tbodyLines; - let autocompletedCells = 0; - for (nextLine = startLine + 2; nextLine < endLine; nextLine++) { - if (state.sCount[nextLine] < state.blkIndent) { - break; - } - let terminate = false; - for (let i$10 = 0, l$5 = terminatorRules.length; i$10 < l$5; i$10++) { - if (terminatorRules[i$10](state, nextLine, endLine, true)) { - terminate = true; - break; - } - } - if (terminate) { - break; - } - lineText = getLine(state, nextLine).trim(); - if (!lineText) { - break; - } - if (state.sCount[nextLine] - state.blkIndent >= 4) { - break; - } - columns = escapedSplit(lineText); - if (columns.length && columns[0] === "") columns.shift(); - if (columns.length && columns[columns.length - 1] === "") columns.pop(); - autocompletedCells += columnCount - columns.length; - if (autocompletedCells > MAX_AUTOCOMPLETED_CELLS) { - break; - } - if (nextLine === startLine + 2) { - const token_tbo = state.push("tbody_open", "tbody", 1); - token_tbo.map = tbodyLines = [startLine + 2, 0]; - } - const token_tro = state.push("tr_open", "tr", 1); - token_tro.map = [nextLine, nextLine + 1]; - for (let i$10 = 0; i$10 < columnCount; i$10++) { - const token_tdo = state.push("td_open", "td", 1); - if (aligns[i$10]) { - token_tdo.attrs = [["style", "text-align:" + aligns[i$10]]]; - } - const token_il = state.push("inline", "", 0); - token_il.content = columns[i$10] ? columns[i$10].trim() : ""; - token_il.children = []; - state.push("td_close", "td", -1); - } - state.push("tr_close", "tr", -1); - } - if (tbodyLines) { - state.push("tbody_close", "tbody", -1); - tbodyLines[1] = nextLine; - } - state.push("table_close", "table", -1); - tableLines[1] = nextLine; - state.parentType = oldParentType; - state.line = nextLine; - return true; -} - -function code(state, startLine, endLine) { - if (state.sCount[startLine] - state.blkIndent < 4) { - return false; - } - let nextLine = startLine + 1; - let last = nextLine; - while (nextLine < endLine) { - if (state.isEmpty(nextLine)) { - nextLine++; - continue; - } - if (state.sCount[nextLine] - state.blkIndent >= 4) { - nextLine++; - last = nextLine; - continue; - } - break; - } - state.line = last; - const token = state.push("code_block", "code", 0); - token.content = state.getLines(startLine, last, 4 + state.blkIndent, false) + "\n"; - token.map = [startLine, state.line]; - return true; -} - -function fence(state, startLine, endLine, silent) { - let pos = state.bMarks[startLine] + state.tShift[startLine]; - let max = state.eMarks[startLine]; - if (state.sCount[startLine] - state.blkIndent >= 4) { - return false; - } - if (pos + 3 > max) { - return false; - } - const marker = state.src.charCodeAt(pos); - if (marker !== 126 && marker !== 96) { - return false; - } - let mem = pos; - pos = state.skipChars(pos, marker); - let len = pos - mem; - if (len < 3) { - return false; - } - const markup = state.src.slice(mem, pos); - const params = state.src.slice(pos, max); - if (marker === 96) { - if (params.indexOf(String.fromCharCode(marker)) >= 0) { - return false; - } - } - if (silent) { - return true; - } - let nextLine = startLine; - let haveEndMarker = false; - for (;;) { - nextLine++; - if (nextLine >= endLine) { - break; - } - pos = mem = state.bMarks[nextLine] + state.tShift[nextLine]; - max = state.eMarks[nextLine]; - if (pos < max && state.sCount[nextLine] < state.blkIndent) { - break; - } - if (state.src.charCodeAt(pos) !== marker) { - continue; - } - if (state.sCount[nextLine] - state.blkIndent >= 4) { - continue; - } - pos = state.skipChars(pos, marker); - if (pos - mem < len) { - continue; - } - pos = state.skipSpaces(pos); - if (pos < max) { - continue; - } - haveEndMarker = true; - break; - } - len = state.sCount[startLine]; - state.line = nextLine + (haveEndMarker ? 1 : 0); - const token = state.push("fence", "code", 0); - token.info = params; - token.content = state.getLines(startLine + 1, nextLine, len, true); - token.markup = markup; - token.map = [startLine, state.line]; - return true; -} - -function blockquote(state, startLine, endLine, silent) { - let pos = state.bMarks[startLine] + state.tShift[startLine]; - let max = state.eMarks[startLine]; - const oldLineMax = state.lineMax; - if (state.sCount[startLine] - state.blkIndent >= 4) { - return false; - } - if (state.src.charCodeAt(pos) !== 62) { - return false; - } - if (silent) { - return true; - } - const oldBMarks = []; - const oldBSCount = []; - const oldSCount = []; - const oldTShift = []; - const terminatorRules = state.md.block.ruler.getRules("blockquote"); - const oldParentType = state.parentType; - state.parentType = "blockquote"; - let lastLineEmpty = false; - let nextLine; - for (nextLine = startLine; nextLine < endLine; nextLine++) { - const isOutdented = state.sCount[nextLine] < state.blkIndent; - pos = state.bMarks[nextLine] + state.tShift[nextLine]; - max = state.eMarks[nextLine]; - if (pos >= max) { - break; - } - if (state.src.charCodeAt(pos++) === 62 && !isOutdented) { - let initial = state.sCount[nextLine] + 1; - let spaceAfterMarker; - let adjustTab; - if (state.src.charCodeAt(pos) === 32) { - pos++; - initial++; - adjustTab = false; - spaceAfterMarker = true; - } else if (state.src.charCodeAt(pos) === 9) { - spaceAfterMarker = true; - if ((state.bsCount[nextLine] + initial) % 4 === 3) { - pos++; - initial++; - adjustTab = false; - } else { - adjustTab = true; - } - } else { - spaceAfterMarker = false; - } - let offset = initial; - oldBMarks.push(state.bMarks[nextLine]); - state.bMarks[nextLine] = pos; - while (pos < max) { - const ch = state.src.charCodeAt(pos); - if (isSpace(ch)) { - if (ch === 9) { - offset += 4 - (offset + state.bsCount[nextLine] + (adjustTab ? 1 : 0)) % 4; - } else { - offset++; - } - } else { - break; - } - pos++; - } - lastLineEmpty = pos >= max; - oldBSCount.push(state.bsCount[nextLine]); - state.bsCount[nextLine] = state.sCount[nextLine] + 1 + (spaceAfterMarker ? 1 : 0); - oldSCount.push(state.sCount[nextLine]); - state.sCount[nextLine] = offset - initial; - oldTShift.push(state.tShift[nextLine]); - state.tShift[nextLine] = pos - state.bMarks[nextLine]; - continue; - } - if (lastLineEmpty) { - break; - } - let terminate = false; - for (let i$10 = 0, l$5 = terminatorRules.length; i$10 < l$5; i$10++) { - if (terminatorRules[i$10](state, nextLine, endLine, true)) { - terminate = true; - break; - } - } - if (terminate) { - state.lineMax = nextLine; - if (state.blkIndent !== 0) { - oldBMarks.push(state.bMarks[nextLine]); - oldBSCount.push(state.bsCount[nextLine]); - oldTShift.push(state.tShift[nextLine]); - oldSCount.push(state.sCount[nextLine]); - state.sCount[nextLine] -= state.blkIndent; - } - break; - } - oldBMarks.push(state.bMarks[nextLine]); - oldBSCount.push(state.bsCount[nextLine]); - oldTShift.push(state.tShift[nextLine]); - oldSCount.push(state.sCount[nextLine]); - state.sCount[nextLine] = -1; - } - const oldIndent = state.blkIndent; - state.blkIndent = 0; - const token_o = state.push("blockquote_open", "blockquote", 1); - token_o.markup = ">"; - const lines = [startLine, 0]; - token_o.map = lines; - state.md.block.tokenize(state, startLine, nextLine); - const token_c = state.push("blockquote_close", "blockquote", -1); - token_c.markup = ">"; - state.lineMax = oldLineMax; - state.parentType = oldParentType; - lines[1] = state.line; - for (let i$10 = 0; i$10 < oldTShift.length; i$10++) { - state.bMarks[i$10 + startLine] = oldBMarks[i$10]; - state.tShift[i$10 + startLine] = oldTShift[i$10]; - state.sCount[i$10 + startLine] = oldSCount[i$10]; - state.bsCount[i$10 + startLine] = oldBSCount[i$10]; - } - state.blkIndent = oldIndent; - return true; -} - -function hr(state, startLine, endLine, silent) { - const max = state.eMarks[startLine]; - if (state.sCount[startLine] - state.blkIndent >= 4) { - return false; - } - let pos = state.bMarks[startLine] + state.tShift[startLine]; - const marker = state.src.charCodeAt(pos++); - if (marker !== 42 && marker !== 45 && marker !== 95) { - return false; - } - let cnt = 1; - while (pos < max) { - const ch = state.src.charCodeAt(pos++); - if (ch !== marker && !isSpace(ch)) { - return false; - } - if (ch === marker) { - cnt++; - } - } - if (cnt < 3) { - return false; - } - if (silent) { - return true; - } - state.line = startLine + 1; - const token = state.push("hr", "hr", 0); - token.map = [startLine, state.line]; - token.markup = Array(cnt + 1).join(String.fromCharCode(marker)); - return true; -} - -function skipBulletListMarker(state, startLine) { - const max = state.eMarks[startLine]; - let pos = state.bMarks[startLine] + state.tShift[startLine]; - const marker = state.src.charCodeAt(pos++); - if (marker !== 42 && marker !== 45 && marker !== 43) { - return -1; - } - if (pos < max) { - const ch = state.src.charCodeAt(pos); - if (!isSpace(ch)) { - return -1; - } - } - return pos; -} -function skipOrderedListMarker(state, startLine) { - const start = state.bMarks[startLine] + state.tShift[startLine]; - const max = state.eMarks[startLine]; - let pos = start; - if (pos + 1 >= max) { - return -1; - } - let ch = state.src.charCodeAt(pos++); - if (ch < 48 || ch > 57) { - return -1; - } - for (;;) { - if (pos >= max) { - return -1; - } - ch = state.src.charCodeAt(pos++); - if (ch >= 48 && ch <= 57) { - if (pos - start >= 10) { - return -1; - } - continue; - } - if (ch === 41 || ch === 46) { - break; - } - return -1; - } - if (pos < max) { - ch = state.src.charCodeAt(pos); - if (!isSpace(ch)) { - return -1; - } - } - return pos; -} -function markTightParagraphs(state, idx) { - const level = state.level + 2; - for (let i$10 = idx + 2, l$5 = state.tokens.length - 2; i$10 < l$5; i$10++) { - if (state.tokens[i$10].level === level && state.tokens[i$10].type === "paragraph_open") { - state.tokens[i$10 + 2].hidden = true; - state.tokens[i$10].hidden = true; - i$10 += 2; - } - } -} -function list(state, startLine, endLine, silent) { - let max, pos, start, token; - let nextLine = startLine; - let tight = true; - if (state.sCount[nextLine] - state.blkIndent >= 4) { - return false; - } - if (state.listIndent >= 0 && state.sCount[nextLine] - state.listIndent >= 4 && state.sCount[nextLine] < state.blkIndent) { - return false; - } - let isTerminatingParagraph = false; - if (silent && state.parentType === "paragraph") { - if (state.sCount[nextLine] >= state.blkIndent) { - isTerminatingParagraph = true; - } - } - let isOrdered; - let markerValue; - let posAfterMarker; - if ((posAfterMarker = skipOrderedListMarker(state, nextLine)) >= 0) { - isOrdered = true; - start = state.bMarks[nextLine] + state.tShift[nextLine]; - markerValue = Number(state.src.slice(start, posAfterMarker - 1)); - if (isTerminatingParagraph && markerValue !== 1) return false; - } else if ((posAfterMarker = skipBulletListMarker(state, nextLine)) >= 0) { - isOrdered = false; - } else { - return false; - } - if (isTerminatingParagraph) { - if (state.skipSpaces(posAfterMarker) >= state.eMarks[nextLine]) return false; - } - if (silent) { - return true; - } - const markerCharCode = state.src.charCodeAt(posAfterMarker - 1); - const listTokIdx = state.tokens.length; - if (isOrdered) { - token = state.push("ordered_list_open", "ol", 1); - if (markerValue !== 1) { - token.attrs = [["start", markerValue]]; - } - } else { - token = state.push("bullet_list_open", "ul", 1); - } - const listLines = [nextLine, 0]; - token.map = listLines; - token.markup = String.fromCharCode(markerCharCode); - let prevEmptyEnd = false; - const terminatorRules = state.md.block.ruler.getRules("list"); - const oldParentType = state.parentType; - state.parentType = "list"; - while (nextLine < endLine) { - pos = posAfterMarker; - max = state.eMarks[nextLine]; - const initial = state.sCount[nextLine] + posAfterMarker - (state.bMarks[nextLine] + state.tShift[nextLine]); - let offset = initial; - while (pos < max) { - const ch = state.src.charCodeAt(pos); - if (ch === 9) { - offset += 4 - (offset + state.bsCount[nextLine]) % 4; - } else if (ch === 32) { - offset++; - } else { - break; - } - pos++; - } - const contentStart = pos; - let indentAfterMarker; - if (contentStart >= max) { - indentAfterMarker = 1; - } else { - indentAfterMarker = offset - initial; - } - if (indentAfterMarker > 4) { - indentAfterMarker = 1; - } - const indent = initial + indentAfterMarker; - token = state.push("list_item_open", "li", 1); - token.markup = String.fromCharCode(markerCharCode); - const itemLines = [nextLine, 0]; - token.map = itemLines; - if (isOrdered) { - token.info = state.src.slice(start, posAfterMarker - 1); - } - const oldTight = state.tight; - const oldTShift = state.tShift[nextLine]; - const oldSCount = state.sCount[nextLine]; - const oldListIndent = state.listIndent; - state.listIndent = state.blkIndent; - state.blkIndent = indent; - state.tight = true; - state.tShift[nextLine] = contentStart - state.bMarks[nextLine]; - state.sCount[nextLine] = offset; - if (contentStart >= max && state.isEmpty(nextLine + 1)) { - state.line = Math.min(state.line + 2, endLine); - } else { - state.md.block.tokenize(state, nextLine, endLine, true); - } - if (!state.tight || prevEmptyEnd) { - tight = false; - } - prevEmptyEnd = state.line - nextLine > 1 && state.isEmpty(state.line - 1); - state.blkIndent = state.listIndent; - state.listIndent = oldListIndent; - state.tShift[nextLine] = oldTShift; - state.sCount[nextLine] = oldSCount; - state.tight = oldTight; - token = state.push("list_item_close", "li", -1); - token.markup = String.fromCharCode(markerCharCode); - nextLine = state.line; - itemLines[1] = nextLine; - if (nextLine >= endLine) { - break; - } - if (state.sCount[nextLine] < state.blkIndent) { - break; - } - if (state.sCount[nextLine] - state.blkIndent >= 4) { - break; - } - let terminate = false; - for (let i$10 = 0, l$5 = terminatorRules.length; i$10 < l$5; i$10++) { - if (terminatorRules[i$10](state, nextLine, endLine, true)) { - terminate = true; - break; - } - } - if (terminate) { - break; - } - if (isOrdered) { - posAfterMarker = skipOrderedListMarker(state, nextLine); - if (posAfterMarker < 0) { - break; - } - start = state.bMarks[nextLine] + state.tShift[nextLine]; - } else { - posAfterMarker = skipBulletListMarker(state, nextLine); - if (posAfterMarker < 0) { - break; - } - } - if (markerCharCode !== state.src.charCodeAt(posAfterMarker - 1)) { - break; - } - } - if (isOrdered) { - token = state.push("ordered_list_close", "ol", -1); - } else { - token = state.push("bullet_list_close", "ul", -1); - } - token.markup = String.fromCharCode(markerCharCode); - listLines[1] = nextLine; - state.line = nextLine; - state.parentType = oldParentType; - if (tight) { - markTightParagraphs(state, listTokIdx); - } - return true; -} - -function reference(state, startLine, _endLine, silent) { - let pos = state.bMarks[startLine] + state.tShift[startLine]; - let max = state.eMarks[startLine]; - let nextLine = startLine + 1; - if (state.sCount[startLine] - state.blkIndent >= 4) { - return false; - } - if (state.src.charCodeAt(pos) !== 91) { - return false; - } - function getNextLine(nextLine$1) { - const endLine = state.lineMax; - if (nextLine$1 >= endLine || state.isEmpty(nextLine$1)) { - return null; - } - let isContinuation = false; - if (state.sCount[nextLine$1] - state.blkIndent > 3) { - isContinuation = true; - } - if (state.sCount[nextLine$1] < 0) { - isContinuation = true; - } - if (!isContinuation) { - const terminatorRules = state.md.block.ruler.getRules("reference"); - const oldParentType = state.parentType; - state.parentType = "reference"; - let terminate = false; - for (let i$10 = 0, l$5 = terminatorRules.length; i$10 < l$5; i$10++) { - if (terminatorRules[i$10](state, nextLine$1, endLine, true)) { - terminate = true; - break; - } - } - state.parentType = oldParentType; - if (terminate) { - return null; - } - } - const pos$1 = state.bMarks[nextLine$1] + state.tShift[nextLine$1]; - const max$1 = state.eMarks[nextLine$1]; - return state.src.slice(pos$1, max$1 + 1); - } - let str = state.src.slice(pos, max + 1); - max = str.length; - let labelEnd = -1; - for (pos = 1; pos < max; pos++) { - const ch = str.charCodeAt(pos); - if (ch === 91) { - return false; - } else if (ch === 93) { - labelEnd = pos; - break; - } else if (ch === 10) { - const lineContent = getNextLine(nextLine); - if (lineContent !== null) { - str += lineContent; - max = str.length; - nextLine++; - } - } else if (ch === 92) { - pos++; - if (pos < max && str.charCodeAt(pos) === 10) { - const lineContent = getNextLine(nextLine); - if (lineContent !== null) { - str += lineContent; - max = str.length; - nextLine++; - } - } - } - } - if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 58) { - return false; - } - for (pos = labelEnd + 2; pos < max; pos++) { - const ch = str.charCodeAt(pos); - if (ch === 10) { - const lineContent = getNextLine(nextLine); - if (lineContent !== null) { - str += lineContent; - max = str.length; - nextLine++; - } - } else if (isSpace(ch)) {} else { - break; - } - } - const destRes = state.md.helpers.parseLinkDestination(str, pos, max); - if (!destRes.ok) { - return false; - } - const href = state.md.normalizeLink(destRes.str); - if (!state.md.validateLink(href)) { - return false; - } - pos = destRes.pos; - const destEndPos = pos; - const destEndLineNo = nextLine; - const start = pos; - for (; pos < max; pos++) { - const ch = str.charCodeAt(pos); - if (ch === 10) { - const lineContent = getNextLine(nextLine); - if (lineContent !== null) { - str += lineContent; - max = str.length; - nextLine++; - } - } else if (isSpace(ch)) {} else { - break; - } - } - let titleRes = state.md.helpers.parseLinkTitle(str, pos, max); - while (titleRes.can_continue) { - const lineContent = getNextLine(nextLine); - if (lineContent === null) break; - str += lineContent; - pos = max; - max = str.length; - nextLine++; - titleRes = state.md.helpers.parseLinkTitle(str, pos, max, titleRes); - } - let title$1; - if (pos < max && start !== pos && titleRes.ok) { - title$1 = titleRes.str; - pos = titleRes.pos; - } else { - title$1 = ""; - pos = destEndPos; - nextLine = destEndLineNo; - } - while (pos < max) { - const ch = str.charCodeAt(pos); - if (!isSpace(ch)) { - break; - } - pos++; - } - if (pos < max && str.charCodeAt(pos) !== 10) { - if (title$1) { - title$1 = ""; - pos = destEndPos; - nextLine = destEndLineNo; - while (pos < max) { - const ch = str.charCodeAt(pos); - if (!isSpace(ch)) { - break; - } - pos++; - } - } - } - if (pos < max && str.charCodeAt(pos) !== 10) { - return false; - } - const label = normalizeReference(str.slice(1, labelEnd)); - if (!label) { - return false; - } - /* istanbul ignore if */ - if (silent) { - return true; - } - if (typeof state.env.references === "undefined") { - state.env.references = {}; - } - if (typeof state.env.references[label] === "undefined") { - state.env.references[label] = { - title: title$1, - href - }; - } - state.line = nextLine; - return true; -} - -var html_blocks_default = [ - "address", - "article", - "aside", - "base", - "basefont", - "blockquote", - "body", - "caption", - "center", - "col", - "colgroup", - "dd", - "details", - "dialog", - "dir", - "div", - "dl", - "dt", - "fieldset", - "figcaption", - "figure", - "footer", - "form", - "frame", - "frameset", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "head", - "header", - "hr", - "html", - "iframe", - "legend", - "li", - "link", - "main", - "menu", - "menuitem", - "nav", - "noframes", - "ol", - "optgroup", - "option", - "p", - "param", - "search", - "section", - "summary", - "table", - "tbody", - "td", - "tfoot", - "th", - "thead", - "title", - "tr", - "track", - "ul" -]; - -const attr_name = "[a-zA-Z_:][a-zA-Z0-9:._-]*"; -const unquoted = "[^\"'=<>`\\x00-\\x20]+"; -const single_quoted = "'[^']*'"; -const double_quoted = "\"[^\"]*\""; -const attr_value = "(?:" + unquoted + "|" + single_quoted + "|" + double_quoted + ")"; -const attribute = "(?:\\s+" + attr_name + "(?:\\s*=\\s*" + attr_value + ")?)"; -const open_tag = "<[A-Za-z][A-Za-z0-9\\-]*" + attribute + "*\\s*\\/?>"; -const close_tag = "<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>"; -const comment = ""; -const processing = "<[?][\\s\\S]*?[?]>"; -const declaration = "]*>"; -const cdata = ""; -const HTML_TAG_RE = new RegExp("^(?:" + open_tag + "|" + close_tag + "|" + comment + "|" + processing + "|" + declaration + "|" + cdata + ")"); -const HTML_OPEN_CLOSE_TAG_RE = new RegExp("^(?:" + open_tag + "|" + close_tag + ")"); - -const HTML_SEQUENCES = [ - [ - /^<(script|pre|style|textarea)(?=(\s|>|$))/i, - /<\/(script|pre|style|textarea)>/i, - true - ], - [ - /^/, - true - ], - [ - /^<\?/, - /\?>/, - true - ], - [ - /^/, - true - ], - [ - /^/, - true - ], - [ - new RegExp("^|$))", "i"), - /^$/, - true - ], - [ - new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + "\\s*$"), - /^$/, - false - ] -]; -function html_block(state, startLine, endLine, silent) { - let pos = state.bMarks[startLine] + state.tShift[startLine]; - let max = state.eMarks[startLine]; - if (state.sCount[startLine] - state.blkIndent >= 4) { - return false; - } - if (!state.md.options.html) { - return false; - } - if (state.src.charCodeAt(pos) !== 60) { - return false; - } - let lineText = state.src.slice(pos, max); - let i$10 = 0; - for (; i$10 < HTML_SEQUENCES.length; i$10++) { - if (HTML_SEQUENCES[i$10][0].test(lineText)) { - break; - } - } - if (i$10 === HTML_SEQUENCES.length) { - return false; - } - if (silent) { - return HTML_SEQUENCES[i$10][2]; - } - let nextLine = startLine + 1; - if (!HTML_SEQUENCES[i$10][1].test(lineText)) { - for (; nextLine < endLine; nextLine++) { - if (state.sCount[nextLine] < state.blkIndent) { - break; - } - pos = state.bMarks[nextLine] + state.tShift[nextLine]; - max = state.eMarks[nextLine]; - lineText = state.src.slice(pos, max); - if (HTML_SEQUENCES[i$10][1].test(lineText)) { - if (lineText.length !== 0) { - nextLine++; - } - break; - } - } - } - state.line = nextLine; - const token = state.push("html_block", "", 0); - token.map = [startLine, nextLine]; - token.content = state.getLines(startLine, nextLine, state.blkIndent, true); - return true; -} - -function heading(state, startLine, endLine, silent) { - let pos = state.bMarks[startLine] + state.tShift[startLine]; - let max = state.eMarks[startLine]; - if (state.sCount[startLine] - state.blkIndent >= 4) { - return false; - } - let ch = state.src.charCodeAt(pos); - if (ch !== 35 || pos >= max) { - return false; - } - let level = 1; - ch = state.src.charCodeAt(++pos); - while (ch === 35 && pos < max && level <= 6) { - level++; - ch = state.src.charCodeAt(++pos); - } - if (level > 6 || pos < max && !isSpace(ch)) { - return false; - } - if (silent) { - return true; - } - max = state.skipSpacesBack(max, pos); - const tmp = state.skipCharsBack(max, 35, pos); - if (tmp > pos && isSpace(state.src.charCodeAt(tmp - 1))) { - max = tmp; - } - state.line = startLine + 1; - const token_o = state.push("heading_open", "h" + String(level), 1); - token_o.markup = "########".slice(0, level); - token_o.map = [startLine, state.line]; - const token_i = state.push("inline", "", 0); - token_i.content = state.src.slice(pos, max).trim(); - token_i.map = [startLine, state.line]; - token_i.children = []; - const token_c = state.push("heading_close", "h" + String(level), -1); - token_c.markup = "########".slice(0, level); - return true; -} - -function lheading(state, startLine, endLine) { - const terminatorRules = state.md.block.ruler.getRules("paragraph"); - if (state.sCount[startLine] - state.blkIndent >= 4) { - return false; - } - const oldParentType = state.parentType; - state.parentType = "paragraph"; - let level = 0; - let marker; - let nextLine = startLine + 1; - for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) { - if (state.sCount[nextLine] - state.blkIndent > 3) { - continue; - } - if (state.sCount[nextLine] >= state.blkIndent) { - let pos = state.bMarks[nextLine] + state.tShift[nextLine]; - const max = state.eMarks[nextLine]; - if (pos < max) { - marker = state.src.charCodeAt(pos); - if (marker === 45 || marker === 61) { - pos = state.skipChars(pos, marker); - pos = state.skipSpaces(pos); - if (pos >= max) { - level = marker === 61 ? 1 : 2; - break; - } - } - } - } - if (state.sCount[nextLine] < 0) { - continue; - } - let terminate = false; - for (let i$10 = 0, l$5 = terminatorRules.length; i$10 < l$5; i$10++) { - if (terminatorRules[i$10](state, nextLine, endLine, true)) { - terminate = true; - break; - } - } - if (terminate) { - break; - } - } - if (!level) { - return false; - } - const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); - state.line = nextLine + 1; - const token_o = state.push("heading_open", "h" + String(level), 1); - token_o.markup = String.fromCharCode(marker); - token_o.map = [startLine, state.line]; - const token_i = state.push("inline", "", 0); - token_i.content = content; - token_i.map = [startLine, state.line - 1]; - token_i.children = []; - const token_c = state.push("heading_close", "h" + String(level), -1); - token_c.markup = String.fromCharCode(marker); - state.parentType = oldParentType; - return true; -} - -function paragraph(state, startLine, endLine) { - const terminatorRules = state.md.block.ruler.getRules("paragraph"); - const oldParentType = state.parentType; - let nextLine = startLine + 1; - state.parentType = "paragraph"; - for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) { - if (state.sCount[nextLine] - state.blkIndent > 3) { - continue; - } - if (state.sCount[nextLine] < 0) { - continue; - } - let terminate = false; - for (let i$10 = 0, l$5 = terminatorRules.length; i$10 < l$5; i$10++) { - if (terminatorRules[i$10](state, nextLine, endLine, true)) { - terminate = true; - break; - } - } - if (terminate) { - break; - } - } - const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); - state.line = nextLine; - const token_o = state.push("paragraph_open", "p", 1); - token_o.map = [startLine, state.line]; - const token_i = state.push("inline", "", 0); - token_i.content = content; - token_i.map = [startLine, state.line]; - token_i.children = []; - state.push("paragraph_close", "p", -1); - state.parentType = oldParentType; - return true; -} - -/** internal -* class ParserBlock -* -* Block-level tokenizer. -**/ -const _rules$1 = [ - [ - "table", - table, - ["paragraph", "reference"] - ], - ["code", code], - [ - "fence", - fence, - [ - "paragraph", - "reference", - "blockquote", - "list" - ] - ], - [ - "blockquote", - blockquote, - [ - "paragraph", - "reference", - "blockquote", - "list" - ] - ], - [ - "hr", - hr, - [ - "paragraph", - "reference", - "blockquote", - "list" - ] - ], - [ - "list", - list, - [ - "paragraph", - "reference", - "blockquote" - ] - ], - ["reference", reference], - [ - "html_block", - html_block, - [ - "paragraph", - "reference", - "blockquote" - ] - ], - [ - "heading", - heading, - [ - "paragraph", - "reference", - "blockquote" - ] - ], - ["lheading", lheading], - ["paragraph", paragraph] -]; -/** -* new ParserBlock() -**/ -function ParserBlock() { - /** - * ParserBlock#ruler -> Ruler - * - * [[Ruler]] instance. Keep configuration of block rules. - **/ - this.ruler = new ruler_default(); - for (let i$10 = 0; i$10 < _rules$1.length; i$10++) { - this.ruler.push(_rules$1[i$10][0], _rules$1[i$10][1], { alt: (_rules$1[i$10][2] || []).slice() }); - } -} -ParserBlock.prototype.tokenize = function(state, startLine, endLine) { - const rules = this.ruler.getRules(""); - const len = rules.length; - const maxNesting = state.md.options.maxNesting; - let line = startLine; - let hasEmptyLines = false; - while (line < endLine) { - state.line = line = state.skipEmptyLines(line); - if (line >= endLine) { - break; - } - if (state.sCount[line] < state.blkIndent) { - break; - } - if (state.level >= maxNesting) { - state.line = endLine; - break; - } - const prevLine = state.line; - let ok = false; - for (let i$10 = 0; i$10 < len; i$10++) { - ok = rules[i$10](state, line, endLine, false); - if (ok) { - if (prevLine >= state.line) { - throw new Error("block rule didn't increment state.line"); - } - break; - } - } - if (!ok) throw new Error("none of the block rules matched"); - state.tight = !hasEmptyLines; - if (state.isEmpty(state.line - 1)) { - hasEmptyLines = true; - } - line = state.line; - if (line < endLine && state.isEmpty(line)) { - hasEmptyLines = true; - line++; - state.line = line; - } - } -}; -/** -* ParserBlock.parse(str, md, env, outTokens) -* -* Process input string and push block tokens into `outTokens` -**/ -ParserBlock.prototype.parse = function(src, md, env, outTokens) { - if (!src) { - return; - } - const state = new this.State(src, md, env, outTokens); - this.tokenize(state, state.line, state.lineMax); -}; -ParserBlock.prototype.State = state_block_default; -var parser_block_default = ParserBlock; - -function StateInline(src, md, env, outTokens) { - this.src = src; - this.env = env; - this.md = md; - this.tokens = outTokens; - this.tokens_meta = Array(outTokens.length); - this.pos = 0; - this.posMax = this.src.length; - this.level = 0; - this.pending = ""; - this.pendingLevel = 0; - this.cache = {}; - this.delimiters = []; - this._prev_delimiters = []; - this.backticks = {}; - this.backticksScanned = false; - this.linkLevel = 0; -} -StateInline.prototype.pushPending = function() { - const token = new token_default("text", "", 0); - token.content = this.pending; - token.level = this.pendingLevel; - this.tokens.push(token); - this.pending = ""; - return token; -}; -StateInline.prototype.push = function(type$2, tag, nesting) { - if (this.pending) { - this.pushPending(); - } - const token = new token_default(type$2, tag, nesting); - let token_meta = null; - if (nesting < 0) { - this.level--; - this.delimiters = this._prev_delimiters.pop(); - } - token.level = this.level; - if (nesting > 0) { - this.level++; - this._prev_delimiters.push(this.delimiters); - this.delimiters = []; - token_meta = { delimiters: this.delimiters }; - } - this.pendingLevel = this.level; - this.tokens.push(token); - this.tokens_meta.push(token_meta); - return token; -}; -StateInline.prototype.scanDelims = function(start, canSplitWord) { - const max = this.posMax; - const marker = this.src.charCodeAt(start); - const lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 32; - let pos = start; - while (pos < max && this.src.charCodeAt(pos) === marker) { - pos++; - } - const count = pos - start; - const nextChar = pos < max ? this.src.charCodeAt(pos) : 32; - const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar)); - const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)); - const isLastWhiteSpace = isWhiteSpace(lastChar); - const isNextWhiteSpace = isWhiteSpace(nextChar); - const left_flanking = !isNextWhiteSpace && (!isNextPunctChar || isLastWhiteSpace || isLastPunctChar); - const right_flanking = !isLastWhiteSpace && (!isLastPunctChar || isNextWhiteSpace || isNextPunctChar); - const can_open = left_flanking && (canSplitWord || !right_flanking || isLastPunctChar); - const can_close = right_flanking && (canSplitWord || !left_flanking || isNextPunctChar); - return { - can_open, - can_close, - length: count - }; -}; -StateInline.prototype.Token = token_default; -var state_inline_default = StateInline; - -function isTerminatorChar(ch) { - switch (ch) { - case 10: - case 33: - case 35: - case 36: - case 37: - case 38: - case 42: - case 43: - case 45: - case 58: - case 60: - case 61: - case 62: - case 64: - case 91: - case 92: - case 93: - case 94: - case 95: - case 96: - case 123: - case 125: - case 126: return true; - default: return false; - } -} -function text(state, silent) { - let pos = state.pos; - while (pos < state.posMax && !isTerminatorChar(state.src.charCodeAt(pos))) { - pos++; - } - if (pos === state.pos) { - return false; - } - if (!silent) { - state.pending += state.src.slice(state.pos, pos); - } - state.pos = pos; - return true; -} - -const SCHEME_RE = /(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i; -function linkify(state, silent) { - if (!state.md.options.linkify) return false; - if (state.linkLevel > 0) return false; - const pos = state.pos; - const max = state.posMax; - if (pos + 3 > max) return false; - if (state.src.charCodeAt(pos) !== 58) return false; - if (state.src.charCodeAt(pos + 1) !== 47) return false; - if (state.src.charCodeAt(pos + 2) !== 47) return false; - const match = state.pending.match(SCHEME_RE); - if (!match) return false; - const proto = match[1]; - const link$1 = state.md.linkify.matchAtStart(state.src.slice(pos - proto.length)); - if (!link$1) return false; - let url = link$1.url; - if (url.length <= proto.length) return false; - url = url.replace(/\*+$/, ""); - const fullUrl = state.md.normalizeLink(url); - if (!state.md.validateLink(fullUrl)) return false; - if (!silent) { - state.pending = state.pending.slice(0, -proto.length); - const token_o = state.push("link_open", "a", 1); - token_o.attrs = [["href", fullUrl]]; - token_o.markup = "linkify"; - token_o.info = "auto"; - const token_t = state.push("text", "", 0); - token_t.content = state.md.normalizeLinkText(url); - const token_c = state.push("link_close", "a", -1); - token_c.markup = "linkify"; - token_c.info = "auto"; - } - state.pos += url.length - proto.length; - return true; -} - -function newline(state, silent) { - let pos = state.pos; - if (state.src.charCodeAt(pos) !== 10) { - return false; - } - const pmax = state.pending.length - 1; - const max = state.posMax; - if (!silent) { - if (pmax >= 0 && state.pending.charCodeAt(pmax) === 32) { - if (pmax >= 1 && state.pending.charCodeAt(pmax - 1) === 32) { - let ws = pmax - 1; - while (ws >= 1 && state.pending.charCodeAt(ws - 1) === 32) ws--; - state.pending = state.pending.slice(0, ws); - state.push("hardbreak", "br", 0); - } else { - state.pending = state.pending.slice(0, -1); - state.push("softbreak", "br", 0); - } - } else { - state.push("softbreak", "br", 0); - } - } - pos++; - while (pos < max && isSpace(state.src.charCodeAt(pos))) { - pos++; - } - state.pos = pos; - return true; -} - -const ESCAPED = []; -for (let i$10 = 0; i$10 < 256; i$10++) { - ESCAPED.push(0); -} -"\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-".split("").forEach(function(ch) { - ESCAPED[ch.charCodeAt(0)] = 1; -}); -function escape(state, silent) { - let pos = state.pos; - const max = state.posMax; - if (state.src.charCodeAt(pos) !== 92) return false; - pos++; - if (pos >= max) return false; - let ch1 = state.src.charCodeAt(pos); - if (ch1 === 10) { - if (!silent) { - state.push("hardbreak", "br", 0); - } - pos++; - while (pos < max) { - ch1 = state.src.charCodeAt(pos); - if (!isSpace(ch1)) break; - pos++; - } - state.pos = pos; - return true; - } - let escapedStr = state.src[pos]; - if (ch1 >= 55296 && ch1 <= 56319 && pos + 1 < max) { - const ch2 = state.src.charCodeAt(pos + 1); - if (ch2 >= 56320 && ch2 <= 57343) { - escapedStr += state.src[pos + 1]; - pos++; - } - } - const origStr = "\\" + escapedStr; - if (!silent) { - const token = state.push("text_special", "", 0); - if (ch1 < 256 && ESCAPED[ch1] !== 0) { - token.content = escapedStr; - } else { - token.content = origStr; - } - token.markup = origStr; - token.info = "escape"; - } - state.pos = pos + 1; - return true; -} - -function backtick(state, silent) { - let pos = state.pos; - const ch = state.src.charCodeAt(pos); - if (ch !== 96) { - return false; - } - const start = pos; - pos++; - const max = state.posMax; - while (pos < max && state.src.charCodeAt(pos) === 96) { - pos++; - } - const marker = state.src.slice(start, pos); - const openerLength = marker.length; - if (state.backticksScanned && (state.backticks[openerLength] || 0) <= start) { - if (!silent) state.pending += marker; - state.pos += openerLength; - return true; - } - let matchEnd = pos; - let matchStart; - while ((matchStart = state.src.indexOf("`", matchEnd)) !== -1) { - matchEnd = matchStart + 1; - while (matchEnd < max && state.src.charCodeAt(matchEnd) === 96) { - matchEnd++; - } - const closerLength = matchEnd - matchStart; - if (closerLength === openerLength) { - if (!silent) { - const token = state.push("code_inline", "code", 0); - token.markup = marker; - token.content = state.src.slice(pos, matchStart).replace(/\n/g, " ").replace(/^ (.+) $/, "$1"); - } - state.pos = matchEnd; - return true; - } - state.backticks[closerLength] = matchStart; - } - state.backticksScanned = true; - if (!silent) state.pending += marker; - state.pos += openerLength; - return true; -} - -function strikethrough_tokenize(state, silent) { - const start = state.pos; - const marker = state.src.charCodeAt(start); - if (silent) { - return false; - } - if (marker !== 126) { - return false; - } - const scanned = state.scanDelims(state.pos, true); - let len = scanned.length; - const ch = String.fromCharCode(marker); - if (len < 2) { - return false; - } - let token; - if (len % 2) { - token = state.push("text", "", 0); - token.content = ch; - len--; - } - for (let i$10 = 0; i$10 < len; i$10 += 2) { - token = state.push("text", "", 0); - token.content = ch + ch; - state.delimiters.push({ - marker, - length: 0, - token: state.tokens.length - 1, - end: -1, - open: scanned.can_open, - close: scanned.can_close - }); - } - state.pos += scanned.length; - return true; -} -function postProcess$1(state, delimiters) { - let token; - const loneMarkers = []; - const max = delimiters.length; - for (let i$10 = 0; i$10 < max; i$10++) { - const startDelim = delimiters[i$10]; - if (startDelim.marker !== 126) { - continue; - } - if (startDelim.end === -1) { - continue; - } - const endDelim = delimiters[startDelim.end]; - token = state.tokens[startDelim.token]; - token.type = "s_open"; - token.tag = "s"; - token.nesting = 1; - token.markup = "~~"; - token.content = ""; - token = state.tokens[endDelim.token]; - token.type = "s_close"; - token.tag = "s"; - token.nesting = -1; - token.markup = "~~"; - token.content = ""; - if (state.tokens[endDelim.token - 1].type === "text" && state.tokens[endDelim.token - 1].content === "~") { - loneMarkers.push(endDelim.token - 1); - } - } - while (loneMarkers.length) { - const i$10 = loneMarkers.pop(); - let j$2 = i$10 + 1; - while (j$2 < state.tokens.length && state.tokens[j$2].type === "s_close") { - j$2++; - } - j$2--; - if (i$10 !== j$2) { - token = state.tokens[j$2]; - state.tokens[j$2] = state.tokens[i$10]; - state.tokens[i$10] = token; - } - } -} -function strikethrough_postProcess(state) { - const tokens_meta = state.tokens_meta; - const max = state.tokens_meta.length; - postProcess$1(state, state.delimiters); - for (let curr = 0; curr < max; curr++) { - if (tokens_meta[curr] && tokens_meta[curr].delimiters) { - postProcess$1(state, tokens_meta[curr].delimiters); - } - } -} -var strikethrough_default = { - tokenize: strikethrough_tokenize, - postProcess: strikethrough_postProcess -}; - -function emphasis_tokenize(state, silent) { - const start = state.pos; - const marker = state.src.charCodeAt(start); - if (silent) { - return false; - } - if (marker !== 95 && marker !== 42) { - return false; - } - const scanned = state.scanDelims(state.pos, marker === 42); - for (let i$10 = 0; i$10 < scanned.length; i$10++) { - const token = state.push("text", "", 0); - token.content = String.fromCharCode(marker); - state.delimiters.push({ - marker, - length: scanned.length, - token: state.tokens.length - 1, - end: -1, - open: scanned.can_open, - close: scanned.can_close - }); - } - state.pos += scanned.length; - return true; -} -function postProcess(state, delimiters) { - const max = delimiters.length; - for (let i$10 = max - 1; i$10 >= 0; i$10--) { - const startDelim = delimiters[i$10]; - if (startDelim.marker !== 95 && startDelim.marker !== 42) { - continue; - } - if (startDelim.end === -1) { - continue; - } - const endDelim = delimiters[startDelim.end]; - const isStrong = i$10 > 0 && delimiters[i$10 - 1].end === startDelim.end + 1 && delimiters[i$10 - 1].marker === startDelim.marker && delimiters[i$10 - 1].token === startDelim.token - 1 && delimiters[startDelim.end + 1].token === endDelim.token + 1; - const ch = String.fromCharCode(startDelim.marker); - const token_o = state.tokens[startDelim.token]; - token_o.type = isStrong ? "strong_open" : "em_open"; - token_o.tag = isStrong ? "strong" : "em"; - token_o.nesting = 1; - token_o.markup = isStrong ? ch + ch : ch; - token_o.content = ""; - const token_c = state.tokens[endDelim.token]; - token_c.type = isStrong ? "strong_close" : "em_close"; - token_c.tag = isStrong ? "strong" : "em"; - token_c.nesting = -1; - token_c.markup = isStrong ? ch + ch : ch; - token_c.content = ""; - if (isStrong) { - state.tokens[delimiters[i$10 - 1].token].content = ""; - state.tokens[delimiters[startDelim.end + 1].token].content = ""; - i$10--; - } - } -} -function emphasis_post_process(state) { - const tokens_meta = state.tokens_meta; - const max = state.tokens_meta.length; - postProcess(state, state.delimiters); - for (let curr = 0; curr < max; curr++) { - if (tokens_meta[curr] && tokens_meta[curr].delimiters) { - postProcess(state, tokens_meta[curr].delimiters); - } - } -} -var emphasis_default = { - tokenize: emphasis_tokenize, - postProcess: emphasis_post_process -}; - -function link(state, silent) { - let code$1, label, res, ref; - let href = ""; - let title$1 = ""; - let start = state.pos; - let parseReference = true; - if (state.src.charCodeAt(state.pos) !== 91) { - return false; - } - const oldPos = state.pos; - const max = state.posMax; - const labelStart = state.pos + 1; - const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, true); - if (labelEnd < 0) { - return false; - } - let pos = labelEnd + 1; - if (pos < max && state.src.charCodeAt(pos) === 40) { - parseReference = false; - pos++; - for (; pos < max; pos++) { - code$1 = state.src.charCodeAt(pos); - if (!isSpace(code$1) && code$1 !== 10) { - break; - } - } - if (pos >= max) { - return false; - } - start = pos; - res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax); - if (res.ok) { - href = state.md.normalizeLink(res.str); - if (state.md.validateLink(href)) { - pos = res.pos; - } else { - href = ""; - } - start = pos; - for (; pos < max; pos++) { - code$1 = state.src.charCodeAt(pos); - if (!isSpace(code$1) && code$1 !== 10) { - break; - } - } - res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax); - if (pos < max && start !== pos && res.ok) { - title$1 = res.str; - pos = res.pos; - for (; pos < max; pos++) { - code$1 = state.src.charCodeAt(pos); - if (!isSpace(code$1) && code$1 !== 10) { - break; - } - } - } - } - if (pos >= max || state.src.charCodeAt(pos) !== 41) { - parseReference = true; - } - pos++; - } - if (parseReference) { - if (typeof state.env.references === "undefined") { - return false; - } - if (pos < max && state.src.charCodeAt(pos) === 91) { - start = pos + 1; - pos = state.md.helpers.parseLinkLabel(state, pos); - if (pos >= 0) { - label = state.src.slice(start, pos++); - } else { - pos = labelEnd + 1; - } - } else { - pos = labelEnd + 1; - } - if (!label) { - label = state.src.slice(labelStart, labelEnd); - } - ref = state.env.references[normalizeReference(label)]; - if (!ref) { - state.pos = oldPos; - return false; - } - href = ref.href; - title$1 = ref.title; - } - if (!silent) { - state.pos = labelStart; - state.posMax = labelEnd; - const token_o = state.push("link_open", "a", 1); - const attrs = [["href", href]]; - token_o.attrs = attrs; - if (title$1) { - attrs.push(["title", title$1]); - } - state.linkLevel++; - state.md.inline.tokenize(state); - state.linkLevel--; - state.push("link_close", "a", -1); - } - state.pos = pos; - state.posMax = max; - return true; -} - -function image(state, silent) { - let code$1, content, label, pos, ref, res, title$1, start; - let href = ""; - const oldPos = state.pos; - const max = state.posMax; - if (state.src.charCodeAt(state.pos) !== 33) { - return false; - } - if (state.src.charCodeAt(state.pos + 1) !== 91) { - return false; - } - const labelStart = state.pos + 2; - const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, false); - if (labelEnd < 0) { - return false; - } - pos = labelEnd + 1; - if (pos < max && state.src.charCodeAt(pos) === 40) { - pos++; - for (; pos < max; pos++) { - code$1 = state.src.charCodeAt(pos); - if (!isSpace(code$1) && code$1 !== 10) { - break; - } - } - if (pos >= max) { - return false; - } - start = pos; - res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax); - if (res.ok) { - href = state.md.normalizeLink(res.str); - if (state.md.validateLink(href)) { - pos = res.pos; - } else { - href = ""; - } - } - start = pos; - for (; pos < max; pos++) { - code$1 = state.src.charCodeAt(pos); - if (!isSpace(code$1) && code$1 !== 10) { - break; - } - } - res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax); - if (pos < max && start !== pos && res.ok) { - title$1 = res.str; - pos = res.pos; - for (; pos < max; pos++) { - code$1 = state.src.charCodeAt(pos); - if (!isSpace(code$1) && code$1 !== 10) { - break; - } - } - } else { - title$1 = ""; - } - if (pos >= max || state.src.charCodeAt(pos) !== 41) { - state.pos = oldPos; - return false; - } - pos++; - } else { - if (typeof state.env.references === "undefined") { - return false; - } - if (pos < max && state.src.charCodeAt(pos) === 91) { - start = pos + 1; - pos = state.md.helpers.parseLinkLabel(state, pos); - if (pos >= 0) { - label = state.src.slice(start, pos++); - } else { - pos = labelEnd + 1; - } - } else { - pos = labelEnd + 1; - } - if (!label) { - label = state.src.slice(labelStart, labelEnd); - } - ref = state.env.references[normalizeReference(label)]; - if (!ref) { - state.pos = oldPos; - return false; - } - href = ref.href; - title$1 = ref.title; - } - if (!silent) { - content = state.src.slice(labelStart, labelEnd); - const tokens = []; - state.md.inline.parse(content, state.md, state.env, tokens); - const token = state.push("image", "img", 0); - const attrs = [["src", href], ["alt", ""]]; - token.attrs = attrs; - token.children = tokens; - token.content = content; - if (title$1) { - attrs.push(["title", title$1]); - } - } - state.pos = pos; - state.posMax = max; - return true; -} - -const EMAIL_RE = /^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/; -const AUTOLINK_RE = /^([a-zA-Z][a-zA-Z0-9+.-]{1,31}):([^<>\x00-\x20]*)$/; -function autolink(state, silent) { - let pos = state.pos; - if (state.src.charCodeAt(pos) !== 60) { - return false; - } - const start = state.pos; - const max = state.posMax; - for (;;) { - if (++pos >= max) return false; - const ch = state.src.charCodeAt(pos); - if (ch === 60) return false; - if (ch === 62) break; - } - const url = state.src.slice(start + 1, pos); - if (AUTOLINK_RE.test(url)) { - const fullUrl = state.md.normalizeLink(url); - if (!state.md.validateLink(fullUrl)) { - return false; - } - if (!silent) { - const token_o = state.push("link_open", "a", 1); - token_o.attrs = [["href", fullUrl]]; - token_o.markup = "autolink"; - token_o.info = "auto"; - const token_t = state.push("text", "", 0); - token_t.content = state.md.normalizeLinkText(url); - const token_c = state.push("link_close", "a", -1); - token_c.markup = "autolink"; - token_c.info = "auto"; - } - state.pos += url.length + 2; - return true; - } - if (EMAIL_RE.test(url)) { - const fullUrl = state.md.normalizeLink("mailto:" + url); - if (!state.md.validateLink(fullUrl)) { - return false; - } - if (!silent) { - const token_o = state.push("link_open", "a", 1); - token_o.attrs = [["href", fullUrl]]; - token_o.markup = "autolink"; - token_o.info = "auto"; - const token_t = state.push("text", "", 0); - token_t.content = state.md.normalizeLinkText(url); - const token_c = state.push("link_close", "a", -1); - token_c.markup = "autolink"; - token_c.info = "auto"; - } - state.pos += url.length + 2; - return true; - } - return false; -} - -function isLinkOpen(str) { - return /^\s]/i.test(str); -} -function isLinkClose(str) { - return /^<\/a\s*>/i.test(str); -} -function isLetter(ch) { - const lc = ch | 32; - return lc >= 97 && lc <= 122; -} -function html_inline(state, silent) { - if (!state.md.options.html) { - return false; - } - const max = state.posMax; - const pos = state.pos; - if (state.src.charCodeAt(pos) !== 60 || pos + 2 >= max) { - return false; - } - const ch = state.src.charCodeAt(pos + 1); - if (ch !== 33 && ch !== 63 && ch !== 47 && !isLetter(ch)) { - return false; - } - const match = state.src.slice(pos).match(HTML_TAG_RE); - if (!match) { - return false; - } - if (!silent) { - const token = state.push("html_inline", "", 0); - token.content = match[0]; - if (isLinkOpen(token.content)) state.linkLevel++; - if (isLinkClose(token.content)) state.linkLevel--; - } - state.pos += match[0].length; - return true; -} - -const DIGITAL_RE = /^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i; -const NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i; -function entity(state, silent) { - const pos = state.pos; - const max = state.posMax; - if (state.src.charCodeAt(pos) !== 38) return false; - if (pos + 1 >= max) return false; - const ch = state.src.charCodeAt(pos + 1); - if (ch === 35) { - const match = state.src.slice(pos).match(DIGITAL_RE); - if (match) { - if (!silent) { - const code$1 = match[1][0].toLowerCase() === "x" ? parseInt(match[1].slice(1), 16) : parseInt(match[1], 10); - const token = state.push("text_special", "", 0); - token.content = isValidEntityCode(code$1) ? fromCodePoint(code$1) : fromCodePoint(65533); - token.markup = match[0]; - token.info = "entity"; - } - state.pos += match[0].length; - return true; - } - } else { - const match = state.src.slice(pos).match(NAMED_RE); - if (match) { - const decoded = decodeHTML(match[0]); - if (decoded !== match[0]) { - if (!silent) { - const token = state.push("text_special", "", 0); - token.content = decoded; - token.markup = match[0]; - token.info = "entity"; - } - state.pos += match[0].length; - return true; - } - } - } - return false; -} - -function processDelimiters(delimiters) { - const openersBottom = {}; - const max = delimiters.length; - if (!max) return; - let headerIdx = 0; - let lastTokenIdx = -2; - const jumps = []; - for (let closerIdx = 0; closerIdx < max; closerIdx++) { - const closer = delimiters[closerIdx]; - jumps.push(0); - if (delimiters[headerIdx].marker !== closer.marker || lastTokenIdx !== closer.token - 1) { - headerIdx = closerIdx; - } - lastTokenIdx = closer.token; - closer.length = closer.length || 0; - if (!closer.close) continue; - if (!openersBottom.hasOwnProperty(closer.marker)) { - openersBottom[closer.marker] = [ - -1, - -1, - -1, - -1, - -1, - -1 - ]; - } - const minOpenerIdx = openersBottom[closer.marker][(closer.open ? 3 : 0) + closer.length % 3]; - let openerIdx = headerIdx - jumps[headerIdx] - 1; - let newMinOpenerIdx = openerIdx; - for (; openerIdx > minOpenerIdx; openerIdx -= jumps[openerIdx] + 1) { - const opener = delimiters[openerIdx]; - if (opener.marker !== closer.marker) continue; - if (opener.open && opener.end < 0) { - let isOddMatch = false; - if (opener.close || closer.open) { - if ((opener.length + closer.length) % 3 === 0) { - if (opener.length % 3 !== 0 || closer.length % 3 !== 0) { - isOddMatch = true; - } - } - } - if (!isOddMatch) { - const lastJump = openerIdx > 0 && !delimiters[openerIdx - 1].open ? jumps[openerIdx - 1] + 1 : 0; - jumps[closerIdx] = closerIdx - openerIdx + lastJump; - jumps[openerIdx] = lastJump; - closer.open = false; - opener.end = closerIdx; - opener.close = false; - newMinOpenerIdx = -1; - lastTokenIdx = -2; - break; - } - } - } - if (newMinOpenerIdx !== -1) { - openersBottom[closer.marker][(closer.open ? 3 : 0) + (closer.length || 0) % 3] = newMinOpenerIdx; - } - } -} -function link_pairs(state) { - const tokens_meta = state.tokens_meta; - const max = state.tokens_meta.length; - processDelimiters(state.delimiters); - for (let curr = 0; curr < max; curr++) { - if (tokens_meta[curr] && tokens_meta[curr].delimiters) { - processDelimiters(tokens_meta[curr].delimiters); - } - } -} - -function fragments_join(state) { - let curr, last; - let level = 0; - const tokens = state.tokens; - const max = state.tokens.length; - for (curr = last = 0; curr < max; curr++) { - if (tokens[curr].nesting < 0) level--; - tokens[curr].level = level; - if (tokens[curr].nesting > 0) level++; - if (tokens[curr].type === "text" && curr + 1 < max && tokens[curr + 1].type === "text") { - tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content; - } else { - if (curr !== last) { - tokens[last] = tokens[curr]; - } - last++; - } - } - if (curr !== last) { - tokens.length = last; - } -} - -/** internal -* class ParserInline -* -* Tokenizes paragraph content. -**/ -const _rules = [ - ["text", text], - ["linkify", linkify], - ["newline", newline], - ["escape", escape], - ["backticks", backtick], - ["strikethrough", strikethrough_default.tokenize], - ["emphasis", emphasis_default.tokenize], - ["link", link], - ["image", image], - ["autolink", autolink], - ["html_inline", html_inline], - ["entity", entity] -]; -const _rules2 = [ - ["balance_pairs", link_pairs], - ["strikethrough", strikethrough_default.postProcess], - ["emphasis", emphasis_default.postProcess], - ["fragments_join", fragments_join] -]; -/** -* new ParserInline() -**/ -function ParserInline() { - /** - * ParserInline#ruler -> Ruler - * - * [[Ruler]] instance. Keep configuration of inline rules. - **/ - this.ruler = new ruler_default(); - for (let i$10 = 0; i$10 < _rules.length; i$10++) { - this.ruler.push(_rules[i$10][0], _rules[i$10][1]); - } - /** - * ParserInline#ruler2 -> Ruler - * - * [[Ruler]] instance. Second ruler used for post-processing - * (e.g. in emphasis-like rules). - **/ - this.ruler2 = new ruler_default(); - for (let i$10 = 0; i$10 < _rules2.length; i$10++) { - this.ruler2.push(_rules2[i$10][0], _rules2[i$10][1]); - } -} -ParserInline.prototype.skipToken = function(state) { - const pos = state.pos; - const rules = this.ruler.getRules(""); - const len = rules.length; - const maxNesting = state.md.options.maxNesting; - const cache = state.cache; - if (typeof cache[pos] !== "undefined") { - state.pos = cache[pos]; - return; - } - let ok = false; - if (state.level < maxNesting) { - for (let i$10 = 0; i$10 < len; i$10++) { - state.level++; - ok = rules[i$10](state, true); - state.level--; - if (ok) { - if (pos >= state.pos) { - throw new Error("inline rule didn't increment state.pos"); - } - break; - } - } - } else { - state.pos = state.posMax; - } - if (!ok) { - state.pos++; - } - cache[pos] = state.pos; -}; -ParserInline.prototype.tokenize = function(state) { - const rules = this.ruler.getRules(""); - const len = rules.length; - const end = state.posMax; - const maxNesting = state.md.options.maxNesting; - while (state.pos < end) { - const prevPos = state.pos; - let ok = false; - if (state.level < maxNesting) { - for (let i$10 = 0; i$10 < len; i$10++) { - ok = rules[i$10](state, false); - if (ok) { - if (prevPos >= state.pos) { - throw new Error("inline rule didn't increment state.pos"); - } - break; - } - } - } - if (ok) { - if (state.pos >= end) { - break; - } - continue; - } - state.pending += state.src[state.pos++]; - } - if (state.pending) { - state.pushPending(); - } -}; -/** -* ParserInline.parse(str, md, env, outTokens) -* -* Process input string and push inline tokens into `outTokens` -**/ -ParserInline.prototype.parse = function(str, md, env, outTokens) { - const state = new this.State(str, md, env, outTokens); - this.tokenize(state); - const rules = this.ruler2.getRules(""); - const len = rules.length; - for (let i$10 = 0; i$10 < len; i$10++) { - rules[i$10](state); - } -}; -ParserInline.prototype.State = state_inline_default; -var parser_inline_default = ParserInline; - -function re_default(opts) { - const re = {}; - opts = opts || {}; - re.src_Any = regex_default$5.source; - re.src_Cc = regex_default$4.source; - re.src_Z = regex_default.source; - re.src_P = regex_default$2.source; - re.src_ZPCc = [ - re.src_Z, - re.src_P, - re.src_Cc - ].join("|"); - re.src_ZCc = [re.src_Z, re.src_Cc].join("|"); - const text_separators = "[><|]"; - re.src_pseudo_letter = "(?:(?!" + text_separators + "|" + re.src_ZPCc + ")" + re.src_Any + ")"; - re.src_ip4 = "(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; - re.src_auth = "(?:(?:(?!" + re.src_ZCc + "|[@/\\[\\]()]).)+@)?"; - re.src_port = "(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?"; - re.src_host_terminator = "(?=$|" + text_separators + "|" + re.src_ZPCc + ")" + "(?!" + (opts["---"] ? "-(?!--)|" : "-|") + "_|:\\d|\\.-|\\.(?!$|" + re.src_ZPCc + "))"; - re.src_path = "(?:" + "[/?#]" + "(?:" + "(?!" + re.src_ZCc + "|" + text_separators + "|[()[\\]{}.,\"'?!\\-;]).|" + "\\[(?:(?!" + re.src_ZCc + "|\\]).)*\\]|" + "\\((?:(?!" + re.src_ZCc + "|[)]).)*\\)|" + "\\{(?:(?!" + re.src_ZCc + "|[}]).)*\\}|" + "\\\"(?:(?!" + re.src_ZCc + "|[\"]).)+\\\"|" + "\\'(?:(?!" + re.src_ZCc + "|[']).)+\\'|" + "\\'(?=" + re.src_pseudo_letter + "|[-])|" + "\\.{2,}[a-zA-Z0-9%/&]|" + "\\.(?!" + re.src_ZCc + "|[.]|$)|" + (opts["---"] ? "\\-(?!--(?:[^-]|$))(?:-*)|" : "\\-+|") + ",(?!" + re.src_ZCc + "|$)|" + ";(?!" + re.src_ZCc + "|$)|" + "\\!+(?!" + re.src_ZCc + "|[!]|$)|" + "\\?(?!" + re.src_ZCc + "|[?]|$)" + ")+" + "|\\/" + ")?"; - re.src_email_name = "[\\-;:&=\\+\\$,\\.a-zA-Z0-9_][\\-;:&=\\+\\$,\\\"\\.a-zA-Z0-9_]*"; - re.src_xn = "xn--[a-z0-9\\-]{1,59}"; - re.src_domain_root = "(?:" + re.src_xn + "|" + re.src_pseudo_letter + "{1,63}" + ")"; - re.src_domain = "(?:" + re.src_xn + "|" + "(?:" + re.src_pseudo_letter + ")" + "|" + "(?:" + re.src_pseudo_letter + "(?:-|" + re.src_pseudo_letter + "){0,61}" + re.src_pseudo_letter + ")" + ")"; - re.src_host = "(?:" + "(?:(?:(?:" + re.src_domain + ")\\.)*" + re.src_domain + ")" + ")"; - re.tpl_host_fuzzy = "(?:" + re.src_ip4 + "|" + "(?:(?:(?:" + re.src_domain + ")\\.)+(?:%TLDS%))" + ")"; - re.tpl_host_no_ip_fuzzy = "(?:(?:(?:" + re.src_domain + ")\\.)+(?:%TLDS%))"; - re.src_host_strict = re.src_host + re.src_host_terminator; - re.tpl_host_fuzzy_strict = re.tpl_host_fuzzy + re.src_host_terminator; - re.src_host_port_strict = re.src_host + re.src_port + re.src_host_terminator; - re.tpl_host_port_fuzzy_strict = re.tpl_host_fuzzy + re.src_port + re.src_host_terminator; - re.tpl_host_port_no_ip_fuzzy_strict = re.tpl_host_no_ip_fuzzy + re.src_port + re.src_host_terminator; - re.tpl_host_fuzzy_test = "localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:" + re.src_ZPCc + "|>|$))"; - re.tpl_email_fuzzy = "(^|" + text_separators + "|\"|\\(|" + re.src_ZCc + ")" + "(" + re.src_email_name + "@" + re.tpl_host_fuzzy_strict + ")"; - re.tpl_link_fuzzy = "(^|(?![.:/\\-_@])(?:[$+<=>^`||]|" + re.src_ZPCc + "))" + "((?![$+<=>^`||])" + re.tpl_host_port_fuzzy_strict + re.src_path + ")"; - re.tpl_link_no_ip_fuzzy = "(^|(?![.:/\\-_@])(?:[$+<=>^`||]|" + re.src_ZPCc + "))" + "((?![$+<=>^`||])" + re.tpl_host_port_no_ip_fuzzy_strict + re.src_path + ")"; - return re; -} - -function assign(obj) { - const sources = Array.prototype.slice.call(arguments, 1); - sources.forEach(function(source) { - if (!source) { - return; - } - Object.keys(source).forEach(function(key) { - obj[key] = source[key]; - }); - }); - return obj; -} -function _class(obj) { - return Object.prototype.toString.call(obj); -} -function isString(obj) { - return _class(obj) === "[object String]"; -} -function isObject(obj) { - return _class(obj) === "[object Object]"; -} -function isRegExp(obj) { - return _class(obj) === "[object RegExp]"; -} -function isFunction(obj) { - return _class(obj) === "[object Function]"; -} -function escapeRE(str) { - return str.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); -} -const defaultOptions = { - fuzzyLink: true, - fuzzyEmail: true, - fuzzyIP: false -}; -function isOptionsObj(obj) { - return Object.keys(obj || {}).reduce(function(acc, k$1) { - return acc || defaultOptions.hasOwnProperty(k$1); - }, false); -} -const defaultSchemas = { - "http:": { validate: function(text$1, pos, self) { - const tail = text$1.slice(pos); - if (!self.re.http) { - self.re.http = new RegExp("^\\/\\/" + self.re.src_auth + self.re.src_host_port_strict + self.re.src_path, "i"); - } - if (self.re.http.test(tail)) { - return tail.match(self.re.http)[0].length; - } - return 0; - } }, - "https:": "http:", - "ftp:": "http:", - "//": { validate: function(text$1, pos, self) { - const tail = text$1.slice(pos); - if (!self.re.no_http) { - self.re.no_http = new RegExp("^" + self.re.src_auth + "(?:localhost|(?:(?:" + self.re.src_domain + ")\\.)+" + self.re.src_domain_root + ")" + self.re.src_port + self.re.src_host_terminator + self.re.src_path, "i"); - } - if (self.re.no_http.test(tail)) { - if (pos >= 3 && text$1[pos - 3] === ":") { - return 0; - } - if (pos >= 3 && text$1[pos - 3] === "/") { - return 0; - } - return tail.match(self.re.no_http)[0].length; - } - return 0; - } }, - "mailto:": { validate: function(text$1, pos, self) { - const tail = text$1.slice(pos); - if (!self.re.mailto) { - self.re.mailto = new RegExp("^" + self.re.src_email_name + "@" + self.re.src_host_strict, "i"); - } - if (self.re.mailto.test(tail)) { - return tail.match(self.re.mailto)[0].length; - } - return 0; - } } -}; -const tlds_2ch_src_re = "a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]"; -const tlds_default = "biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф".split("|"); -function resetScanCache(self) { - self.__index__ = -1; - self.__text_cache__ = ""; -} -function createValidator(re) { - return function(text$1, pos) { - const tail = text$1.slice(pos); - if (re.test(tail)) { - return tail.match(re)[0].length; - } - return 0; - }; -} -function createNormalizer() { - return function(match, self) { - self.normalize(match); - }; -} -function compile(self) { - const re = self.re = re_default(self.__opts__); - const tlds = self.__tlds__.slice(); - self.onCompile(); - if (!self.__tlds_replaced__) { - tlds.push(tlds_2ch_src_re); - } - tlds.push(re.src_xn); - re.src_tlds = tlds.join("|"); - function untpl(tpl) { - return tpl.replace("%TLDS%", re.src_tlds); - } - re.email_fuzzy = RegExp(untpl(re.tpl_email_fuzzy), "i"); - re.link_fuzzy = RegExp(untpl(re.tpl_link_fuzzy), "i"); - re.link_no_ip_fuzzy = RegExp(untpl(re.tpl_link_no_ip_fuzzy), "i"); - re.host_fuzzy_test = RegExp(untpl(re.tpl_host_fuzzy_test), "i"); - const aliases = []; - self.__compiled__ = {}; - function schemaError(name, val) { - throw new Error("(LinkifyIt) Invalid schema \"" + name + "\": " + val); - } - Object.keys(self.__schemas__).forEach(function(name) { - const val = self.__schemas__[name]; - if (val === null) { - return; - } - const compiled = { - validate: null, - link: null - }; - self.__compiled__[name] = compiled; - if (isObject(val)) { - if (isRegExp(val.validate)) { - compiled.validate = createValidator(val.validate); - } else if (isFunction(val.validate)) { - compiled.validate = val.validate; - } else { - schemaError(name, val); - } - if (isFunction(val.normalize)) { - compiled.normalize = val.normalize; - } else if (!val.normalize) { - compiled.normalize = createNormalizer(); - } else { - schemaError(name, val); - } - return; - } - if (isString(val)) { - aliases.push(name); - return; - } - schemaError(name, val); - }); - aliases.forEach(function(alias) { - if (!self.__compiled__[self.__schemas__[alias]]) { - return; - } - self.__compiled__[alias].validate = self.__compiled__[self.__schemas__[alias]].validate; - self.__compiled__[alias].normalize = self.__compiled__[self.__schemas__[alias]].normalize; - }); - self.__compiled__[""] = { - validate: null, - normalize: createNormalizer() - }; - const slist = Object.keys(self.__compiled__).filter(function(name) { - return name.length > 0 && self.__compiled__[name]; - }).map(escapeRE).join("|"); - self.re.schema_test = RegExp("(^|(?!_)(?:[><|]|" + re.src_ZPCc + "))(" + slist + ")", "i"); - self.re.schema_search = RegExp("(^|(?!_)(?:[><|]|" + re.src_ZPCc + "))(" + slist + ")", "ig"); - self.re.schema_at_start = RegExp("^" + self.re.schema_search.source, "i"); - self.re.pretest = RegExp("(" + self.re.schema_test.source + ")|(" + self.re.host_fuzzy_test.source + ")|@", "i"); - resetScanCache(self); -} -/** -* class Match -* -* Match result. Single element of array, returned by [[LinkifyIt#match]] -**/ -function Match(self, shift) { - const start = self.__index__; - const end = self.__last_index__; - const text$1 = self.__text_cache__.slice(start, end); - /** - * Match#schema -> String - * - * Prefix (protocol) for matched string. - **/ - this.schema = self.__schema__.toLowerCase(); - /** - * Match#index -> Number - * - * First position of matched string. - **/ - this.index = start + shift; - /** - * Match#lastIndex -> Number - * - * Next position after matched string. - **/ - this.lastIndex = end + shift; - /** - * Match#raw -> String - * - * Matched string. - **/ - this.raw = text$1; - /** - * Match#text -> String - * - * Notmalized text of matched string. - **/ - this.text = text$1; - /** - * Match#url -> String - * - * Normalized url of matched string. - **/ - this.url = text$1; -} -function createMatch(self, shift) { - const match = new Match(self, shift); - self.__compiled__[match.schema].normalize(match, self); - return match; -} -/** -* class LinkifyIt -**/ -/** -* new LinkifyIt(schemas, options) -* - schemas (Object): Optional. Additional schemas to validate (prefix/validator) -* - options (Object): { fuzzyLink|fuzzyEmail|fuzzyIP: true|false } -* -* Creates new linkifier instance with optional additional schemas. -* Can be called without `new` keyword for convenience. -* -* By default understands: -* -* - `http(s)://...` , `ftp://...`, `mailto:...` & `//...` links -* - "fuzzy" links and emails (example.com, foo@bar.com). -* -* `schemas` is an object, where each key/value describes protocol/rule: -* -* - __key__ - link prefix (usually, protocol name with `:` at the end, `skype:` -* for example). `linkify-it` makes shure that prefix is not preceeded with -* alphanumeric char and symbols. Only whitespaces and punctuation allowed. -* - __value__ - rule to check tail after link prefix -* - _String_ - just alias to existing rule -* - _Object_ -* - _validate_ - validator function (should return matched length on success), -* or `RegExp`. -* - _normalize_ - optional function to normalize text & url of matched result -* (for example, for @twitter mentions). -* -* `options`: -* -* - __fuzzyLink__ - recognige URL-s without `http(s):` prefix. Default `true`. -* - __fuzzyIP__ - allow IPs in fuzzy links above. Can conflict with some texts -* like version numbers. Default `false`. -* - __fuzzyEmail__ - recognize emails without `mailto:` prefix. -* -**/ -function LinkifyIt(schemas, options) { - if (!(this instanceof LinkifyIt)) { - return new LinkifyIt(schemas, options); - } - if (!options) { - if (isOptionsObj(schemas)) { - options = schemas; - schemas = {}; - } - } - this.__opts__ = assign({}, defaultOptions, options); - this.__index__ = -1; - this.__last_index__ = -1; - this.__schema__ = ""; - this.__text_cache__ = ""; - this.__schemas__ = assign({}, defaultSchemas, schemas); - this.__compiled__ = {}; - this.__tlds__ = tlds_default; - this.__tlds_replaced__ = false; - this.re = {}; - compile(this); -} -/** chainable -* LinkifyIt#add(schema, definition) -* - schema (String): rule name (fixed pattern prefix) -* - definition (String|RegExp|Object): schema definition -* -* Add new rule definition. See constructor description for details. -**/ -LinkifyIt.prototype.add = function add(schema, definition) { - this.__schemas__[schema] = definition; - compile(this); - return this; -}; -/** chainable -* LinkifyIt#set(options) -* - options (Object): { fuzzyLink|fuzzyEmail|fuzzyIP: true|false } -* -* Set recognition options for links without schema. -**/ -LinkifyIt.prototype.set = function set(options) { - this.__opts__ = assign(this.__opts__, options); - return this; -}; -/** -* LinkifyIt#test(text) -> Boolean -* -* Searches linkifiable pattern and returns `true` on success or `false` on fail. -**/ -LinkifyIt.prototype.test = function test(text$1) { - this.__text_cache__ = text$1; - this.__index__ = -1; - if (!text$1.length) { - return false; - } - let m$3, ml, me, len, shift, next, re, tld_pos, at_pos; - if (this.re.schema_test.test(text$1)) { - re = this.re.schema_search; - re.lastIndex = 0; - while ((m$3 = re.exec(text$1)) !== null) { - len = this.testSchemaAt(text$1, m$3[2], re.lastIndex); - if (len) { - this.__schema__ = m$3[2]; - this.__index__ = m$3.index + m$3[1].length; - this.__last_index__ = m$3.index + m$3[0].length + len; - break; - } - } - } - if (this.__opts__.fuzzyLink && this.__compiled__["http:"]) { - tld_pos = text$1.search(this.re.host_fuzzy_test); - if (tld_pos >= 0) { - if (this.__index__ < 0 || tld_pos < this.__index__) { - if ((ml = text$1.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy)) !== null) { - shift = ml.index + ml[1].length; - if (this.__index__ < 0 || shift < this.__index__) { - this.__schema__ = ""; - this.__index__ = shift; - this.__last_index__ = ml.index + ml[0].length; - } - } - } - } - } - if (this.__opts__.fuzzyEmail && this.__compiled__["mailto:"]) { - at_pos = text$1.indexOf("@"); - if (at_pos >= 0) { - if ((me = text$1.match(this.re.email_fuzzy)) !== null) { - shift = me.index + me[1].length; - next = me.index + me[0].length; - if (this.__index__ < 0 || shift < this.__index__ || shift === this.__index__ && next > this.__last_index__) { - this.__schema__ = "mailto:"; - this.__index__ = shift; - this.__last_index__ = next; - } - } - } - } - return this.__index__ >= 0; -}; -/** -* LinkifyIt#pretest(text) -> Boolean -* -* Very quick check, that can give false positives. Returns true if link MAY BE -* can exists. Can be used for speed optimization, when you need to check that -* link NOT exists. -**/ -LinkifyIt.prototype.pretest = function pretest(text$1) { - return this.re.pretest.test(text$1); -}; -/** -* LinkifyIt#testSchemaAt(text, name, position) -> Number -* - text (String): text to scan -* - name (String): rule (schema) name -* - position (Number): text offset to check from -* -* Similar to [[LinkifyIt#test]] but checks only specific protocol tail exactly -* at given position. Returns length of found pattern (0 on fail). -**/ -LinkifyIt.prototype.testSchemaAt = function testSchemaAt(text$1, schema, pos) { - if (!this.__compiled__[schema.toLowerCase()]) { - return 0; - } - return this.__compiled__[schema.toLowerCase()].validate(text$1, pos, this); -}; -/** -* LinkifyIt#match(text) -> Array|null -* -* Returns array of found link descriptions or `null` on fail. We strongly -* recommend to use [[LinkifyIt#test]] first, for best speed. -* -* ##### Result match description -* -* - __schema__ - link schema, can be empty for fuzzy links, or `//` for -* protocol-neutral links. -* - __index__ - offset of matched text -* - __lastIndex__ - index of next char after mathch end -* - __raw__ - matched text -* - __text__ - normalized text -* - __url__ - link, generated from matched text -**/ -LinkifyIt.prototype.match = function match(text$1) { - const result = []; - let shift = 0; - if (this.__index__ >= 0 && this.__text_cache__ === text$1) { - result.push(createMatch(this, shift)); - shift = this.__last_index__; - } - let tail = shift ? text$1.slice(shift) : text$1; - while (this.test(tail)) { - result.push(createMatch(this, shift)); - tail = tail.slice(this.__last_index__); - shift += this.__last_index__; - } - if (result.length) { - return result; - } - return null; -}; -/** -* LinkifyIt#matchAtStart(text) -> Match|null -* -* Returns fully-formed (not fuzzy) link if it starts at the beginning -* of the string, and null otherwise. -**/ -LinkifyIt.prototype.matchAtStart = function matchAtStart(text$1) { - this.__text_cache__ = text$1; - this.__index__ = -1; - if (!text$1.length) return null; - const m$3 = this.re.schema_at_start.exec(text$1); - if (!m$3) return null; - const len = this.testSchemaAt(text$1, m$3[2], m$3[0].length); - if (!len) return null; - this.__schema__ = m$3[2]; - this.__index__ = m$3.index + m$3[1].length; - this.__last_index__ = m$3.index + m$3[0].length + len; - return createMatch(this, 0); -}; -/** chainable -* LinkifyIt#tlds(list [, keepOld]) -> this -* - list (Array): list of tlds -* - keepOld (Boolean): merge with current list if `true` (`false` by default) -* -* Load (or merge) new tlds list. Those are user for fuzzy links (without prefix) -* to avoid false positives. By default this algorythm used: -* -* - hostname with any 2-letter root zones are ok. -* - biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф -* are ok. -* - encoded (`xn--...`) root zones are ok. -* -* If list is replaced, then exact match for 2-chars root zones will be checked. -**/ -LinkifyIt.prototype.tlds = function tlds(list$1, keepOld) { - list$1 = Array.isArray(list$1) ? list$1 : [list$1]; - if (!keepOld) { - this.__tlds__ = list$1.slice(); - this.__tlds_replaced__ = true; - compile(this); - return this; - } - this.__tlds__ = this.__tlds__.concat(list$1).sort().filter(function(el, idx, arr) { - return el !== arr[idx - 1]; - }).reverse(); - compile(this); - return this; -}; -/** -* LinkifyIt#normalize(match) -* -* Default normalizer (if schema does not define it's own). -**/ -LinkifyIt.prototype.normalize = function normalize$1(match) { - if (!match.schema) { - match.url = "http://" + match.url; - } - if (match.schema === "mailto:" && !/^mailto:/i.test(match.url)) { - match.url = "mailto:" + match.url; - } -}; -/** -* LinkifyIt#onCompile() -* -* Override to modify basic RegExp-s. -**/ -LinkifyIt.prototype.onCompile = function onCompile() {}; -var linkify_it_default = LinkifyIt; - -/** Highest positive signed 32-bit float value */ -const maxInt = 2147483647; -/** Bootstring parameters */ -const base = 36; -const tMin = 1; -const tMax = 26; -const skew = 38; -const damp = 700; -const initialBias = 72; -const initialN = 128; -const delimiter = "-"; -/** Regular expressions */ -const regexPunycode = /^xn--/; -const regexNonASCII = /[^\0-\x7F]/; -const regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g; -/** Error messages */ -const errors = { - "overflow": "Overflow: input needs wider integers to process", - "not-basic": "Illegal input >= 0x80 (not a basic code point)", - "invalid-input": "Invalid input" -}; -/** Convenience shortcuts */ -const baseMinusTMin = base - tMin; -const floor = Math.floor; -const stringFromCharCode = String.fromCharCode; -/** -* A generic error utility function. -* @private -* @param {String} type The error type. -* @returns {Error} Throws a `RangeError` with the applicable error message. -*/ -function error(type$2) { - throw new RangeError(errors[type$2]); -} -/** -* A generic `Array#map` utility function. -* @private -* @param {Array} array The array to iterate over. -* @param {Function} callback The function that gets called for every array -* item. -* @returns {Array} A new array of values returned by the callback function. -*/ -function map(array, callback) { - const result = []; - let length = array.length; - while (length--) { - result[length] = callback(array[length]); - } - return result; -} -/** -* A simple `Array#map`-like wrapper to work with domain name strings or email -* addresses. -* @private -* @param {String} domain The domain name or email address. -* @param {Function} callback The function that gets called for every -* character. -* @returns {String} A new string of characters returned by the callback -* function. -*/ -function mapDomain(domain, callback) { - const parts = domain.split("@"); - let result = ""; - if (parts.length > 1) { - result = parts[0] + "@"; - domain = parts[1]; - } - domain = domain.replace(regexSeparators, "."); - const labels = domain.split("."); - const encoded = map(labels, callback).join("."); - return result + encoded; -} -/** -* Creates an array containing the numeric code points of each Unicode -* character in the string. While JavaScript uses UCS-2 internally, -* this function will convert a pair of surrogate halves (each of which -* UCS-2 exposes as separate characters) into a single code point, -* matching UTF-16. -* @see `punycode.ucs2.encode` -* @see -* @memberOf punycode.ucs2 -* @name decode -* @param {String} string The Unicode input string (UCS-2). -* @returns {Array} The new array of code points. -*/ -function ucs2decode(string) { - const output = []; - let counter = 0; - const length = string.length; - while (counter < length) { - const value = string.charCodeAt(counter++); - if (value >= 55296 && value <= 56319 && counter < length) { - const extra = string.charCodeAt(counter++); - if ((extra & 64512) == 56320) { - output.push(((value & 1023) << 10) + (extra & 1023) + 65536); - } else { - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; -} -/** -* Creates a string based on an array of numeric code points. -* @see `punycode.ucs2.decode` -* @memberOf punycode.ucs2 -* @name encode -* @param {Array} codePoints The array of numeric code points. -* @returns {String} The new Unicode string (UCS-2). -*/ -const ucs2encode = (codePoints) => String.fromCodePoint(...codePoints); -/** -* Converts a basic code point into a digit/integer. -* @see `digitToBasic()` -* @private -* @param {Number} codePoint The basic numeric code point value. -* @returns {Number} The numeric value of a basic code point (for use in -* representing integers) in the range `0` to `base - 1`, or `base` if -* the code point does not represent a value. -*/ -const basicToDigit = function(codePoint) { - if (codePoint >= 48 && codePoint < 58) { - return 26 + (codePoint - 48); - } - if (codePoint >= 65 && codePoint < 91) { - return codePoint - 65; - } - if (codePoint >= 97 && codePoint < 123) { - return codePoint - 97; - } - return base; -}; -/** -* Converts a digit/integer into a basic code point. -* @see `basicToDigit()` -* @private -* @param {Number} digit The numeric value of a basic code point. -* @returns {Number} The basic code point whose value (when used for -* representing integers) is `digit`, which needs to be in the range -* `0` to `base - 1`. If `flag` is non-zero, the uppercase form is -* used; else, the lowercase form is used. The behavior is undefined -* if `flag` is non-zero and `digit` has no uppercase form. -*/ -const digitToBasic = function(digit, flag) { - return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); -}; -/** -* Bias adaptation function as per section 3.4 of RFC 3492. -* https://tools.ietf.org/html/rfc3492#section-3.4 -* @private -*/ -const adapt = function(delta, numPoints, firstTime) { - let k$1 = 0; - delta = firstTime ? floor(delta / damp) : delta >> 1; - delta += floor(delta / numPoints); - for (; delta > baseMinusTMin * tMax >> 1; k$1 += base) { - delta = floor(delta / baseMinusTMin); - } - return floor(k$1 + (baseMinusTMin + 1) * delta / (delta + skew)); -}; -/** -* Converts a Punycode string of ASCII-only symbols to a string of Unicode -* symbols. -* @memberOf punycode -* @param {String} input The Punycode string of ASCII-only symbols. -* @returns {String} The resulting string of Unicode symbols. -*/ -const decode = function(input) { - const output = []; - const inputLength = input.length; - let i$10 = 0; - let n$13 = initialN; - let bias = initialBias; - let basic = input.lastIndexOf(delimiter); - if (basic < 0) { - basic = 0; - } - for (let j$2 = 0; j$2 < basic; ++j$2) { - if (input.charCodeAt(j$2) >= 128) { - error("not-basic"); - } - output.push(input.charCodeAt(j$2)); - } - for (let index = basic > 0 ? basic + 1 : 0; index < inputLength;) { - const oldi = i$10; - for (let w$1 = 1, k$1 = base;; k$1 += base) { - if (index >= inputLength) { - error("invalid-input"); - } - const digit = basicToDigit(input.charCodeAt(index++)); - if (digit >= base) { - error("invalid-input"); - } - if (digit > floor((maxInt - i$10) / w$1)) { - error("overflow"); - } - i$10 += digit * w$1; - const t$7 = k$1 <= bias ? tMin : k$1 >= bias + tMax ? tMax : k$1 - bias; - if (digit < t$7) { - break; - } - const baseMinusT = base - t$7; - if (w$1 > floor(maxInt / baseMinusT)) { - error("overflow"); - } - w$1 *= baseMinusT; - } - const out = output.length + 1; - bias = adapt(i$10 - oldi, out, oldi == 0); - if (floor(i$10 / out) > maxInt - n$13) { - error("overflow"); - } - n$13 += floor(i$10 / out); - i$10 %= out; - output.splice(i$10++, 0, n$13); - } - return String.fromCodePoint(...output); -}; -/** -* Converts a string of Unicode symbols (e.g. a domain name label) to a -* Punycode string of ASCII-only symbols. -* @memberOf punycode -* @param {String} input The string of Unicode symbols. -* @returns {String} The resulting Punycode string of ASCII-only symbols. -*/ -const encode = function(input) { - const output = []; - input = ucs2decode(input); - const inputLength = input.length; - let n$13 = initialN; - let delta = 0; - let bias = initialBias; - for (const currentValue of input) { - if (currentValue < 128) { - output.push(stringFromCharCode(currentValue)); - } - } - const basicLength = output.length; - let handledCPCount = basicLength; - if (basicLength) { - output.push(delimiter); - } - while (handledCPCount < inputLength) { - let m$3 = maxInt; - for (const currentValue of input) { - if (currentValue >= n$13 && currentValue < m$3) { - m$3 = currentValue; - } - } - const handledCPCountPlusOne = handledCPCount + 1; - if (m$3 - n$13 > floor((maxInt - delta) / handledCPCountPlusOne)) { - error("overflow"); - } - delta += (m$3 - n$13) * handledCPCountPlusOne; - n$13 = m$3; - for (const currentValue of input) { - if (currentValue < n$13 && ++delta > maxInt) { - error("overflow"); - } - if (currentValue === n$13) { - let q = delta; - for (let k$1 = base;; k$1 += base) { - const t$7 = k$1 <= bias ? tMin : k$1 >= bias + tMax ? tMax : k$1 - bias; - if (q < t$7) { - break; - } - const qMinusT = q - t$7; - const baseMinusT = base - t$7; - output.push(stringFromCharCode(digitToBasic(t$7 + qMinusT % baseMinusT, 0))); - q = floor(qMinusT / baseMinusT); - } - output.push(stringFromCharCode(digitToBasic(q, 0))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength); - delta = 0; - ++handledCPCount; - } - } - ++delta; - ++n$13; - } - return output.join(""); -}; -/** -* Converts a Punycode string representing a domain name or an email address -* to Unicode. Only the Punycoded parts of the input will be converted, i.e. -* it doesn't matter if you call it on a string that has already been -* converted to Unicode. -* @memberOf punycode -* @param {String} input The Punycoded domain name or email address to -* convert to Unicode. -* @returns {String} The Unicode representation of the given Punycode -* string. -*/ -const toUnicode = function(input) { - return mapDomain(input, function(string) { - return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; - }); -}; -/** -* Converts a Unicode string representing a domain name or an email address to -* Punycode. Only the non-ASCII parts of the domain name will be converted, -* i.e. it doesn't matter if you call it with a domain that's already in -* ASCII. -* @memberOf punycode -* @param {String} input The domain name or email address to convert, as a -* Unicode string. -* @returns {String} The Punycode representation of the given domain name or -* email address. -*/ -const toASCII = function(input) { - return mapDomain(input, function(string) { - return regexNonASCII.test(string) ? "xn--" + encode(string) : string; - }); -}; -/** Define the public API */ -const punycode = { - "version": "2.3.1", - "ucs2": { - "decode": ucs2decode, - "encode": ucs2encode - }, - "decode": decode, - "encode": encode, - "toASCII": toASCII, - "toUnicode": toUnicode -}; -var punycode_es6_default = punycode; - -var default_default = { - options: { - html: false, - xhtmlOut: false, - breaks: false, - langPrefix: "language-", - linkify: false, - typographer: false, - quotes: "“”‘’", - highlight: null, - maxNesting: 100 - }, - components: { - core: {}, - block: {}, - inline: {} - } -}; - -var zero_default = { - options: { - html: false, - xhtmlOut: false, - breaks: false, - langPrefix: "language-", - linkify: false, - typographer: false, - quotes: "“”‘’", - highlight: null, - maxNesting: 20 - }, - components: { - core: { rules: [ - "normalize", - "block", - "inline", - "text_join" - ] }, - block: { rules: ["paragraph"] }, - inline: { - rules: ["text"], - rules2: ["balance_pairs", "fragments_join"] - } - } -}; - -var commonmark_default = { - options: { - html: true, - xhtmlOut: true, - breaks: false, - langPrefix: "language-", - linkify: false, - typographer: false, - quotes: "“”‘’", - highlight: null, - maxNesting: 20 - }, - components: { - core: { rules: [ - "normalize", - "block", - "inline", - "text_join" - ] }, - block: { rules: [ - "blockquote", - "code", - "fence", - "heading", - "hr", - "html_block", - "lheading", - "list", - "reference", - "paragraph" - ] }, - inline: { - rules: [ - "autolink", - "backticks", - "emphasis", - "entity", - "escape", - "html_inline", - "image", - "link", - "newline", - "text" - ], - rules2: [ - "balance_pairs", - "emphasis", - "fragments_join" - ] - } - } -}; - -const config = { - default: default_default, - zero: zero_default, - commonmark: commonmark_default -}; -const BAD_PROTO_RE = /^(vbscript|javascript|file|data):/; -const GOOD_DATA_RE = /^data:image\/(gif|png|jpeg|webp);/; -function validateLink(url) { - const str = url.trim().toLowerCase(); - return BAD_PROTO_RE.test(str) ? GOOD_DATA_RE.test(str) : true; -} -const RECODE_HOSTNAME_FOR = [ - "http:", - "https:", - "mailto:" -]; -function normalizeLink(url) { - const parsed = parse_default(url, true); - if (parsed.hostname) { - if (!parsed.protocol || RECODE_HOSTNAME_FOR.indexOf(parsed.protocol) >= 0) { - try { - parsed.hostname = punycode_es6_default.toASCII(parsed.hostname); - } catch (er) {} - } - } - return encode_default(format(parsed)); -} -function normalizeLinkText(url) { - const parsed = parse_default(url, true); - if (parsed.hostname) { - if (!parsed.protocol || RECODE_HOSTNAME_FOR.indexOf(parsed.protocol) >= 0) { - try { - parsed.hostname = punycode_es6_default.toUnicode(parsed.hostname); - } catch (er) {} - } - } - return decode_default(format(parsed), decode_default.defaultChars + "%"); -} -/** -* class MarkdownIt -* -* Main parser/renderer class. -* -* ##### Usage -* -* ```javascript -* // node.js, "classic" way: -* var MarkdownIt = require('markdown-it'), -* md = new MarkdownIt(); -* var result = md.render('# markdown-it rulezz!'); -* -* // node.js, the same, but with sugar: -* var md = require('markdown-it')(); -* var result = md.render('# markdown-it rulezz!'); -* -* // browser without AMD, added to "window" on script load -* // Note, there are no dash. -* var md = window.markdownit(); -* var result = md.render('# markdown-it rulezz!'); -* ``` -* -* Single line rendering, without paragraph wrap: -* -* ```javascript -* var md = require('markdown-it')(); -* var result = md.renderInline('__markdown-it__ rulezz!'); -* ``` -**/ -/** -* new MarkdownIt([presetName, options]) -* - presetName (String): optional, `commonmark` / `zero` -* - options (Object) -* -* Creates parser instanse with given config. Can be called without `new`. -* -* ##### presetName -* -* MarkdownIt provides named presets as a convenience to quickly -* enable/disable active syntax rules and options for common use cases. -* -* - ["commonmark"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.mjs) - -* configures parser to strict [CommonMark](http://commonmark.org/) mode. -* - [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.mjs) - -* similar to GFM, used when no preset name given. Enables all available rules, -* but still without html, typographer & autolinker. -* - ["zero"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.mjs) - -* all rules disabled. Useful to quickly setup your config via `.enable()`. -* For example, when you need only `bold` and `italic` markup and nothing else. -* -* ##### options: -* -* - __html__ - `false`. Set `true` to enable HTML tags in source. Be careful! -* That's not safe! You may need external sanitizer to protect output from XSS. -* It's better to extend features via plugins, instead of enabling HTML. -* - __xhtmlOut__ - `false`. Set `true` to add '/' when closing single tags -* (`
    `). This is needed only for full CommonMark compatibility. In real -* world you will need HTML output. -* - __breaks__ - `false`. Set `true` to convert `\n` in paragraphs into `
    `. -* - __langPrefix__ - `language-`. CSS language class prefix for fenced blocks. -* Can be useful for external highlighters. -* - __linkify__ - `false`. Set `true` to autoconvert URL-like text to links. -* - __typographer__ - `false`. Set `true` to enable [some language-neutral -* replacement](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.mjs) + -* quotes beautification (smartquotes). -* - __quotes__ - `“”‘’`, String or Array. Double + single quotes replacement -* pairs, when typographer enabled and smartquotes on. For example, you can -* use `'«»„“'` for Russian, `'„“‚‘'` for German, and -* `['«\xA0', '\xA0»', '‹\xA0', '\xA0›']` for French (including nbsp). -* - __highlight__ - `null`. Highlighter function for fenced code blocks. -* Highlighter `function (str, lang)` should return escaped HTML. It can also -* return empty string if the source was not changed and should be escaped -* externaly. If result starts with ` or ``): -* -* ```javascript -* var hljs = require('highlight.js') // https://highlightjs.org/ -* -* // Actual default values -* var md = require('markdown-it')({ -* highlight: function (str, lang) { -* if (lang && hljs.getLanguage(lang)) { -* try { -* return '
    ' +
    -*                hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
    -*                '
    '; -* } catch (__) {} -* } -* -* return '
    ' + md.utils.escapeHtml(str) + '
    '; -* } -* }); -* ``` -* -**/ -function MarkdownIt(presetName, options) { - if (!(this instanceof MarkdownIt)) { - return new MarkdownIt(presetName, options); - } - if (!options) { - if (!isString$1(presetName)) { - options = presetName || {}; - presetName = "default"; - } - } - /** - * MarkdownIt#inline -> ParserInline - * - * Instance of [[ParserInline]]. You may need it to add new rules when - * writing plugins. For simple rules control use [[MarkdownIt.disable]] and - * [[MarkdownIt.enable]]. - **/ - this.inline = new parser_inline_default(); - /** - * MarkdownIt#block -> ParserBlock - * - * Instance of [[ParserBlock]]. You may need it to add new rules when - * writing plugins. For simple rules control use [[MarkdownIt.disable]] and - * [[MarkdownIt.enable]]. - **/ - this.block = new parser_block_default(); - /** - * MarkdownIt#core -> Core - * - * Instance of [[Core]] chain executor. You may need it to add new rules when - * writing plugins. For simple rules control use [[MarkdownIt.disable]] and - * [[MarkdownIt.enable]]. - **/ - this.core = new parser_core_default(); - /** - * MarkdownIt#renderer -> Renderer - * - * Instance of [[Renderer]]. Use it to modify output look. Or to add rendering - * rules for new token types, generated by plugins. - * - * ##### Example - * - * ```javascript - * var md = require('markdown-it')(); - * - * function myToken(tokens, idx, options, env, self) { - * //... - * return result; - * }; - * - * md.renderer.rules['my_token'] = myToken - * ``` - * - * See [[Renderer]] docs and [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.mjs). - **/ - this.renderer = new renderer_default(); - /** - * MarkdownIt#linkify -> LinkifyIt - * - * [linkify-it](https://github.com/markdown-it/linkify-it) instance. - * Used by [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.mjs) - * rule. - **/ - this.linkify = new linkify_it_default(); - /** - * MarkdownIt#validateLink(url) -> Boolean - * - * Link validation function. CommonMark allows too much in links. By default - * we disable `javascript:`, `vbscript:`, `file:` schemas, and almost all `data:...` schemas - * except some embedded image types. - * - * You can change this behaviour: - * - * ```javascript - * var md = require('markdown-it')(); - * // enable everything - * md.validateLink = function () { return true; } - * ``` - **/ - this.validateLink = validateLink; - /** - * MarkdownIt#normalizeLink(url) -> String - * - * Function used to encode link url to a machine-readable format, - * which includes url-encoding, punycode, etc. - **/ - this.normalizeLink = normalizeLink; - /** - * MarkdownIt#normalizeLinkText(url) -> String - * - * Function used to decode link url to a human-readable format` - **/ - this.normalizeLinkText = normalizeLinkText; - /** - * MarkdownIt#utils -> utils - * - * Assorted utility functions, useful to write plugins. See details - * [here](https://github.com/markdown-it/markdown-it/blob/master/lib/common/utils.mjs). - **/ - this.utils = utils_exports; - /** - * MarkdownIt#helpers -> helpers - * - * Link components parser functions, useful to write plugins. See details - * [here](https://github.com/markdown-it/markdown-it/blob/master/lib/helpers). - **/ - this.helpers = assign$1({}, helpers_exports); - this.options = {}; - this.configure(presetName); - if (options) { - this.set(options); - } -} -/** chainable -* MarkdownIt.set(options) -* -* Set parser options (in the same format as in constructor). Probably, you -* will never need it, but you can change options after constructor call. -* -* ##### Example -* -* ```javascript -* var md = require('markdown-it')() -* .set({ html: true, breaks: true }) -* .set({ typographer, true }); -* ``` -* -* __Note:__ To achieve the best possible performance, don't modify a -* `markdown-it` instance options on the fly. If you need multiple configurations -* it's best to create multiple instances and initialize each with separate -* config. -**/ -MarkdownIt.prototype.set = function(options) { - assign$1(this.options, options); - return this; -}; -/** chainable, internal -* MarkdownIt.configure(presets) -* -* Batch load of all options and compenent settings. This is internal method, -* and you probably will not need it. But if you will - see available presets -* and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets) -* -* We strongly recommend to use presets instead of direct config loads. That -* will give better compatibility with next versions. -**/ -MarkdownIt.prototype.configure = function(presets) { - const self = this; - if (isString$1(presets)) { - const presetName = presets; - presets = config[presetName]; - if (!presets) { - throw new Error("Wrong `markdown-it` preset \"" + presetName + "\", check name"); - } - } - if (!presets) { - throw new Error("Wrong `markdown-it` preset, can't be empty"); - } - if (presets.options) { - self.set(presets.options); - } - if (presets.components) { - Object.keys(presets.components).forEach(function(name) { - if (presets.components[name].rules) { - self[name].ruler.enableOnly(presets.components[name].rules); - } - if (presets.components[name].rules2) { - self[name].ruler2.enableOnly(presets.components[name].rules2); - } - }); - } - return this; -}; -/** chainable -* MarkdownIt.enable(list, ignoreInvalid) -* - list (String|Array): rule name or list of rule names to enable -* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found. -* -* Enable list or rules. It will automatically find appropriate components, -* containing rules with given names. If rule not found, and `ignoreInvalid` -* not set - throws exception. -* -* ##### Example -* -* ```javascript -* var md = require('markdown-it')() -* .enable(['sub', 'sup']) -* .disable('smartquotes'); -* ``` -**/ -MarkdownIt.prototype.enable = function(list$1, ignoreInvalid) { - let result = []; - if (!Array.isArray(list$1)) { - list$1 = [list$1]; - } - [ - "core", - "block", - "inline" - ].forEach(function(chain) { - result = result.concat(this[chain].ruler.enable(list$1, true)); - }, this); - result = result.concat(this.inline.ruler2.enable(list$1, true)); - const missed = list$1.filter(function(name) { - return result.indexOf(name) < 0; - }); - if (missed.length && !ignoreInvalid) { - throw new Error("MarkdownIt. Failed to enable unknown rule(s): " + missed); - } - return this; -}; -/** chainable -* MarkdownIt.disable(list, ignoreInvalid) -* - list (String|Array): rule name or list of rule names to disable. -* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found. -* -* The same as [[MarkdownIt.enable]], but turn specified rules off. -**/ -MarkdownIt.prototype.disable = function(list$1, ignoreInvalid) { - let result = []; - if (!Array.isArray(list$1)) { - list$1 = [list$1]; - } - [ - "core", - "block", - "inline" - ].forEach(function(chain) { - result = result.concat(this[chain].ruler.disable(list$1, true)); - }, this); - result = result.concat(this.inline.ruler2.disable(list$1, true)); - const missed = list$1.filter(function(name) { - return result.indexOf(name) < 0; - }); - if (missed.length && !ignoreInvalid) { - throw new Error("MarkdownIt. Failed to disable unknown rule(s): " + missed); - } - return this; -}; -/** chainable -* MarkdownIt.use(plugin, params) -* -* Load specified plugin with given params into current parser instance. -* It's just a sugar to call `plugin(md, params)` with curring. -* -* ##### Example -* -* ```javascript -* var iterator = require('markdown-it-for-inline'); -* var md = require('markdown-it')() -* .use(iterator, 'foo_replace', 'text', function (tokens, idx) { -* tokens[idx].content = tokens[idx].content.replace(/foo/g, 'bar'); -* }); -* ``` -**/ -MarkdownIt.prototype.use = function(plugin) { - const args = [this].concat(Array.prototype.slice.call(arguments, 1)); - plugin.apply(plugin, args); - return this; -}; -/** internal -* MarkdownIt.parse(src, env) -> Array -* - src (String): source string -* - env (Object): environment sandbox -* -* Parse input string and return list of block tokens (special token type -* "inline" will contain list of inline tokens). You should not call this -* method directly, until you write custom renderer (for example, to produce -* AST). -* -* `env` is used to pass data between "distributed" rules and return additional -* metadata like reference info, needed for the renderer. It also can be used to -* inject data in specific cases. Usually, you will be ok to pass `{}`, -* and then pass updated object to renderer. -**/ -MarkdownIt.prototype.parse = function(src, env) { - if (typeof src !== "string") { - throw new Error("Input data should be a String"); - } - const state = new this.core.State(src, this, env); - this.core.process(state); - return state.tokens; -}; -/** -* MarkdownIt.render(src [, env]) -> String -* - src (String): source string -* - env (Object): environment sandbox -* -* Render markdown string into html. It does all magic for you :). -* -* `env` can be used to inject additional metadata (`{}` by default). -* But you will not need it with high probability. See also comment -* in [[MarkdownIt.parse]]. -**/ -MarkdownIt.prototype.render = function(src, env) { - env = env || {}; - return this.renderer.render(this.parse(src, env), this.options, env); -}; -/** internal -* MarkdownIt.parseInline(src, env) -> Array -* - src (String): source string -* - env (Object): environment sandbox -* -* The same as [[MarkdownIt.parse]] but skip all block rules. It returns the -* block tokens list with the single `inline` element, containing parsed inline -* tokens in `children` property. Also updates `env` object. -**/ -MarkdownIt.prototype.parseInline = function(src, env) { - const state = new this.core.State(src, this, env); - state.inlineMode = true; - this.core.process(state); - return state.tokens; -}; -/** -* MarkdownIt.renderInline(src [, env]) -> String -* - src (String): source string -* - env (Object): environment sandbox -* -* Similar to [[MarkdownIt.render]] but for single paragraph content. Result -* will NOT be wrapped into `

    ` tags. -**/ -MarkdownIt.prototype.renderInline = function(src, env) { - env = env || {}; - return this.renderer.render(this.parseInline(src, env), this.options, env); -}; -var lib_default = MarkdownIt; - -/** -* This is only safe for (and intended to be used for) text node positions. If -* you are using attribute position, then this is only safe if the attribute -* value is surrounded by double-quotes, and is unsafe otherwise (because the -* value could break out of the attribute value and e.g. add another attribute). -*/ -function escapeNodeText(str) { - const frag = document.createElement("div"); - D(b`${str}`, frag); - return frag.innerHTML.replaceAll(//gim, ""); -} -function unescapeNodeText(str) { - if (!str) { - return ""; - } - const frag = document.createElement("textarea"); - frag.innerHTML = str; - return frag.value; -} - -var MarkdownDirective = class extends i$5 { - #markdownIt = lib_default({ highlight: (str, lang) => { - switch (lang) { - case "html": { - const iframe = document.createElement("iframe"); - iframe.classList.add("html-view"); - iframe.srcdoc = str; - iframe.sandbox = ""; - return iframe.innerHTML; - } - default: return escapeNodeText(str); - } - } }); - #lastValue = null; - #lastTagClassMap = null; - update(_part, [value, tagClassMap]) { - if (this.#lastValue === value && JSON.stringify(tagClassMap) === this.#lastTagClassMap) { - return E; - } - this.#lastValue = value; - this.#lastTagClassMap = JSON.stringify(tagClassMap); - return this.render(value, tagClassMap); - } - #originalClassMap = new Map(); - #applyTagClassMap(tagClassMap) { - Object.entries(tagClassMap).forEach(([tag]) => { - let tokenName; - switch (tag) { - case "p": - tokenName = "paragraph"; - break; - case "h1": - case "h2": - case "h3": - case "h4": - case "h5": - case "h6": - tokenName = "heading"; - break; - case "ul": - tokenName = "bullet_list"; - break; - case "ol": - tokenName = "ordered_list"; - break; - case "li": - tokenName = "list_item"; - break; - case "a": - tokenName = "link"; - break; - case "strong": - tokenName = "strong"; - break; - case "em": - tokenName = "em"; - break; - } - if (!tokenName) { - return; - } - const key = `${tokenName}_open`; - this.#markdownIt.renderer.rules[key] = (tokens, idx, options, _env, self) => { - const token = tokens[idx]; - const tokenClasses = tagClassMap[token.tag] ?? []; - for (const clazz of tokenClasses) { - token.attrJoin("class", clazz); - } - return self.renderToken(tokens, idx, options); - }; - }); - } - #unapplyTagClassMap() { - for (const [key] of this.#originalClassMap) { - delete this.#markdownIt.renderer.rules[key]; - } - this.#originalClassMap.clear(); - } - /** - * Renders the markdown string to HTML using MarkdownIt. - * - * Note: MarkdownIt doesn't enable HTML in its output, so we render the - * value directly without further sanitization. - * @see https://github.com/markdown-it/markdown-it/blob/master/docs/security.md - */ - render(value, tagClassMap) { - if (tagClassMap) { - this.#applyTagClassMap(tagClassMap); - } - const htmlString = this.#markdownIt.render(value); - this.#unapplyTagClassMap(); - return o(htmlString); - } -}; -const markdown = e$10(MarkdownDirective); -const markdownItStandalone = lib_default(); -function renderMarkdownToHtmlString(value) { - return markdownItStandalone.render(value); -} - -var __esDecorate$1 = void 0 && (void 0).__esDecorate || function(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { - function accept(f$4) { - if (f$4 !== void 0 && typeof f$4 !== "function") throw new TypeError("Function expected"); - return f$4; - } - var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; - var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; - var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); - var _$1, done = false; - for (var i$10 = decorators.length - 1; i$10 >= 0; i$10--) { - var context = {}; - for (var p$3 in contextIn) context[p$3] = p$3 === "access" ? {} : contextIn[p$3]; - for (var p$3 in contextIn.access) context.access[p$3] = contextIn.access[p$3]; - context.addInitializer = function(f$4) { - if (done) throw new TypeError("Cannot add initializers after decoration has completed"); - extraInitializers.push(accept(f$4 || null)); - }; - var result = (0, decorators[i$10])(kind === "accessor" ? { - get: descriptor.get, - set: descriptor.set - } : descriptor[key], context); - if (kind === "accessor") { - if (result === void 0) continue; - if (result === null || typeof result !== "object") throw new TypeError("Object expected"); - if (_$1 = accept(result.get)) descriptor.get = _$1; - if (_$1 = accept(result.set)) descriptor.set = _$1; - if (_$1 = accept(result.init)) initializers.unshift(_$1); - } else if (_$1 = accept(result)) { - if (kind === "field") initializers.unshift(_$1); - else descriptor[key] = _$1; - } - } - if (target) Object.defineProperty(target, contextIn.name, descriptor); - done = true; -}; -var __runInitializers$1 = void 0 && (void 0).__runInitializers || function(thisArg, initializers, value) { - var useValue = arguments.length > 2; - for (var i$10 = 0; i$10 < initializers.length; i$10++) { - value = useValue ? initializers[i$10].call(thisArg, value) : initializers[i$10].call(thisArg); - } - return useValue ? value : void 0; -}; -let Text = (() => { - let _classDecorators = [t$1("a2ui-text")]; - let _classDescriptor; - let _classExtraInitializers = []; - let _classThis; - let _classSuper = Root; - let _text_decorators; - let _text_initializers = []; - let _text_extraInitializers = []; - let _usageHint_decorators; - let _usageHint_initializers = []; - let _usageHint_extraInitializers = []; - var Text = class extends _classSuper { - static { - _classThis = this; - } - static { - const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; - _text_decorators = [n$6()]; - _usageHint_decorators = [n$6({ - reflect: true, - attribute: "usage-hint" - })]; - __esDecorate$1(this, null, _text_decorators, { - kind: "accessor", - name: "text", - static: false, - private: false, - access: { - has: (obj) => "text" in obj, - get: (obj) => obj.text, - set: (obj, value) => { - obj.text = value; - } - }, - metadata: _metadata - }, _text_initializers, _text_extraInitializers); - __esDecorate$1(this, null, _usageHint_decorators, { - kind: "accessor", - name: "usageHint", - static: false, - private: false, - access: { - has: (obj) => "usageHint" in obj, - get: (obj) => obj.usageHint, - set: (obj, value) => { - obj.usageHint = value; - } - }, - metadata: _metadata - }, _usageHint_initializers, _usageHint_extraInitializers); - __esDecorate$1(null, _classDescriptor = { value: _classThis }, _classDecorators, { - kind: "class", - name: _classThis.name, - metadata: _metadata - }, null, _classExtraInitializers); - Text = _classThis = _classDescriptor.value; - if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { - enumerable: true, - configurable: true, - writable: true, - value: _metadata - }); - } - #text_accessor_storage = __runInitializers$1(this, _text_initializers, null); - get text() { - return this.#text_accessor_storage; - } - set text(value) { - this.#text_accessor_storage = value; - } - #usageHint_accessor_storage = (__runInitializers$1(this, _text_extraInitializers), __runInitializers$1(this, _usageHint_initializers, null)); - get usageHint() { - return this.#usageHint_accessor_storage; - } - set usageHint(value) { - this.#usageHint_accessor_storage = value; - } - static { - this.styles = [structuralStyles, i$9` - :host { - display: block; - flex: var(--weight); - } - - h1, - h2, - h3, - h4, - h5 { - line-height: inherit; - font: inherit; - } - `]; - } - #renderText() { - let textValue = null; - if (this.text && typeof this.text === "object") { - if ("literalString" in this.text && this.text.literalString) { - textValue = this.text.literalString; - } else if ("literal" in this.text && this.text.literal !== undefined) { - textValue = this.text.literal; - } else if (this.text && "path" in this.text && this.text.path) { - if (!this.processor || !this.component) { - return b`(no model)`; - } - const value = this.processor.getData(this.component, this.text.path, this.surfaceId ?? A2uiMessageProcessor.DEFAULT_SURFACE_ID); - if (value !== null && value !== undefined) { - textValue = value.toString(); - } - } - } - if (textValue === null || textValue === undefined) { - return b`(empty)`; - } - let markdownText = textValue; - switch (this.usageHint) { - case "h1": - markdownText = `# ${markdownText}`; - break; - case "h2": - markdownText = `## ${markdownText}`; - break; - case "h3": - markdownText = `### ${markdownText}`; - break; - case "h4": - markdownText = `#### ${markdownText}`; - break; - case "h5": - markdownText = `##### ${markdownText}`; - break; - case "caption": - markdownText = `*${markdownText}*`; - break; - default: break; - } - return b`${markdown(markdownText, appendToAll(this.theme.markdown, [ - "ol", - "ul", - "li" - ], {}))}`; - } - #areHintedStyles(styles) { - if (typeof styles !== "object") return false; - if (Array.isArray(styles)) return false; - if (!styles) return false; - const expected = [ - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "caption", - "body" - ]; - return expected.every((v$2) => v$2 in styles); - } - #getAdditionalStyles() { - let additionalStyles = {}; - const styles = this.theme.additionalStyles?.Text; - if (!styles) return additionalStyles; - if (this.#areHintedStyles(styles)) { - const hint = this.usageHint ?? "body"; - additionalStyles = styles[hint]; - } else { - additionalStyles = styles; - } - return additionalStyles; - } - render() { - const classes = merge(this.theme.components.Text.all, this.usageHint ? this.theme.components.Text[this.usageHint] : {}); - return b`

    - ${this.#renderText()} -
    `; - } - constructor() { - super(...arguments); - __runInitializers$1(this, _usageHint_extraInitializers); - } - static { - __runInitializers$1(_classThis, _classExtraInitializers); - } - }; - return Text = _classThis; -})(); - -var __esDecorate = void 0 && (void 0).__esDecorate || function(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { - function accept(f$4) { - if (f$4 !== void 0 && typeof f$4 !== "function") throw new TypeError("Function expected"); - return f$4; - } - var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; - var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; - var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); - var _$1, done = false; - for (var i$10 = decorators.length - 1; i$10 >= 0; i$10--) { - var context = {}; - for (var p$3 in contextIn) context[p$3] = p$3 === "access" ? {} : contextIn[p$3]; - for (var p$3 in contextIn.access) context.access[p$3] = contextIn.access[p$3]; - context.addInitializer = function(f$4) { - if (done) throw new TypeError("Cannot add initializers after decoration has completed"); - extraInitializers.push(accept(f$4 || null)); - }; - var result = (0, decorators[i$10])(kind === "accessor" ? { - get: descriptor.get, - set: descriptor.set - } : descriptor[key], context); - if (kind === "accessor") { - if (result === void 0) continue; - if (result === null || typeof result !== "object") throw new TypeError("Object expected"); - if (_$1 = accept(result.get)) descriptor.get = _$1; - if (_$1 = accept(result.set)) descriptor.set = _$1; - if (_$1 = accept(result.init)) initializers.unshift(_$1); - } else if (_$1 = accept(result)) { - if (kind === "field") initializers.unshift(_$1); - else descriptor[key] = _$1; - } - } - if (target) Object.defineProperty(target, contextIn.name, descriptor); - done = true; -}; -var __runInitializers = void 0 && (void 0).__runInitializers || function(thisArg, initializers, value) { - var useValue = arguments.length > 2; - for (var i$10 = 0; i$10 < initializers.length; i$10++) { - value = useValue ? initializers[i$10].call(thisArg, value) : initializers[i$10].call(thisArg); - } - return useValue ? value : void 0; -}; -let Video = (() => { - let _classDecorators = [t$1("a2ui-video")]; - let _classDescriptor; - let _classExtraInitializers = []; - let _classThis; - let _classSuper = Root; - let _url_decorators; - let _url_initializers = []; - let _url_extraInitializers = []; - var Video = class extends _classSuper { - static { - _classThis = this; - } - static { - const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; - _url_decorators = [n$6()]; - __esDecorate(this, null, _url_decorators, { - kind: "accessor", - name: "url", - static: false, - private: false, - access: { - has: (obj) => "url" in obj, - get: (obj) => obj.url, - set: (obj, value) => { - obj.url = value; - } - }, - metadata: _metadata - }, _url_initializers, _url_extraInitializers); - __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { - kind: "class", - name: _classThis.name, - metadata: _metadata - }, null, _classExtraInitializers); - Video = _classThis = _classDescriptor.value; - if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { - enumerable: true, - configurable: true, - writable: true, - value: _metadata - }); - } - #url_accessor_storage = __runInitializers(this, _url_initializers, null); - get url() { - return this.#url_accessor_storage; - } - set url(value) { - this.#url_accessor_storage = value; - } - static { - this.styles = [structuralStyles, i$9` - * { - box-sizing: border-box; - } - - :host { - display: block; - flex: var(--weight); - min-height: 0; - overflow: auto; - } - - video { - display: block; - width: 100%; - } - `]; - } - #renderVideo() { - if (!this.url) { - return A; - } - if (this.url && typeof this.url === "object") { - if ("literalString" in this.url) { - return b`