tesseract-agent 0.4.11 → 0.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19350,91 +19350,1612 @@ var init_cron_tools = __esm({
19350
19350
  }
19351
19351
  });
19352
19352
 
19353
- // ../../packages/agent-core/dist/design-tokens.js
19354
- function colorVar(name, c) {
19355
- return c.cssVar ?? `--color-${name}`;
19353
+ // ../../packages/shared/dist/ws-protocol.js
19354
+ var MIRRORED_AGENT_EVENTS;
19355
+ var init_ws_protocol = __esm({
19356
+ "../../packages/shared/dist/ws-protocol.js"() {
19357
+ "use strict";
19358
+ MIRRORED_AGENT_EVENTS = /* @__PURE__ */ new Set([
19359
+ "chat:stream",
19360
+ "agent:tool_use",
19361
+ "agent:tool_result",
19362
+ // M4 H10 — co-viewers must see tool OUTPUT, not just the call
19363
+ "agent:file_edit",
19364
+ "chat:complete",
19365
+ "chat:error",
19366
+ "agent:status",
19367
+ "agent:mode_changed",
19368
+ // M4 H11 — co-viewer run-mode badge must flip on plan/edit
19369
+ "agent:session_state",
19370
+ // M4 H11 — co-viewer spinner must clear on idle
19371
+ "agent:todos",
19372
+ // plan sidebar — co-viewers see the live checklist
19373
+ "agent:plan_sections",
19374
+ // plan review — co-viewers see the sectioned plan
19375
+ "agent:narration",
19376
+ // live status strip — co-viewers see "what it's doing now"
19377
+ "agent:preview_ready",
19378
+ // co-viewers (incl. mobile) see the preview the moment it's ready
19379
+ "agent:elicitation_complete",
19380
+ // M5 — co-viewers clear a resolved url-mode card
19381
+ "chat:echoed",
19382
+ "chat:scheduled_fired"
19383
+ // cron — co-viewers see the synthetic "Scheduled" user turn
19384
+ // NOT mirrored: agent:capabilities (host-local model/MCP metadata — mirroring
19385
+ // would stomp a co-viewer's own picker with the driver's host); session:forked
19386
+ // and agent:context_usage are driver-only correlation/host-local replies.
19387
+ ]);
19388
+ }
19389
+ });
19390
+
19391
+ // ../../packages/shared/dist/frame.js
19392
+ var init_frame = __esm({
19393
+ "../../packages/shared/dist/frame.js"() {
19394
+ "use strict";
19395
+ }
19396
+ });
19397
+
19398
+ // ../../packages/shared/dist/plans.js
19399
+ var NO_QUOTAS, NO_FEATURES, PLAN_CATALOG;
19400
+ var init_plans = __esm({
19401
+ "../../packages/shared/dist/plans.js"() {
19402
+ "use strict";
19403
+ NO_QUOTAS = { computeHours: 0, storageGb: 0, egressGb: 0 };
19404
+ NO_FEATURES = {
19405
+ sync: false,
19406
+ mobile: false,
19407
+ cloudWorkspace: false,
19408
+ cloudServer: false,
19409
+ remoteAgents: false,
19410
+ voice: false,
19411
+ team: false,
19412
+ parallelAgents: false,
19413
+ advancedBrowser: false,
19414
+ hosting: false,
19415
+ plugins: false,
19416
+ scheduling: false,
19417
+ api: false,
19418
+ sso: false,
19419
+ seats: 1,
19420
+ maxMachines: 1
19421
+ };
19422
+ PLAN_CATALOG = [
19423
+ {
19424
+ id: "free",
19425
+ name: "Free",
19426
+ monthlyUsd: 0,
19427
+ tagline: "Your machine, your phone, your voice.",
19428
+ features: [
19429
+ "Unlimited agent usage",
19430
+ "Full IDE: editor, files, agent, browser tool",
19431
+ "Voice mode",
19432
+ "Mobile app \u2014 reach your computer from your phone",
19433
+ "Cloud workspace \u2014 your machine and recent projects in one view",
19434
+ "One machine",
19435
+ "Deploy to your own machine or server",
19436
+ "Community support"
19437
+ ],
19438
+ featurePolicy: { ...NO_FEATURES, voice: true, mobile: true, cloudWorkspace: true },
19439
+ quotas: { ...NO_QUOTAS }
19440
+ },
19441
+ {
19442
+ id: "standard",
19443
+ name: "Pro",
19444
+ monthlyUsd: 20,
19445
+ tagline: "Your workspace, everywhere.",
19446
+ features: [
19447
+ "Everything in Free",
19448
+ "Unlimited machines \u2014 run agents on all of them",
19449
+ "Tesseract cloud server \u2014 a managed always-on agent in the cloud",
19450
+ "Deploy to the cloud \u2014 your app on a *.tesseract.dev URL",
19451
+ "Includes ~1 always-on service + 20 GB storage + 100 GB bandwidth (overage metered)",
19452
+ "Sync settings across your devices",
19453
+ "Email support"
19454
+ ],
19455
+ featurePolicy: {
19456
+ ...NO_FEATURES,
19457
+ sync: true,
19458
+ mobile: true,
19459
+ cloudWorkspace: true,
19460
+ cloudServer: true,
19461
+ remoteAgents: true,
19462
+ voice: true,
19463
+ hosting: true,
19464
+ plugins: true,
19465
+ scheduling: true,
19466
+ maxMachines: 0
19467
+ },
19468
+ // ~1 small always-on service (~720 compute-hours/mo, rounded) + 20 GB storage + 100 GB egress.
19469
+ quotas: { computeHours: 750, storageGb: 20, egressGb: 100 }
19470
+ },
19471
+ {
19472
+ id: "pro",
19473
+ name: "Team",
19474
+ monthlyUsd: 40,
19475
+ perSeat: true,
19476
+ tagline: "For teams shipping together.",
19477
+ features: [
19478
+ "Everything in Pro, per seat",
19479
+ "Team seats + shared workspaces",
19480
+ "Parallel agents",
19481
+ "Advanced browser automation",
19482
+ "API access",
19483
+ "SSO, audit logs, centralized billing",
19484
+ "Pooled cloud hosting \u2014 bigger shared quota",
19485
+ "Priority support"
19486
+ ],
19487
+ featurePolicy: {
19488
+ sync: true,
19489
+ mobile: true,
19490
+ cloudWorkspace: true,
19491
+ cloudServer: true,
19492
+ remoteAgents: true,
19493
+ voice: true,
19494
+ team: true,
19495
+ parallelAgents: true,
19496
+ advancedBrowser: true,
19497
+ hosting: true,
19498
+ plugins: true,
19499
+ scheduling: true,
19500
+ api: true,
19501
+ sso: true,
19502
+ seats: 2,
19503
+ maxMachines: 0
19504
+ },
19505
+ // Pooled across the team — ~4× Pro's starter quota.
19506
+ quotas: { computeHours: 3e3, storageGb: 100, egressGb: 500 }
19507
+ }
19508
+ ];
19509
+ }
19510
+ });
19511
+
19512
+ // ../../packages/shared/dist/slug.js
19513
+ var init_slug = __esm({
19514
+ "../../packages/shared/dist/slug.js"() {
19515
+ "use strict";
19516
+ }
19517
+ });
19518
+
19519
+ // ../../packages/shared/dist/hosting.js
19520
+ var init_hosting = __esm({
19521
+ "../../packages/shared/dist/hosting.js"() {
19522
+ "use strict";
19523
+ }
19524
+ });
19525
+
19526
+ // ../../packages/shared/dist/cloud-agent.js
19527
+ var init_cloud_agent = __esm({
19528
+ "../../packages/shared/dist/cloud-agent.js"() {
19529
+ "use strict";
19530
+ }
19531
+ });
19532
+
19533
+ // ../../packages/shared/dist/settings.js
19534
+ var MODEL_OPTIONS;
19535
+ var init_settings = __esm({
19536
+ "../../packages/shared/dist/settings.js"() {
19537
+ "use strict";
19538
+ MODEL_OPTIONS = [
19539
+ { id: "claude-opus-4-8", label: "Claude Opus 4.8" },
19540
+ { id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
19541
+ { id: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5" }
19542
+ ];
19543
+ }
19544
+ });
19545
+
19546
+ // ../../packages/shared/dist/engines.js
19547
+ function engineById(id) {
19548
+ return ENGINE_CATALOG[id];
19549
+ }
19550
+ var ENGINE_CATALOG, ENGINE_IDS;
19551
+ var init_engines = __esm({
19552
+ "../../packages/shared/dist/engines.js"() {
19553
+ "use strict";
19554
+ init_settings();
19555
+ ENGINE_CATALOG = {
19556
+ "claude-code": {
19557
+ id: "claude-code",
19558
+ label: "Claude Code",
19559
+ description: "Anthropic's Claude Code \u2014 the default engine, deepest tool + browser integration.",
19560
+ cliBinary: "claude",
19561
+ // Claude's token is injected via CLAUDE_CODE_OAUTH_TOKEN, so oauth needs no auth file.
19562
+ supportedModes: ["oauth", "apiKey", "localCli"],
19563
+ apiKeyEnv: "ANTHROPIC_API_KEY",
19564
+ models: MODEL_OPTIONS,
19565
+ capabilities: { permissionGating: true, browserControl: true, liveRunMode: true, resume: true, fork: true, contextUsage: true, scheduling: true },
19566
+ homepageUrl: "https://docs.claude.com/en/docs/claude-code",
19567
+ installCommand: "npm install -g @anthropic-ai/claude-code",
19568
+ installHint: "Bundled with the app; install the standalone CLI for local-instance mode."
19569
+ },
19570
+ "openai-codex": {
19571
+ id: "openai-codex",
19572
+ label: "OpenAI Codex",
19573
+ description: "OpenAI's Codex CLI. Sign in with ChatGPT or use an API key.",
19574
+ cliBinary: "codex",
19575
+ supportedModes: ["oauth", "apiKey", "localCli"],
19576
+ apiKeyEnv: "OPENAI_API_KEY",
19577
+ authFileRel: "auth.json",
19578
+ // under $CODEX_HOME
19579
+ models: [
19580
+ { id: "gpt-5.5-codex", label: "GPT-5.5 Codex" },
19581
+ { id: "gpt-5.5", label: "GPT-5.5" }
19582
+ ],
19583
+ capabilities: { permissionGating: false, browserControl: false, liveRunMode: false, resume: true },
19584
+ homepageUrl: "https://developers.openai.com/codex/cli",
19585
+ installCommand: "npm install -g @openai/codex",
19586
+ installHint: "npm i -g @openai/codex (or brew install codex)"
19587
+ },
19588
+ opencode: {
19589
+ id: "opencode",
19590
+ label: "OpenCode",
19591
+ description: "Open-source agent over 75+ providers. Log in per provider.",
19592
+ cliBinary: "opencode",
19593
+ supportedModes: ["oauth", "apiKey", "localCli"],
19594
+ // OpenCode reads provider keys from env / its own auth.json; no single apiKeyEnv.
19595
+ authFileRel: "auth.json",
19596
+ // under ~/.local/share/opencode
19597
+ models: [],
19598
+ // provider+model is configured inside OpenCode; "" ⇒ its default
19599
+ capabilities: { permissionGating: false, browserControl: false, liveRunMode: false, resume: true },
19600
+ homepageUrl: "https://opencode.ai",
19601
+ installCommand: "npm install -g opencode-ai",
19602
+ installHint: "npm i -g opencode-ai (see opencode.ai/docs)"
19603
+ },
19604
+ "gemini-cli": {
19605
+ id: "gemini-cli",
19606
+ label: "Gemini CLI",
19607
+ description: "Google's Gemini CLI. Sign in with Google or use a Gemini API key.",
19608
+ cliBinary: "gemini",
19609
+ supportedModes: ["oauth", "apiKey", "localCli"],
19610
+ apiKeyEnv: "GEMINI_API_KEY",
19611
+ models: [
19612
+ { id: "gemini-3.1-pro", label: "Gemini 3.1 Pro" },
19613
+ { id: "gemini-2.5-flash", label: "Gemini 2.5 Flash" }
19614
+ ],
19615
+ capabilities: { permissionGating: false, browserControl: false, liveRunMode: false, resume: false },
19616
+ homepageUrl: "https://github.com/google-gemini/gemini-cli",
19617
+ installCommand: "npm install -g @google/gemini-cli",
19618
+ installHint: "npm i -g @google/gemini-cli"
19619
+ },
19620
+ openclaw: {
19621
+ id: "openclaw",
19622
+ label: "OpenClaw",
19623
+ description: "OpenClaw runtime \u2014 runs your installed channels, model providers, and plugins natively.",
19624
+ cliBinary: "openclaw",
19625
+ // OpenClaw manages its own provider auth (`openclaw onboard` / openclaw.json), so the
19626
+ // only mode is "use the installed, already-onboarded CLI" — like OpenCode.
19627
+ supportedModes: ["localCli"],
19628
+ models: [],
19629
+ // provider+model is configured inside OpenClaw; '' ⇒ its default
19630
+ capabilities: { permissionGating: false, browserControl: false, liveRunMode: false, resume: false },
19631
+ homepageUrl: "https://docs.openclaw.ai",
19632
+ installCommand: "npm install -g openclaw",
19633
+ installHint: "npm i -g openclaw, then run `openclaw onboard` (see docs.openclaw.ai)"
19634
+ }
19635
+ };
19636
+ ENGINE_IDS = Object.keys(ENGINE_CATALOG);
19637
+ }
19638
+ });
19639
+
19640
+ // ../../packages/shared/dist/providers.js
19641
+ function providerById(id) {
19642
+ return PROVIDER_CATALOG[id];
19643
+ }
19644
+ var PROVIDER_CATALOG, PROVIDER_IDS, NATIVE_PROVIDER_IDS;
19645
+ var init_providers = __esm({
19646
+ "../../packages/shared/dist/providers.js"() {
19647
+ "use strict";
19648
+ PROVIDER_CATALOG = {
19649
+ anthropic: {
19650
+ id: "anthropic",
19651
+ label: "Anthropic",
19652
+ description: "Claude models, direct from Anthropic. The native backend for Claude Code.",
19653
+ baseUrl: "https://api.anthropic.com",
19654
+ api: "anthropic-messages",
19655
+ claudeNative: true,
19656
+ authEnvVars: ["ANTHROPIC_API_KEY"],
19657
+ authModes: ["oauth", "apiKey"],
19658
+ models: [
19659
+ { id: "claude-opus-4-8", label: "Claude Opus 4.8", role: "main" },
19660
+ { id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6", role: "main" },
19661
+ { id: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5", role: "fast" }
19662
+ ],
19663
+ homepageUrl: "https://docs.claude.com/en/docs/about-claude/models"
19664
+ },
19665
+ openai: {
19666
+ id: "openai",
19667
+ label: "OpenAI",
19668
+ description: "OpenAI models. The native backend for the Codex engine.",
19669
+ baseUrl: "https://api.openai.com/v1",
19670
+ api: "openai-completions",
19671
+ claudeNative: false,
19672
+ authEnvVars: ["OPENAI_API_KEY"],
19673
+ authModes: ["oauth", "apiKey"],
19674
+ models: [
19675
+ { id: "gpt-5.5-codex", label: "GPT-5.5 Codex", role: "main" },
19676
+ { id: "gpt-5.5", label: "GPT-5.5", role: "main" }
19677
+ ],
19678
+ homepageUrl: "https://platform.openai.com/docs/models"
19679
+ },
19680
+ google: {
19681
+ id: "google",
19682
+ label: "Google Gemini",
19683
+ description: "Gemini models. The native backend for the Gemini engine.",
19684
+ baseUrl: "https://generativelanguage.googleapis.com",
19685
+ api: "gemini",
19686
+ claudeNative: false,
19687
+ authEnvVars: ["GEMINI_API_KEY"],
19688
+ authModes: ["oauth", "apiKey"],
19689
+ models: [
19690
+ { id: "gemini-3.1-pro", label: "Gemini 3.1 Pro", role: "main" },
19691
+ { id: "gemini-2.5-flash", label: "Gemini 2.5 Flash", role: "fast" }
19692
+ ],
19693
+ homepageUrl: "https://ai.google.dev/gemini-api/docs/models"
19694
+ },
19695
+ openrouter: {
19696
+ id: "openrouter",
19697
+ label: "OpenRouter",
19698
+ description: "One key, hundreds of models. Exposes an Anthropic-compatible route \u2014 no proxy needed for Claude Code.",
19699
+ // OpenAI-style base; the Anthropic-compatible base is `…/api` (no `/v1`).
19700
+ baseUrl: "https://openrouter.ai/api/v1",
19701
+ anthropicBaseUrl: "https://openrouter.ai/api",
19702
+ api: "openai-completions",
19703
+ claudeNative: true,
19704
+ authEnvVars: ["OPENROUTER_API_KEY"],
19705
+ headers: {
19706
+ "HTTP-Referer": "https://app.tesseract.dev",
19707
+ "X-Title": "Tesseract"
19708
+ },
19709
+ authModes: ["apiKey"],
19710
+ // Any OpenRouter slug is valid; these are stable starters (free entry in UI).
19711
+ models: [
19712
+ { id: "deepseek/deepseek-chat", label: "DeepSeek Chat", role: "fast" },
19713
+ { id: "deepseek/deepseek-r1", label: "DeepSeek R1", role: "main" },
19714
+ { id: "google/gemini-2.5-flash", label: "Gemini 2.5 Flash", role: "fast" },
19715
+ { id: "google/gemini-2.5-pro", label: "Gemini 2.5 Pro", role: "main" }
19716
+ ],
19717
+ homepageUrl: "https://openrouter.ai/docs"
19718
+ },
19719
+ ollama: {
19720
+ id: "ollama",
19721
+ label: "Ollama (local)",
19722
+ description: "Run open models locally. No API key. Models are discovered from your running Ollama.",
19723
+ baseUrl: "http://127.0.0.1:11434",
19724
+ api: "ollama",
19725
+ claudeNative: false,
19726
+ authEnvVars: [],
19727
+ authModes: ["apiKey"],
19728
+ // optional bearer for remote Ollama; usually none
19729
+ models: [],
19730
+ dynamicModels: true,
19731
+ homepageUrl: "https://ollama.com",
19732
+ installCommand: "curl -fsSL https://ollama.com/install.sh | sh"
19733
+ },
19734
+ deepseek: {
19735
+ id: "deepseek",
19736
+ label: "DeepSeek",
19737
+ description: "DeepSeek Chat + Reasoner. Cheap and capable. Reached via the proxy for Claude Code.",
19738
+ baseUrl: "https://api.deepseek.com",
19739
+ api: "openai-completions",
19740
+ claudeNative: false,
19741
+ authEnvVars: ["DEEPSEEK_API_KEY"],
19742
+ authModes: ["apiKey"],
19743
+ models: [
19744
+ { id: "deepseek-chat", label: "DeepSeek Chat", role: "fast" },
19745
+ { id: "deepseek-reasoner", label: "DeepSeek Reasoner", role: "main" }
19746
+ ],
19747
+ homepageUrl: "https://api-docs.deepseek.com"
19748
+ },
19749
+ moonshot: {
19750
+ id: "moonshot",
19751
+ label: "Kimi (Moonshot)",
19752
+ description: "Kimi K2 models. Use the coding endpoint (Anthropic-compatible, no proxy) or the OpenAI endpoint.",
19753
+ // Default to the OpenAI-style endpoint; the per-credential `baseUrl` can switch
19754
+ // to the Anthropic-compatible coding endpoint below.
19755
+ baseUrl: "https://api.moonshot.ai/v1",
19756
+ anthropicBaseUrl: "https://api.kimi.com/coding/",
19757
+ api: "openai-completions",
19758
+ claudeNative: true,
19759
+ authEnvVars: ["MOONSHOT_API_KEY", "KIMI_API_KEY"],
19760
+ authModes: ["apiKey"],
19761
+ models: [
19762
+ { id: "kimi-code", label: "Kimi Code (coding endpoint)", role: "main" },
19763
+ { id: "kimi-k2.5", label: "Kimi K2.5", role: "main" },
19764
+ { id: "kimi-k2-thinking", label: "Kimi K2 Thinking", role: "main" }
19765
+ ],
19766
+ homepageUrl: "https://platform.moonshot.ai/docs"
19767
+ },
19768
+ "custom-openai": {
19769
+ id: "custom-openai",
19770
+ label: "Custom (OpenAI-compatible)",
19771
+ description: "Any OpenAI-compatible endpoint (LM Studio, llama.cpp, vLLM, a private gateway). Set the base URL per key.",
19772
+ baseUrl: "",
19773
+ api: "openai-completions",
19774
+ claudeNative: false,
19775
+ authEnvVars: ["OPENAI_API_KEY"],
19776
+ authModes: ["apiKey"],
19777
+ models: [],
19778
+ homepageUrl: "https://platform.openai.com/docs/api-reference"
19779
+ },
19780
+ litellm: {
19781
+ id: "litellm",
19782
+ label: "LiteLLM Proxy",
19783
+ description: "Your LiteLLM proxy fronting 100+ providers. Point it at the anthropic route for direct Claude Code use.",
19784
+ baseUrl: "",
19785
+ anthropicBaseUrl: "",
19786
+ api: "openai-completions",
19787
+ // Configurable: LiteLLM can expose an Anthropic-shaped route. Treated as
19788
+ // claudeNative so users can point Claude Code straight at it.
19789
+ claudeNative: true,
19790
+ authEnvVars: ["LITELLM_API_KEY"],
19791
+ authModes: ["apiKey"],
19792
+ models: [],
19793
+ homepageUrl: "https://docs.litellm.ai/docs/simple_proxy"
19794
+ }
19795
+ };
19796
+ PROVIDER_IDS = Object.keys(PROVIDER_CATALOG);
19797
+ NATIVE_PROVIDER_IDS = ["anthropic", "openai", "google"];
19798
+ }
19799
+ });
19800
+
19801
+ // ../../packages/shared/dist/runtimes.js
19802
+ var RUNTIME_CATALOG, RUNTIME_IDS;
19803
+ var init_runtimes = __esm({
19804
+ "../../packages/shared/dist/runtimes.js"() {
19805
+ "use strict";
19806
+ init_engines();
19807
+ RUNTIME_CATALOG = [
19808
+ ...ENGINE_IDS.map((id) => ({
19809
+ id,
19810
+ label: ENGINE_CATALOG[id].label,
19811
+ cliBinary: ENGINE_CATALOG[id].cliBinary,
19812
+ installCommand: ENGINE_CATALOG[id].installCommand,
19813
+ kind: "engine"
19814
+ })),
19815
+ { id: "ollama", label: "Ollama", cliBinary: "ollama", installCommand: "curl -fsSL https://ollama.com/install.sh | sh", kind: "tool" },
19816
+ { id: "ccr", label: "Claude Code Router", cliBinary: "ccr", installCommand: "npm install -g @musistudio/claude-code-router", kind: "tool" }
19817
+ ];
19818
+ RUNTIME_IDS = RUNTIME_CATALOG.map((r) => r.id);
19819
+ }
19820
+ });
19821
+
19822
+ // ../../packages/shared/dist/runner-configs.js
19823
+ var init_runner_configs = __esm({
19824
+ "../../packages/shared/dist/runner-configs.js"() {
19825
+ "use strict";
19826
+ init_providers();
19827
+ }
19828
+ });
19829
+
19830
+ // ../../packages/shared/dist/rotation.js
19831
+ function refreshCredentials(creds, now) {
19832
+ return creds.map((c) => {
19833
+ if (c.status === "cooldown" && (c.cooldownUntil == null || c.cooldownUntil <= now)) {
19834
+ return { ...c, status: "active", cooldownUntil: void 0 };
19835
+ }
19836
+ if (c.status === "active" && c.expiresAt != null && c.expiresAt <= now) {
19837
+ return { ...c, status: "expired" };
19838
+ }
19839
+ return c;
19840
+ });
19841
+ }
19842
+ function selectRotatable(items, now, isUsable = () => true) {
19843
+ const usable = refreshCredentials(items, now).filter((c) => c.status === "active" && (c.expiresAt == null || c.expiresAt > now) && isUsable(c));
19844
+ if (usable.length === 0)
19845
+ return void 0;
19846
+ return usable.sort((a, b) => a.priority - b.priority || (a.lastUsedAt ?? 0) - (b.lastUsedAt ?? 0))[0];
19847
+ }
19848
+ function classifyError(raw) {
19849
+ const s = raw.toLowerCase();
19850
+ if (/\b429\b|rate[ _-]?limit|too many requests/.test(s))
19851
+ return "rate_limit";
19852
+ if (/quota|insufficient[_ ]?quota|credit|billing|payment required|\b402\b|usage limit|exceeded your/.test(s))
19853
+ return "quota_exceeded";
19854
+ if (/expired|token (?:has )?expired|refresh|re-?authenticate|session expired/.test(s))
19855
+ return "auth_expired";
19856
+ if (/\b401\b|\b403\b|invalid (?:api )?key|unauthorized|invalid token|authentication/.test(s))
19857
+ return "invalid_key";
19858
+ if (/\beai_again\b|\benotfound\b|getaddrinfo|network is unreachable|\benetunreach\b|\benetdown\b|offline|no address associated|dns/.test(s))
19859
+ return "network_down";
19860
+ if (/\beconnreset\b|\beconnrefused\b|\betimedout\b|\bepipe\b|socket hang ?up|connection (?:closed|reset|error|aborted)|\b50[0234]\b|\b529\b|overloaded|service unavailable|bad gateway|gateway time-?out|temporarily unavailable/.test(s))
19861
+ return "transient";
19862
+ return "unknown";
19863
+ }
19864
+ function recordFailure(creds, id, errorCode, now, opts) {
19865
+ if (errorCode === "unknown" || errorCode === "transient" || errorCode === "network_down") {
19866
+ return { next: creds, advanced: false };
19867
+ }
19868
+ let advanced = false;
19869
+ const next = creds.map((c) => {
19870
+ if (c.id !== id)
19871
+ return c;
19872
+ advanced = true;
19873
+ const consecutiveFailures = (c.consecutiveFailures ?? 0) + 1;
19874
+ if (errorCode === "auth_expired") {
19875
+ return { ...c, status: "expired", lastErrorCode: errorCode, consecutiveFailures };
19876
+ }
19877
+ if (errorCode === "invalid_key") {
19878
+ return { ...c, status: "revoked", lastErrorCode: errorCode, consecutiveFailures };
19879
+ }
19880
+ const backoff = Math.min(COOLDOWN_BASE_MS * 2 ** (consecutiveFailures - 1), COOLDOWN_MAX_MS);
19881
+ const cooldownUntil = opts?.cooldownUntil ?? now + backoff;
19882
+ return { ...c, status: "cooldown", cooldownUntil, lastErrorCode: errorCode, consecutiveFailures };
19883
+ });
19884
+ return { next, advanced };
19885
+ }
19886
+ function recordSuccess(creds, id, now) {
19887
+ return creds.map((c) => c.id === id ? { ...c, status: "active", cooldownUntil: void 0, consecutiveFailures: 0, lastUsedAt: now, lastErrorCode: void 0 } : c);
19888
+ }
19889
+ var COOLDOWN_BASE_MS, COOLDOWN_MAX_MS;
19890
+ var init_rotation = __esm({
19891
+ "../../packages/shared/dist/rotation.js"() {
19892
+ "use strict";
19893
+ COOLDOWN_BASE_MS = 6e4;
19894
+ COOLDOWN_MAX_MS = 36e5;
19895
+ }
19896
+ });
19897
+
19898
+ // ../../packages/shared/dist/design-tokens.js
19899
+ function isObj(v) {
19900
+ return typeof v === "object" && v !== null && !Array.isArray(v);
19356
19901
  }
19357
- function tokensToCss(tokens) {
19358
- const lines = [
19902
+ function isToken(node) {
19903
+ return isObj(node) && "$value" in node;
19904
+ }
19905
+ function tessExt(token) {
19906
+ const ext = token.$extensions?.["com.tesseract"];
19907
+ return isObj(ext) ? ext : void 0;
19908
+ }
19909
+ function walkTokens(tree) {
19910
+ const out = [];
19911
+ const rec = (node, path5) => {
19912
+ if (!isObj(node))
19913
+ return;
19914
+ if (isToken(node)) {
19915
+ out.push({ path: path5, token: node });
19916
+ return;
19917
+ }
19918
+ for (const key2 of Object.keys(node)) {
19919
+ if (key2.startsWith("$"))
19920
+ continue;
19921
+ rec(node[key2], [...path5, key2]);
19922
+ }
19923
+ };
19924
+ rec(tree, []);
19925
+ return out;
19926
+ }
19927
+ function stringifyValue(v) {
19928
+ if (v == null)
19929
+ return "";
19930
+ if (Array.isArray(v))
19931
+ return v.map((x) => isObj(x) ? JSON.stringify(x) : String(x)).join(", ");
19932
+ if (isObj(v))
19933
+ return JSON.stringify(v);
19934
+ return String(v);
19935
+ }
19936
+ function flattenForDisplay(tree) {
19937
+ return walkTokens(tree).map(({ path: path5, token }) => {
19938
+ const dark = tessExt(token)?.modes?.dark;
19939
+ return {
19940
+ path: path5,
19941
+ dotPath: path5.join("."),
19942
+ group: path5.slice(0, -1).join(" \xB7 "),
19943
+ label: path5[path5.length - 1] ?? "",
19944
+ type: token.$type,
19945
+ value: stringifyValue(token.$value),
19946
+ isColor: token.$type === "color",
19947
+ darkValue: dark === void 0 ? void 0 : stringifyValue(dark)
19948
+ };
19949
+ });
19950
+ }
19951
+ function kebab(s) {
19952
+ return s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
19953
+ }
19954
+ function tokenCssVarName(path5, token) {
19955
+ const override = token ? tessExt(token)?.cssVar : void 0;
19956
+ if (override)
19957
+ return override.startsWith("--") ? override : `--${override}`;
19958
+ for (const { match, prefix } of VAR_ALIASES) {
19959
+ if (match.length <= path5.length && match.every((seg, i) => path5[i] === seg)) {
19960
+ const rest = path5.slice(match.length).map(kebab).filter(Boolean);
19961
+ return ["--" + prefix, ...rest].join("-");
19962
+ }
19963
+ }
19964
+ return ["--token", ...path5.map(kebab).filter(Boolean)].join("-");
19965
+ }
19966
+ function categoryRank(top) {
19967
+ const i = CATEGORY_ORDER.indexOf(top ?? "");
19968
+ return i === -1 ? CATEGORY_ORDER.length : i;
19969
+ }
19970
+ function shadowToCss(v) {
19971
+ const s = (k, d = "0") => v[k] == null ? d : String(v[k]);
19972
+ const inset = v.inset ? "inset " : "";
19973
+ return `${inset}${s("offsetX")} ${s("offsetY")} ${s("blur")} ${s("spread")} ${s("color", "#000")}`.replace(/\s+/g, " ").trim();
19974
+ }
19975
+ function cssValue(type, v) {
19976
+ if (Array.isArray(v)) {
19977
+ if (type === "fontFamily") {
19978
+ return v.map((f) => typeof f === "string" && /\s/.test(f) && !/^["']/.test(f) ? `"${f}"` : String(f)).join(", ");
19979
+ }
19980
+ return v.map((x) => isObj(x) ? shadowToCss(x) : String(x)).join(", ");
19981
+ }
19982
+ if (isObj(v))
19983
+ return shadowToCss(v);
19984
+ return String(v);
19985
+ }
19986
+ function tokensToCss(input) {
19987
+ const tokens = normalizeTokens(input);
19988
+ const rows = walkTokens(tokens);
19989
+ const ordered = rows.map((r, i) => ({ r, i })).sort((a, b) => categoryRank(a.r.path[0]) - categoryRank(b.r.path[0]) || a.i - b.i).map((x) => x.r);
19990
+ const root = [];
19991
+ const dark = [];
19992
+ for (const { path: path5, token } of ordered) {
19993
+ const name = tokenCssVarName(path5, token);
19994
+ root.push(` ${name}: ${cssValue(token.$type, token.$value)};`);
19995
+ const d = tessExt(token)?.modes?.dark;
19996
+ if (d !== void 0)
19997
+ dark.push(` ${name}: ${cssValue(token.$type, d)};`);
19998
+ }
19999
+ const out = [
19359
20000
  "/* GENERATED from design-system/tokens.json \u2014 do not edit by hand. */",
19360
- ":root {"
20001
+ ":root {",
20002
+ ...root,
20003
+ "}"
19361
20004
  ];
19362
- const push = (k, v) => lines.push(` ${k}: ${v};`);
19363
- for (const [name, c] of Object.entries(tokens.colors ?? {}))
19364
- push(colorVar(name, c), c.value);
19365
- for (const [role, fam] of Object.entries(tokens.typography?.fontFamilies ?? {}))
19366
- push(`--font-${role}`, fam);
19367
- for (const [step, s] of Object.entries(tokens.typography?.scale ?? {}))
19368
- push(`--text-${step}`, s.size);
19369
- for (const [name, w] of Object.entries(tokens.typography?.weights ?? {}))
19370
- push(`--weight-${name}`, String(w));
19371
- for (const [step, v] of Object.entries(tokens.spacing ?? {}))
19372
- push(`--space-${step}`, v);
19373
- for (const [name, v] of Object.entries(tokens.radius ?? {}))
19374
- push(`--radius-${name}`, v);
19375
- for (const [name, v] of Object.entries(tokens.shadow ?? {}))
19376
- push(`--shadow-${name}`, v);
19377
- lines.push("}", "");
19378
- return lines.join("\n");
20005
+ if (dark.length)
20006
+ out.push("", ".dark {", ...dark, "}");
20007
+ out.push("");
20008
+ return out.join("\n");
19379
20009
  }
19380
- function getTokenPath(tokens, dotPath) {
20010
+ function getTokenSegments(tokens, segments) {
19381
20011
  let cur = tokens;
19382
- for (const key2 of dotPath.split(".")) {
19383
- if (cur == null || typeof cur !== "object")
20012
+ for (const key2 of segments) {
20013
+ if (!isObj(cur))
19384
20014
  return void 0;
19385
20015
  cur = cur[key2];
19386
20016
  }
19387
20017
  return cur;
19388
20018
  }
19389
- function setTokenPath(tokens, dotPath, value) {
19390
- const keys = dotPath.split(".").filter(Boolean);
19391
- if (keys.length === 0)
20019
+ function getTokenPath(tokens, dotPath) {
20020
+ return getTokenSegments(tokens, dotPath.split(".").filter(Boolean));
20021
+ }
20022
+ function setTokenSegments(tokens, segments, value) {
20023
+ if (segments.length === 0)
19392
20024
  throw new Error("empty token path");
19393
20025
  const root = { ...tokens };
19394
20026
  let cur = root;
19395
- for (let i = 0; i < keys.length - 1; i++) {
19396
- const k = keys[i];
20027
+ for (let i = 0; i < segments.length - 1; i++) {
20028
+ const k = segments[i];
19397
20029
  const next = cur[k];
19398
- cur[k] = next && typeof next === "object" ? { ...next } : {};
20030
+ cur[k] = isObj(next) ? { ...next } : {};
19399
20031
  cur = cur[k];
19400
20032
  }
19401
- cur[keys[keys.length - 1]] = value;
20033
+ cur[segments[segments.length - 1]] = value;
19402
20034
  return root;
19403
20035
  }
19404
- var DESIGN_DIR, TOKENS_FILE, TOKENS_CSS_FILE, DESIGN_CLAUDE_MD, ColorToken, TypeStep, Component, DesignTokensSchema;
20036
+ function setTokenPath(tokens, dotPath, value) {
20037
+ return setTokenSegments(tokens, dotPath.split(".").filter(Boolean), value);
20038
+ }
20039
+ function makeToken(value, type) {
20040
+ const tok = { $value: value };
20041
+ if (type)
20042
+ tok.$type = type;
20043
+ return tok;
20044
+ }
20045
+ function splitFamily(s) {
20046
+ if (Array.isArray(s))
20047
+ return s;
20048
+ if (typeof s === "string")
20049
+ return s.split(",").map((x) => x.trim()).filter(Boolean);
20050
+ return String(s ?? "");
20051
+ }
20052
+ function isLightDarkPair(n) {
20053
+ if ("$value" in n)
20054
+ return false;
20055
+ const scalar = (v) => typeof v === "string" || typeof v === "number";
20056
+ const keys = Object.keys(n).filter((k) => !k.startsWith("$"));
20057
+ return keys.length > 0 && keys.includes("light") && keys.every((k) => k === "light" || k === "dark") && scalar(n.light) && (n.dark === void 0 || scalar(n.dark));
20058
+ }
20059
+ function isLegacyColorLeaf(v) {
20060
+ return isObj(v) && typeof v.value === "string" && !("$value" in v);
20061
+ }
20062
+ function canonicalizeNode(node, inheritedType) {
20063
+ if (typeof node === "string" || typeof node === "number" || Array.isArray(node)) {
20064
+ return makeToken(node, inheritedType);
20065
+ }
20066
+ if (!isObj(node))
20067
+ return void 0;
20068
+ if (isLightDarkPair(node)) {
20069
+ const modes = {};
20070
+ for (const k of Object.keys(node))
20071
+ if (k !== "light" && !k.startsWith("$"))
20072
+ modes[k] = node[k];
20073
+ const tok = makeToken(node.light, node.$type ?? inheritedType);
20074
+ if (Object.keys(modes).length)
20075
+ tok.$extensions = { "com.tesseract": { modes } };
20076
+ return tok;
20077
+ }
20078
+ if ("$value" in node) {
20079
+ const tok = { $value: node.$value };
20080
+ const t = node.$type ?? inheritedType;
20081
+ if (t)
20082
+ tok.$type = t;
20083
+ if (typeof node.$description === "string")
20084
+ tok.$description = node.$description;
20085
+ if (isObj(node.$extensions))
20086
+ tok.$extensions = node.$extensions;
20087
+ return tok;
20088
+ }
20089
+ if (inheritedType === "color" && isLegacyColorLeaf(node)) {
20090
+ const tok = makeToken(node.value, "color");
20091
+ if (node.role)
20092
+ tok.$description = node.role;
20093
+ if (node.cssVar)
20094
+ tok.$extensions = { "com.tesseract": { cssVar: node.cssVar } };
20095
+ return tok;
20096
+ }
20097
+ return canonicalizeGroup(node, inheritedType);
20098
+ }
20099
+ function canonicalizeGroup(node, inheritedType) {
20100
+ const groupType = node.$type ?? inheritedType;
20101
+ const g = {};
20102
+ if (typeof node.$type === "string")
20103
+ g.$type = node.$type;
20104
+ if (typeof node.$description === "string")
20105
+ g.$description = node.$description;
20106
+ if (isObj(node.$extensions))
20107
+ g.$extensions = node.$extensions;
20108
+ for (const key2 of Object.keys(node)) {
20109
+ if (key2.startsWith("$"))
20110
+ continue;
20111
+ const child = canonicalizeNode(node[key2], groupType);
20112
+ if (child !== void 0)
20113
+ g[key2] = child;
20114
+ }
20115
+ return g;
20116
+ }
20117
+ function normalizeColorGroup(src) {
20118
+ const g = { $type: "color" };
20119
+ if (typeof src.$description === "string")
20120
+ g.$description = src.$description;
20121
+ for (const key2 of Object.keys(src)) {
20122
+ if (key2.startsWith("$"))
20123
+ continue;
20124
+ const v = src[key2];
20125
+ if (isLegacyColorLeaf(v)) {
20126
+ const tok = makeToken(v.value, "color");
20127
+ if (v.role)
20128
+ tok.$description = v.role;
20129
+ if (v.cssVar)
20130
+ tok.$extensions = { "com.tesseract": { cssVar: v.cssVar } };
20131
+ g[key2] = tok;
20132
+ } else {
20133
+ const child = canonicalizeNode(v, "color");
20134
+ if (child !== void 0)
20135
+ g[key2] = child;
20136
+ }
20137
+ }
20138
+ return g;
20139
+ }
20140
+ function hasTokens(g) {
20141
+ return Object.keys(g).some((k) => !k.startsWith("$"));
20142
+ }
20143
+ function normalizeTypography(src) {
20144
+ const g = {};
20145
+ if (typeof src.$description === "string")
20146
+ g.$description = src.$description;
20147
+ if (isObj(src.fontFamilies)) {
20148
+ const ff = { $type: "fontFamily" };
20149
+ for (const [k, val] of Object.entries(src.fontFamilies))
20150
+ ff[k] = makeToken(splitFamily(val), "fontFamily");
20151
+ g.fontFamily = ff;
20152
+ }
20153
+ if (isObj(src.scale)) {
20154
+ const sizes = { $type: "dimension" };
20155
+ const leading = { $type: "lineHeight" };
20156
+ const weights = { $type: "fontWeight" };
20157
+ for (const [k, step] of Object.entries(src.scale)) {
20158
+ if (!isObj(step))
20159
+ continue;
20160
+ if (step.size != null)
20161
+ sizes[k] = makeToken(step.size, "dimension");
20162
+ if (step.lineHeight != null)
20163
+ leading[k] = makeToken(step.lineHeight, "lineHeight");
20164
+ if (step.weight != null)
20165
+ weights[k] = makeToken(step.weight, "fontWeight");
20166
+ }
20167
+ g.fontSize = sizes;
20168
+ if (hasTokens(leading))
20169
+ g.lineHeight = leading;
20170
+ if (hasTokens(weights))
20171
+ g.fontWeight = weights;
20172
+ }
20173
+ if (isObj(src.weights)) {
20174
+ const w = isObj(g.fontWeight) ? g.fontWeight : { $type: "fontWeight" };
20175
+ for (const [k, val] of Object.entries(src.weights))
20176
+ w[k] = makeToken(val, "fontWeight");
20177
+ g.fontWeight = w;
20178
+ }
20179
+ const TYPE_HINT = {
20180
+ fontFamily: "fontFamily",
20181
+ fontSize: "dimension",
20182
+ fontWeight: "fontWeight",
20183
+ lineHeight: "lineHeight",
20184
+ letterSpacing: "letterSpacing"
20185
+ };
20186
+ for (const key2 of Object.keys(src)) {
20187
+ if (key2.startsWith("$"))
20188
+ continue;
20189
+ if (key2 === "fontFamilies" || key2 === "scale" || key2 === "weights")
20190
+ continue;
20191
+ if (g[key2] !== void 0)
20192
+ continue;
20193
+ if (isObj(src[key2]))
20194
+ g[key2] = canonicalizeGroup(src[key2], TYPE_HINT[key2]);
20195
+ }
20196
+ return g;
20197
+ }
20198
+ function normalizeDimensionGroup(src, dtype) {
20199
+ const g = { $type: src.$type ?? dtype };
20200
+ if (typeof src.$description === "string")
20201
+ g.$description = src.$description;
20202
+ for (const key2 of Object.keys(src)) {
20203
+ if (key2.startsWith("$"))
20204
+ continue;
20205
+ const child = canonicalizeNode(src[key2], g.$type);
20206
+ if (child !== void 0)
20207
+ g[key2] = child;
20208
+ }
20209
+ return g;
20210
+ }
20211
+ function normalizeTokens(raw) {
20212
+ if (!isObj(raw))
20213
+ return {};
20214
+ const out = {};
20215
+ out.$schema = typeof raw.$schema === "string" ? raw.$schema : DTCG_SCHEMA_URL;
20216
+ const meta4 = isObj(raw.$meta) ? raw.$meta : isObj(raw.meta) ? raw.meta : void 0;
20217
+ if (meta4)
20218
+ out.$meta = { ...meta4 };
20219
+ const comps = isObj(raw.$components) ? raw.$components : isObj(raw.components) ? raw.components : void 0;
20220
+ if (comps)
20221
+ out.$components = comps;
20222
+ const colorSrc = isObj(raw.color) ? raw.color : isObj(raw.colors) ? raw.colors : void 0;
20223
+ if (colorSrc)
20224
+ out.color = normalizeColorGroup(colorSrc);
20225
+ if (isObj(raw.typography))
20226
+ out.typography = normalizeTypography(raw.typography);
20227
+ if (isObj(raw.spacing))
20228
+ out.spacing = normalizeDimensionGroup(raw.spacing, "dimension");
20229
+ if (isObj(raw.radius))
20230
+ out.radius = normalizeDimensionGroup(raw.radius, "dimension");
20231
+ if (isObj(raw.shadow))
20232
+ out.shadow = normalizeDimensionGroup(raw.shadow, "shadow");
20233
+ for (const key2 of Object.keys(raw)) {
20234
+ if (key2.startsWith("$") || KNOWN_TOP.has(key2))
20235
+ continue;
20236
+ if (isObj(raw[key2]))
20237
+ out[key2] = canonicalizeGroup(raw[key2], void 0);
20238
+ }
20239
+ return out;
20240
+ }
20241
+ function applyDesignPack(current, packTokens, info, opts) {
20242
+ const cur = normalizeTokens(current);
20243
+ const pack = normalizeTokens(packTokens);
20244
+ const { mode } = opts;
20245
+ const writeLeaves = (base, keep) => {
20246
+ let acc = base;
20247
+ for (const { path: path5, token } of walkTokens(pack)) {
20248
+ if (keep && !keep(path5))
20249
+ continue;
20250
+ acc = setTokenSegments(acc, path5, token);
20251
+ }
20252
+ return acc;
20253
+ };
20254
+ let out;
20255
+ if (mode === "replace") {
20256
+ out = { $schema: pack.$schema ?? cur.$schema ?? DTCG_SCHEMA_URL };
20257
+ if (cur.$meta)
20258
+ out.$meta = cur.$meta;
20259
+ if (cur.$components)
20260
+ out.$components = cur.$components;
20261
+ for (const k of Object.keys(pack))
20262
+ if (!k.startsWith("$"))
20263
+ out[k] = pack[k];
20264
+ } else if (mode === "palette") {
20265
+ out = writeLeaves(cur, (p) => p[0] === "color" || p[0] === "typography" && p[1] === "fontFamily");
20266
+ } else {
20267
+ out = writeLeaves(cur);
20268
+ }
20269
+ const prevMeta = isObj(out.$meta) ? out.$meta : {};
20270
+ return { ...out, $meta: { ...prevMeta, theme: { id: info.id, name: info.name, appliedMode: mode } } };
20271
+ }
20272
+ function parseColorToRgb(v) {
20273
+ const s = v.trim();
20274
+ const hex3 = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(s);
20275
+ if (hex3)
20276
+ return [parseInt(hex3[1] + hex3[1], 16), parseInt(hex3[2] + hex3[2], 16), parseInt(hex3[3] + hex3[3], 16)];
20277
+ const hex6 = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(s);
20278
+ if (hex6)
20279
+ return [parseInt(hex6[1], 16), parseInt(hex6[2], 16), parseInt(hex6[3], 16)];
20280
+ const hsl = /^(-?\d+(?:\.\d+)?)\s*[, ]\s*(-?\d+(?:\.\d+)?)%\s*[, ]\s*(-?\d+(?:\.\d+)?)%$/.exec(s);
20281
+ if (hsl)
20282
+ return hslToRgb(parseFloat(hsl[1]), parseFloat(hsl[2]), parseFloat(hsl[3]));
20283
+ return null;
20284
+ }
20285
+ function hslToRgb(h, s, l) {
20286
+ h = (h % 360 + 360) % 360;
20287
+ s /= 100;
20288
+ l /= 100;
20289
+ const c = (1 - Math.abs(2 * l - 1)) * s;
20290
+ const x = c * (1 - Math.abs(h / 60 % 2 - 1));
20291
+ const m = l - c / 2;
20292
+ let r = 0, g = 0, b = 0;
20293
+ if (h < 60)
20294
+ [r, g, b] = [c, x, 0];
20295
+ else if (h < 120)
20296
+ [r, g, b] = [x, c, 0];
20297
+ else if (h < 180)
20298
+ [r, g, b] = [0, c, x];
20299
+ else if (h < 240)
20300
+ [r, g, b] = [0, x, c];
20301
+ else if (h < 300)
20302
+ [r, g, b] = [x, 0, c];
20303
+ else
20304
+ [r, g, b] = [c, 0, x];
20305
+ return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)];
20306
+ }
20307
+ function relLuminance([r, g, b]) {
20308
+ const lin = (c) => {
20309
+ const cs = c / 255;
20310
+ return cs <= 0.03928 ? cs / 12.92 : Math.pow((cs + 0.055) / 1.055, 2.4);
20311
+ };
20312
+ return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
20313
+ }
20314
+ function contrastRatio(a, b) {
20315
+ const ca = parseColorToRgb(a), cb = parseColorToRgb(b);
20316
+ if (!ca || !cb)
20317
+ return 0;
20318
+ const la = relLuminance(ca), lb = relLuminance(cb);
20319
+ const hi = Math.max(la, lb), lo = Math.min(la, lb);
20320
+ return (hi + 0.05) / (lo + 0.05);
20321
+ }
20322
+ function setNested(obj, segs, value) {
20323
+ let cur = obj;
20324
+ for (let i = 0; i < segs.length - 1; i++) {
20325
+ const k = segs[i];
20326
+ if (!isObj(cur[k]))
20327
+ cur[k] = {};
20328
+ cur = cur[k];
20329
+ }
20330
+ cur[segs[segs.length - 1]] = value;
20331
+ }
20332
+ function tokensToTailwindTheme(input) {
20333
+ const tokens = normalizeTokens(input);
20334
+ const extend2 = {};
20335
+ for (const { path: path5, token } of walkTokens(tokens)) {
20336
+ const bucket = TW_BUCKETS.find((b) => b.match.length <= path5.length && b.match.every((seg, i) => path5[i] === seg));
20337
+ if (!bucket)
20338
+ continue;
20339
+ const rest = path5.slice(bucket.match.length).map(kebab).filter(Boolean);
20340
+ if (rest.length === 0)
20341
+ continue;
20342
+ const ref = `var(${tokenCssVarName(path5, token)})`;
20343
+ if (!extend2[bucket.key])
20344
+ extend2[bucket.key] = {};
20345
+ if (bucket.flat)
20346
+ extend2[bucket.key][rest.join("-")] = ref;
20347
+ else
20348
+ setNested(extend2[bucket.key], rest, ref);
20349
+ }
20350
+ return { extend: extend2 };
20351
+ }
20352
+ function tokensToTailwindConfig(input) {
20353
+ const theme = tokensToTailwindTheme(input);
20354
+ return [
20355
+ "// GENERATED from design-system/tokens.json \u2014 do not edit by hand.",
20356
+ "// Spread `theme.extend` into your tailwind.config; values reference the vars in tokens.css.",
20357
+ `export const theme = ${JSON.stringify(theme, null, 2)};`,
20358
+ "export default theme;",
20359
+ ""
20360
+ ].join("\n");
20361
+ }
20362
+ function leafSignature(token) {
20363
+ const dark = tessExt(token)?.modes?.dark;
20364
+ return JSON.stringify(dark === void 0 ? [token.$value] : [token.$value, dark]);
20365
+ }
20366
+ function indexLeaves(t) {
20367
+ const m = /* @__PURE__ */ new Map();
20368
+ for (const { path: path5, token } of walkTokens(t)) {
20369
+ m.set(path5.join("."), { sig: leafSignature(token), disp: stringifyValue(token.$value) });
20370
+ }
20371
+ return m;
20372
+ }
20373
+ function diffTokens(prev, next) {
20374
+ const a = indexLeaves(normalizeTokens(prev));
20375
+ const b = indexLeaves(normalizeTokens(next));
20376
+ const added = [];
20377
+ const removed = [];
20378
+ const changed = [];
20379
+ for (const k of b.keys())
20380
+ if (!a.has(k))
20381
+ added.push(k);
20382
+ for (const [k, va] of a) {
20383
+ const vb = b.get(k);
20384
+ if (!vb) {
20385
+ removed.push(k);
20386
+ continue;
20387
+ }
20388
+ if (va.sig !== vb.sig)
20389
+ changed.push({ path: k, from: va.disp, to: vb.disp });
20390
+ }
20391
+ added.sort();
20392
+ removed.sort();
20393
+ changed.sort((x, y) => x.path < y.path ? -1 : x.path > y.path ? 1 : 0);
20394
+ return { added, removed, changed };
20395
+ }
20396
+ function bumpVersion(prev, level = "patch") {
20397
+ const m = typeof prev === "string" ? /^(\d+)\.(\d+)\.(\d+)/.exec(prev.trim()) : null;
20398
+ if (!m)
20399
+ return "1.0.0";
20400
+ let [maj, min, pat] = [Number(m[1]), Number(m[2]), Number(m[3])];
20401
+ if (level === "major") {
20402
+ maj += 1;
20403
+ min = 0;
20404
+ pat = 0;
20405
+ } else if (level === "minor") {
20406
+ min += 1;
20407
+ pat = 0;
20408
+ } else
20409
+ pat += 1;
20410
+ return `${maj}.${min}.${pat}`;
20411
+ }
20412
+ var DESIGN_DIR, TOKENS_FILE, TOKENS_CSS_FILE, DESIGN_CLAUDE_MD, DTCG_SCHEMA_URL, DTCG_TYPES, VAR_ALIASES, CATEGORY_ORDER, KNOWN_TOP, TW_BUCKETS;
19405
20413
  var init_design_tokens = __esm({
19406
- "../../packages/agent-core/dist/design-tokens.js"() {
20414
+ "../../packages/shared/dist/design-tokens.js"() {
19407
20415
  "use strict";
19408
- init_zod();
19409
20416
  DESIGN_DIR = "design-system";
19410
20417
  TOKENS_FILE = "design-system/tokens.json";
19411
20418
  TOKENS_CSS_FILE = "design-system/tokens.css";
19412
20419
  DESIGN_CLAUDE_MD = "design-system/CLAUDE.md";
19413
- ColorToken = external_exports.object({ value: external_exports.string(), cssVar: external_exports.string().optional(), role: external_exports.string().optional() });
19414
- TypeStep = external_exports.object({ size: external_exports.string(), lineHeight: external_exports.string().optional(), weight: external_exports.number().optional() });
19415
- Component = external_exports.object({
19416
- selectorHint: external_exports.string().optional(),
19417
- sourceFiles: external_exports.array(external_exports.string()).optional(),
19418
- tokensUsed: external_exports.array(external_exports.string()).optional()
19419
- });
19420
- DesignTokensSchema = external_exports.object({
20420
+ DTCG_SCHEMA_URL = "https://design-tokens.github.io/community-group/format/";
20421
+ DTCG_TYPES = [
20422
+ "color",
20423
+ "dimension",
20424
+ "fontFamily",
20425
+ "fontWeight",
20426
+ "duration",
20427
+ "cubicBezier",
20428
+ "number",
20429
+ "shadow",
20430
+ "strokeStyle",
20431
+ "border",
20432
+ "transition",
20433
+ "gradient",
20434
+ "typography",
20435
+ "lineHeight",
20436
+ "letterSpacing"
20437
+ ];
20438
+ VAR_ALIASES = [
20439
+ { match: ["typography", "fontFamily"], prefix: "font" },
20440
+ { match: ["typography", "fontSize"], prefix: "text" },
20441
+ { match: ["typography", "fontWeight"], prefix: "weight" },
20442
+ { match: ["typography", "lineHeight"], prefix: "leading" },
20443
+ { match: ["typography", "letterSpacing"], prefix: "tracking" },
20444
+ { match: ["color"], prefix: "color" },
20445
+ { match: ["colors"], prefix: "color" },
20446
+ { match: ["spacing"], prefix: "space" },
20447
+ { match: ["radius"], prefix: "radius" },
20448
+ { match: ["shadow"], prefix: "shadow" },
20449
+ { match: ["motion", "duration"], prefix: "duration" },
20450
+ { match: ["motion", "easing"], prefix: "ease" }
20451
+ ];
20452
+ CATEGORY_ORDER = ["color", "typography", "spacing", "radius", "shadow", "motion"];
20453
+ KNOWN_TOP = /* @__PURE__ */ new Set(["meta", "components", "color", "colors", "typography", "spacing", "radius", "shadow"]);
20454
+ TW_BUCKETS = [
20455
+ { match: ["typography", "fontFamily"], key: "fontFamily", flat: true },
20456
+ { match: ["typography", "fontSize"], key: "fontSize", flat: true },
20457
+ { match: ["typography", "fontWeight"], key: "fontWeight", flat: true },
20458
+ { match: ["typography", "lineHeight"], key: "lineHeight", flat: true },
20459
+ { match: ["typography", "letterSpacing"], key: "letterSpacing", flat: true },
20460
+ { match: ["color"], key: "colors", flat: false },
20461
+ { match: ["colors"], key: "colors", flat: false },
20462
+ { match: ["spacing"], key: "spacing", flat: true },
20463
+ { match: ["radius"], key: "borderRadius", flat: true },
20464
+ { match: ["shadow"], key: "boxShadow", flat: true },
20465
+ { match: ["motion", "duration"], key: "transitionDuration", flat: true },
20466
+ { match: ["motion", "easing"], key: "transitionTimingFunction", flat: true }
20467
+ ];
20468
+ }
20469
+ });
20470
+
20471
+ // ../../packages/shared/dist/snapshot.js
20472
+ var SNAPSHOT_MAX_TEXT_BYTES, SNAPSHOT_MAX_BINARY_BYTES, SNAPSHOT_MAX_TOTAL_BYTES;
20473
+ var init_snapshot = __esm({
20474
+ "../../packages/shared/dist/snapshot.js"() {
20475
+ "use strict";
20476
+ SNAPSHOT_MAX_TEXT_BYTES = 512 * 1024;
20477
+ SNAPSHOT_MAX_BINARY_BYTES = 4 * 1024 * 1024;
20478
+ SNAPSHOT_MAX_TOTAL_BYTES = 24 * 1024 * 1024;
20479
+ }
20480
+ });
20481
+
20482
+ // ../../packages/shared/dist/index.js
20483
+ var init_dist2 = __esm({
20484
+ "../../packages/shared/dist/index.js"() {
20485
+ "use strict";
20486
+ init_ws_protocol();
20487
+ init_frame();
20488
+ init_plans();
20489
+ init_slug();
20490
+ init_hosting();
20491
+ init_cloud_agent();
20492
+ init_engines();
20493
+ init_providers();
20494
+ init_runtimes();
20495
+ init_runner_configs();
20496
+ init_rotation();
20497
+ init_settings();
20498
+ init_design_tokens();
20499
+ init_snapshot();
20500
+ }
20501
+ });
20502
+
20503
+ // ../../packages/agent-core/dist/design-tokens.js
20504
+ var TokenValueSchema, NodeSchema, DtcgTokensSchema, DesignTokensSchema;
20505
+ var init_design_tokens2 = __esm({
20506
+ "../../packages/agent-core/dist/design-tokens.js"() {
20507
+ "use strict";
20508
+ init_zod();
20509
+ init_dist2();
20510
+ TokenValueSchema = external_exports.union([
20511
+ external_exports.string(),
20512
+ external_exports.number(),
20513
+ external_exports.array(external_exports.string()),
20514
+ external_exports.record(external_exports.string(), external_exports.unknown()),
20515
+ external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown()))
20516
+ ]);
20517
+ NodeSchema = external_exports.lazy(() => external_exports.union([
20518
+ external_exports.object({ $value: TokenValueSchema }).catchall(external_exports.unknown()),
20519
+ // token: must carry $value
20520
+ external_exports.record(external_exports.string(), external_exports.unknown())
20521
+ // group: any record of nodes
20522
+ ]));
20523
+ DtcgTokensSchema = external_exports.object({
19421
20524
  $schema: external_exports.string().optional(),
19422
- meta: external_exports.object({
19423
- name: external_exports.string().optional(),
19424
- framework: external_exports.enum(["tailwind", "css", "css-modules", "unknown"]).optional(),
19425
- generatedAt: external_exports.string().optional()
19426
- }).optional(),
19427
- colors: external_exports.record(external_exports.string(), ColorToken).optional(),
19428
- typography: external_exports.object({
19429
- fontFamilies: external_exports.record(external_exports.string(), external_exports.string()).optional(),
19430
- scale: external_exports.record(external_exports.string(), TypeStep).optional(),
19431
- weights: external_exports.record(external_exports.string(), external_exports.number()).optional()
19432
- }).optional(),
19433
- spacing: external_exports.record(external_exports.string(), external_exports.string()).optional(),
19434
- radius: external_exports.record(external_exports.string(), external_exports.string()).optional(),
19435
- shadow: external_exports.record(external_exports.string(), external_exports.string()).optional(),
19436
- components: external_exports.record(external_exports.string(), Component).optional()
19437
- });
20525
+ $meta: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
20526
+ $components: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
20527
+ }).catchall(NodeSchema);
20528
+ DesignTokensSchema = DtcgTokensSchema;
20529
+ }
20530
+ });
20531
+
20532
+ // ../../packages/design-packs/dist/types.js
20533
+ var DESIGN_PACK_SCHEMA;
20534
+ var init_types = __esm({
20535
+ "../../packages/design-packs/dist/types.js"() {
20536
+ "use strict";
20537
+ DESIGN_PACK_SCHEMA = "https://tesseract.fineguide.ai/schemas/design-pack/v1";
20538
+ }
20539
+ });
20540
+
20541
+ // ../../packages/design-packs/dist/packs/_build.js
20542
+ function buildPack(s) {
20543
+ const dual = (lv) => ({ $value: lv[0], $extensions: { "com.tesseract": { modes: { dark: lv[1] } } } });
20544
+ const r = s.radius ?? { sm: "6px", md: "10px", lg: "16px" };
20545
+ const sh = s.shadow ?? {
20546
+ sm: "0 1px 2px rgb(0 0 0 / 0.06)",
20547
+ md: "0 4px 12px rgb(0 0 0 / 0.08)",
20548
+ lg: "0 12px 32px rgb(0 0 0 / 0.12)"
20549
+ };
20550
+ const b = s.baseFontPx ?? 16;
20551
+ const tokens = {
20552
+ $schema: "https://design-tokens.github.io/community-group/format/",
20553
+ color: {
20554
+ $type: "color",
20555
+ brand: {
20556
+ primary: { $value: s.brandPrimary },
20557
+ onPrimary: { $value: s.onPrimary },
20558
+ ...s.brandAccent ? { accent: { $value: s.brandAccent } } : {}
20559
+ },
20560
+ surface: { page: dual(s.page), card: dual(s.card) },
20561
+ text: { primary: dual(s.textPrimary), secondary: dual(s.textSecondary), muted: dual(s.textMuted) },
20562
+ border: { default: dual(s.border) }
20563
+ },
20564
+ typography: {
20565
+ fontFamily: {
20566
+ $type: "fontFamily",
20567
+ sans: { $value: s.sans },
20568
+ ...s.display ? { display: { $value: s.display } } : {},
20569
+ mono: { $value: s.mono ?? ["ui-monospace", "SFMono-Regular", "Menlo", "monospace"] }
20570
+ },
20571
+ fontSize: {
20572
+ $type: "dimension",
20573
+ sm: { $value: `${b - 2}px` },
20574
+ base: { $value: `${b}px` },
20575
+ lg: { $value: `${b + 2}px` },
20576
+ xl: { $value: `${b + 8}px` },
20577
+ "2xl": { $value: `${b + 16}px` }
20578
+ },
20579
+ fontWeight: { $type: "fontWeight", normal: { $value: 400 }, medium: { $value: 500 }, bold: { $value: 700 } }
20580
+ },
20581
+ spacing: {
20582
+ $type: "dimension",
20583
+ xs: { $value: "4px" },
20584
+ sm: { $value: "8px" },
20585
+ md: { $value: "16px" },
20586
+ lg: { $value: "24px" },
20587
+ xl: { $value: "40px" }
20588
+ },
20589
+ radius: { $type: "dimension", sm: { $value: r.sm }, md: { $value: r.md }, lg: { $value: r.lg }, full: { $value: "9999px" } },
20590
+ shadow: { $type: "shadow", sm: { $value: sh.sm }, md: { $value: sh.md }, lg: { $value: sh.lg } }
20591
+ };
20592
+ return { $packSchema: DESIGN_PACK_SCHEMA, id: s.id, name: s.name, description: s.description, style: s.style, tokens };
20593
+ }
20594
+ var init_build = __esm({
20595
+ "../../packages/design-packs/dist/packs/_build.js"() {
20596
+ "use strict";
20597
+ init_types();
20598
+ }
20599
+ });
20600
+
20601
+ // ../../packages/design-packs/dist/packs/clean-minimal.js
20602
+ var clean_minimal_default;
20603
+ var init_clean_minimal = __esm({
20604
+ "../../packages/design-packs/dist/packs/clean-minimal.js"() {
20605
+ "use strict";
20606
+ init_build();
20607
+ clean_minimal_default = buildPack({
20608
+ id: "clean-minimal",
20609
+ name: "Clean Minimal",
20610
+ description: "Whitespace, neutral grays, restrained. The safe default.",
20611
+ style: "minimal",
20612
+ brandPrimary: "#111827",
20613
+ onPrimary: "#ffffff",
20614
+ page: ["#ffffff", "#0b0b0c"],
20615
+ card: ["#fafafa", "#151517"],
20616
+ textPrimary: ["#111827", "#f4f4f5"],
20617
+ textSecondary: ["#4b5563", "#a1a1aa"],
20618
+ textMuted: ["#888d99", "#71717a"],
20619
+ border: ["#e5e7eb", "#27272a"],
20620
+ sans: ["Inter", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "sans-serif"],
20621
+ radius: { sm: "6px", md: "8px", lg: "12px" }
20622
+ });
20623
+ }
20624
+ });
20625
+
20626
+ // ../../packages/design-packs/dist/packs/corporate-trust.js
20627
+ var corporate_trust_default;
20628
+ var init_corporate_trust = __esm({
20629
+ "../../packages/design-packs/dist/packs/corporate-trust.js"() {
20630
+ "use strict";
20631
+ init_build();
20632
+ corporate_trust_default = buildPack({
20633
+ id: "corporate-trust",
20634
+ name: "Corporate Trust",
20635
+ description: "Professional blue/slate, structured, trust signals.",
20636
+ style: "corporate",
20637
+ brandPrimary: "#1d4ed8",
20638
+ onPrimary: "#ffffff",
20639
+ brandAccent: "#0ea5e9",
20640
+ page: ["#ffffff", "#0b1220"],
20641
+ card: ["#f8fafc", "#0f1a2e"],
20642
+ textPrimary: ["#0f172a", "#e2e8f0"],
20643
+ textSecondary: ["#475569", "#94a3b8"],
20644
+ textMuted: ["#7e8ba1", "#64748b"],
20645
+ border: ["#e2e8f0", "#1e293b"],
20646
+ sans: ["Inter", "-apple-system", "Segoe UI", "sans-serif"],
20647
+ radius: { sm: "4px", md: "8px", lg: "12px" }
20648
+ });
20649
+ }
20650
+ });
20651
+
20652
+ // ../../packages/design-packs/dist/packs/refined-brutalist.js
20653
+ var refined_brutalist_default;
20654
+ var init_refined_brutalist = __esm({
20655
+ "../../packages/design-packs/dist/packs/refined-brutalist.js"() {
20656
+ "use strict";
20657
+ init_build();
20658
+ refined_brutalist_default = buildPack({
20659
+ id: "refined-brutalist",
20660
+ name: "Refined Brutalist",
20661
+ description: "Raw grotesk type, visible grid, hard edges, high accessible contrast.",
20662
+ style: "brutalist",
20663
+ brandPrimary: "#000000",
20664
+ onPrimary: "#ffffff",
20665
+ brandAccent: "#ff3b00",
20666
+ page: ["#ffffff", "#000000"],
20667
+ card: ["#f4f4f4", "#0c0c0c"],
20668
+ textPrimary: ["#000000", "#ffffff"],
20669
+ textSecondary: ["#333333", "#cccccc"],
20670
+ textMuted: ["#666666", "#999999"],
20671
+ border: ["#000000", "#ffffff"],
20672
+ sans: ["Space Grotesk", "Arial", "Helvetica", "sans-serif"],
20673
+ mono: ["Space Mono", "ui-monospace", "monospace"],
20674
+ radius: { sm: "0px", md: "0px", lg: "0px" },
20675
+ shadow: { sm: "2px 2px 0 #000", md: "4px 4px 0 #000", lg: "8px 8px 0 #000" }
20676
+ });
20677
+ }
20678
+ });
20679
+
20680
+ // ../../packages/design-packs/dist/packs/editorial.js
20681
+ var editorial_default;
20682
+ var init_editorial = __esm({
20683
+ "../../packages/design-packs/dist/packs/editorial.js"() {
20684
+ "use strict";
20685
+ init_build();
20686
+ editorial_default = buildPack({
20687
+ id: "editorial",
20688
+ name: "Editorial",
20689
+ description: "Serif display, classical art-converging, magazine layout.",
20690
+ style: "editorial",
20691
+ brandPrimary: "#1a1a1a",
20692
+ onPrimary: "#ffffff",
20693
+ brandAccent: "#9a3412",
20694
+ page: ["#fbfaf7", "#1a1714"],
20695
+ card: ["#ffffff", "#221d19"],
20696
+ textPrimary: ["#1a1a1a", "#f0ece4"],
20697
+ textSecondary: ["#57534e", "#a8a29e"],
20698
+ textMuted: ["#78716c", "#857b6e"],
20699
+ border: ["#e7e2d8", "#2a2520"],
20700
+ sans: ["Georgia", "Cambria", "Times New Roman", "serif"],
20701
+ display: ["Playfair Display", "Georgia", "serif"],
20702
+ radius: { sm: "2px", md: "4px", lg: "6px" }
20703
+ });
20704
+ }
20705
+ });
20706
+
20707
+ // ../../packages/design-packs/dist/packs/soft-clay-playful.js
20708
+ var soft_clay_playful_default;
20709
+ var init_soft_clay_playful = __esm({
20710
+ "../../packages/design-packs/dist/packs/soft-clay-playful.js"() {
20711
+ "use strict";
20712
+ init_build();
20713
+ soft_clay_playful_default = buildPack({
20714
+ id: "soft-clay-playful",
20715
+ name: "Soft / Clay Playful",
20716
+ description: "Rounded claymorphism, friendly, bright violet accents.",
20717
+ style: "playful",
20718
+ brandPrimary: "#7c3aed",
20719
+ onPrimary: "#ffffff",
20720
+ brandAccent: "#f59e0b",
20721
+ page: ["#fffdf9", "#15131a"],
20722
+ card: ["#ffffff", "#1d1a24"],
20723
+ textPrimary: ["#2e1065", "#f5f3ff"],
20724
+ textSecondary: ["#6d28d9", "#c4b5fd"],
20725
+ textMuted: ["#8b5cf6", "#8b7fb0"],
20726
+ border: ["#ede9fe", "#2e2640"],
20727
+ sans: ["Quicksand", "Nunito", "-apple-system", "sans-serif"],
20728
+ radius: { sm: "12px", md: "20px", lg: "28px" },
20729
+ shadow: { sm: "0 2px 6px rgb(124 58 237 / 0.12)", md: "0 8px 20px rgb(124 58 237 / 0.16)", lg: "0 16px 40px rgb(124 58 237 / 0.20)" }
20730
+ });
20731
+ }
20732
+ });
20733
+
20734
+ // ../../packages/design-packs/dist/packs/premium-dark.js
20735
+ var premium_dark_default;
20736
+ var init_premium_dark = __esm({
20737
+ "../../packages/design-packs/dist/packs/premium-dark.js"() {
20738
+ "use strict";
20739
+ init_build();
20740
+ premium_dark_default = buildPack({
20741
+ id: "premium-dark",
20742
+ name: "Premium Dark",
20743
+ description: "Dark-first, high-end gold accent, luxe restraint.",
20744
+ style: "dark",
20745
+ brandPrimary: "#e5b567",
20746
+ onPrimary: "#1a1408",
20747
+ brandAccent: "#f5d491",
20748
+ page: ["#0a0a0b", "#070708"],
20749
+ card: ["#161618", "#1c1c1f"],
20750
+ textPrimary: ["#fafafa", "#fafafa"],
20751
+ textSecondary: ["#a1a1aa", "#a1a1aa"],
20752
+ textMuted: ["#71717a", "#71717a"],
20753
+ border: ["#27272a", "#2c2c30"],
20754
+ sans: ["Inter", "-apple-system", "Segoe UI", "sans-serif"],
20755
+ radius: { sm: "6px", md: "10px", lg: "14px" },
20756
+ shadow: { sm: "0 1px 2px rgb(0 0 0 / 0.5)", md: "0 6px 16px rgb(0 0 0 / 0.55)", lg: "0 16px 40px rgb(0 0 0 / 0.6)" }
20757
+ });
20758
+ }
20759
+ });
20760
+
20761
+ // ../../packages/design-packs/dist/packs/glass-aurora.js
20762
+ var glass_aurora_default;
20763
+ var init_glass_aurora = __esm({
20764
+ "../../packages/design-packs/dist/packs/glass-aurora.js"() {
20765
+ "use strict";
20766
+ init_build();
20767
+ glass_aurora_default = buildPack({
20768
+ id: "glass-aurora",
20769
+ name: "Glass / Aurora",
20770
+ description: "Translucent frosted layers, soft gradients and glow.",
20771
+ style: "glass",
20772
+ brandPrimary: "#4f46e5",
20773
+ onPrimary: "#ffffff",
20774
+ brandAccent: "#22d3ee",
20775
+ page: ["#f8fafc", "#0b1020"],
20776
+ card: ["#ffffff", "#111735"],
20777
+ textPrimary: ["#0f172a", "#e7ecff"],
20778
+ textSecondary: ["#475569", "#aab4d4"],
20779
+ textMuted: ["#7e8ba1", "#6b7494"],
20780
+ border: ["#e2e8f0", "#23294a"],
20781
+ sans: ["Inter", "-apple-system", "Segoe UI", "sans-serif"],
20782
+ radius: { sm: "10px", md: "16px", lg: "24px" },
20783
+ shadow: { sm: "0 1px 2px rgb(79 70 229 / 0.10)", md: "0 8px 24px rgb(79 70 229 / 0.14)", lg: "0 20px 48px rgb(79 70 229 / 0.18)" }
20784
+ });
20785
+ }
20786
+ });
20787
+
20788
+ // ../../packages/design-packs/dist/packs/dopamine-pop.js
20789
+ var dopamine_pop_default;
20790
+ var init_dopamine_pop = __esm({
20791
+ "../../packages/design-packs/dist/packs/dopamine-pop.js"() {
20792
+ "use strict";
20793
+ init_build();
20794
+ dopamine_pop_default = buildPack({
20795
+ id: "dopamine-pop",
20796
+ name: "Dopamine Pop",
20797
+ description: "Confident, accessible full-color system. Bold and energetic.",
20798
+ style: "dopamine",
20799
+ brandPrimary: "#7e22ce",
20800
+ onPrimary: "#ffffff",
20801
+ brandAccent: "#f59e0b",
20802
+ page: ["#fffaf5", "#190a18"],
20803
+ card: ["#ffffff", "#241023"],
20804
+ textPrimary: ["#3b0764", "#fdf4ff"],
20805
+ textSecondary: ["#7e22ce", "#e9d5ff"],
20806
+ textMuted: ["#a855f7", "#9b6fb5"],
20807
+ border: ["#f5d0fe", "#3b1d49"],
20808
+ sans: ["Plus Jakarta Sans", "Inter", "-apple-system", "sans-serif"],
20809
+ radius: { sm: "8px", md: "14px", lg: "22px" }
20810
+ });
20811
+ }
20812
+ });
20813
+
20814
+ // ../../packages/design-packs/dist/packs/retro-y2k.js
20815
+ var retro_y2k_default;
20816
+ var init_retro_y2k = __esm({
20817
+ "../../packages/design-packs/dist/packs/retro-y2k.js"() {
20818
+ "use strict";
20819
+ init_build();
20820
+ retro_y2k_default = buildPack({
20821
+ id: "retro-y2k",
20822
+ name: "Retro / Y2K",
20823
+ description: "Nostalgic, grain-textured, vibrant and chunky.",
20824
+ style: "retro",
20825
+ brandPrimary: "#b91c1c",
20826
+ onPrimary: "#fdf6ec",
20827
+ brandAccent: "#f59e0b",
20828
+ page: ["#fdf6ec", "#1b1410"],
20829
+ card: ["#fffaf0", "#241a13"],
20830
+ textPrimary: ["#1c1917", "#f5ede0"],
20831
+ textSecondary: ["#57534e", "#bcae9c"],
20832
+ textMuted: ["#78716c", "#8a7c6a"],
20833
+ border: ["#e7d9c2", "#352a1d"],
20834
+ sans: ["Space Grotesk", "Arial", "sans-serif"],
20835
+ display: ["Space Grotesk", "Impact", "sans-serif"],
20836
+ radius: { sm: "4px", md: "8px", lg: "14px" },
20837
+ shadow: { sm: "3px 3px 0 rgb(28 25 23 / 0.9)", md: "5px 5px 0 rgb(28 25 23 / 0.9)", lg: "8px 8px 0 rgb(28 25 23 / 0.9)" }
20838
+ });
20839
+ }
20840
+ });
20841
+
20842
+ // ../../packages/design-packs/dist/packs/warm-organic.js
20843
+ var warm_organic_default;
20844
+ var init_warm_organic = __esm({
20845
+ "../../packages/design-packs/dist/packs/warm-organic.js"() {
20846
+ "use strict";
20847
+ init_build();
20848
+ warm_organic_default = buildPack({
20849
+ id: "warm-organic",
20850
+ name: "Warm Organic",
20851
+ description: "Earth tones, natural, calm. Wellness and hospitality.",
20852
+ style: "organic",
20853
+ brandPrimary: "#7c5c43",
20854
+ onPrimary: "#ffffff",
20855
+ brandAccent: "#84cc16",
20856
+ page: ["#faf6f1", "#1a1512"],
20857
+ card: ["#fffdf9", "#221b16"],
20858
+ textPrimary: ["#2b211a", "#efe7dd"],
20859
+ textSecondary: ["#6b5b4d", "#c4b3a3"],
20860
+ textMuted: ["#998a7a", "#8a7868"],
20861
+ border: ["#e8ddcf", "#33291f"],
20862
+ sans: ["Source Sans 3", "Source Sans Pro", "-apple-system", "sans-serif"],
20863
+ radius: { sm: "8px", md: "14px", lg: "20px" }
20864
+ });
20865
+ }
20866
+ });
20867
+
20868
+ // ../../packages/design-packs/dist/packs/luxury-elegant.js
20869
+ var luxury_elegant_default;
20870
+ var init_luxury_elegant = __esm({
20871
+ "../../packages/design-packs/dist/packs/luxury-elegant.js"() {
20872
+ "use strict";
20873
+ init_build();
20874
+ luxury_elegant_default = buildPack({
20875
+ id: "luxury-elegant",
20876
+ name: "Luxury Elegant",
20877
+ description: "Muted, fine serif, gold-on-black, refined restraint.",
20878
+ style: "luxury",
20879
+ brandPrimary: "#11100f",
20880
+ onPrimary: "#d4af37",
20881
+ brandAccent: "#b08d57",
20882
+ page: ["#faf9f7", "#0e0d0c"],
20883
+ card: ["#ffffff", "#171513"],
20884
+ textPrimary: ["#1a1816", "#f3efe9"],
20885
+ textSecondary: ["#57514a", "#b8ada0"],
20886
+ textMuted: ["#8a8278", "#7c7468"],
20887
+ border: ["#e8e2d8", "#2a251f"],
20888
+ sans: ["Cormorant Garamond", "Garamond", "Georgia", "serif"],
20889
+ display: ["Cormorant Garamond", "Didot", "Georgia", "serif"],
20890
+ radius: { sm: "2px", md: "4px", lg: "8px" },
20891
+ shadow: { sm: "0 1px 2px rgb(0 0 0 / 0.05)", md: "0 6px 18px rgb(0 0 0 / 0.07)", lg: "0 18px 44px rgb(0 0 0 / 0.10)" }
20892
+ });
20893
+ }
20894
+ });
20895
+
20896
+ // ../../packages/design-packs/dist/packs/bento-tech.js
20897
+ var bento_tech_default;
20898
+ var init_bento_tech = __esm({
20899
+ "../../packages/design-packs/dist/packs/bento-tech.js"() {
20900
+ "use strict";
20901
+ init_build();
20902
+ bento_tech_default = buildPack({
20903
+ id: "bento-tech",
20904
+ name: "Bento Tech",
20905
+ description: "Crisp modular bento rhythm, grid-forward, product-led.",
20906
+ style: "tech",
20907
+ brandPrimary: "#2563eb",
20908
+ onPrimary: "#ffffff",
20909
+ brandAccent: "#06b6d4",
20910
+ page: ["#f6f7f9", "#0c0e12"],
20911
+ card: ["#ffffff", "#13161c"],
20912
+ textPrimary: ["#0b0e14", "#e9edf5"],
20913
+ textSecondary: ["#3f4756", "#9aa4b8"],
20914
+ textMuted: ["#7a8499", "#6b7488"],
20915
+ border: ["#e6e8ee", "#1d212b"],
20916
+ sans: ["Geist", "Inter", "-apple-system", "sans-serif"],
20917
+ mono: ["Geist Mono", "ui-monospace", "monospace"],
20918
+ radius: { sm: "8px", md: "12px", lg: "16px" }
20919
+ });
20920
+ }
20921
+ });
20922
+
20923
+ // ../../packages/design-packs/dist/index.js
20924
+ function getPack(id) {
20925
+ return PACKS_BY_ID[id];
20926
+ }
20927
+ var PACKS, PACKS_BY_ID;
20928
+ var init_dist3 = __esm({
20929
+ "../../packages/design-packs/dist/index.js"() {
20930
+ "use strict";
20931
+ init_types();
20932
+ init_clean_minimal();
20933
+ init_corporate_trust();
20934
+ init_refined_brutalist();
20935
+ init_editorial();
20936
+ init_soft_clay_playful();
20937
+ init_premium_dark();
20938
+ init_glass_aurora();
20939
+ init_dopamine_pop();
20940
+ init_retro_y2k();
20941
+ init_warm_organic();
20942
+ init_luxury_elegant();
20943
+ init_bento_tech();
20944
+ PACKS = [
20945
+ clean_minimal_default,
20946
+ corporate_trust_default,
20947
+ refined_brutalist_default,
20948
+ editorial_default,
20949
+ soft_clay_playful_default,
20950
+ premium_dark_default,
20951
+ glass_aurora_default,
20952
+ dopamine_pop_default,
20953
+ retro_y2k_default,
20954
+ warm_organic_default,
20955
+ luxury_elegant_default,
20956
+ bento_tech_default
20957
+ ];
20958
+ PACKS_BY_ID = Object.fromEntries(PACKS.map((p) => [p.id, p]));
19438
20959
  }
19439
20960
  });
19440
20961
 
@@ -19448,8 +20969,8 @@ function within(root, p) {
19448
20969
  }
19449
20970
  async function loadTokens(root) {
19450
20971
  try {
19451
- const parsed = DesignTokensSchema.safeParse(JSON.parse(await readFile(join4(root, TOKENS_FILE), "utf8")));
19452
- return parsed.success ? parsed.data : {};
20972
+ const norm = normalizeTokens(JSON.parse(await readFile(join4(root, TOKENS_FILE), "utf8")));
20973
+ return DesignTokensSchema.safeParse(norm).success ? norm : {};
19453
20974
  } catch {
19454
20975
  return {};
19455
20976
  }
@@ -19472,28 +20993,64 @@ function buildDesignTools(deps) {
19472
20993
  return root;
19473
20994
  };
19474
20995
  return [
19475
- tool2("read_design_tokens", "Read the project design system from design-system/tokens.json (colors, typography, spacing, radius, shadow, components). Call this ONCE when you need token values \u2014 do not guess hardcoded hex/sizes.", { section: external_exports.enum(["all", "colors", "typography", "spacing", "radius", "shadow", "components"]).optional().describe("Limit to one section (default: all)") }, async (args) => {
20996
+ tool2("read_design_tokens", "Read the project design system from design-system/tokens.json in W3C DTCG format (color, typography, spacing, radius, shadow, components). Call this ONCE when you need token values \u2014 do not guess hardcoded hex/sizes.", { section: external_exports.enum(["all", "color", "typography", "spacing", "radius", "shadow", "components"]).optional().describe("Limit to one section (default: all)") }, async (args) => {
19476
20997
  const tokens = await loadTokens(needRoot());
19477
- const out = !args.section || args.section === "all" ? tokens : { [args.section]: tokens[args.section] ?? {} };
20998
+ const key2 = args.section === "components" ? "$components" : args.section;
20999
+ const out = !args.section || args.section === "all" ? tokens : { [args.section]: tokens[key2] ?? {} };
19478
21000
  return text(JSON.stringify(out, null, 2));
19479
21001
  }),
19480
- tool2("write_design_token", 'Set one or more design tokens by dot-path (e.g. "colors.primary.value" = "#d97757", "spacing.2" = "0.5rem") and regenerate design-system/tokens.css. Batch related edits in one call. Path-guarded to the project root.', {
21002
+ tool2("write_design_token", 'Set one or more design tokens by DTCG dot-path (e.g. "color.brand.primary.$value" = "#d97757", "spacing.md.$value" = "0.5rem") and regenerate design-system/tokens.css. Token leaves carry $value; set a group $type once (e.g. "color.$type" = "color"). Batch related edits in one call. Path-guarded to the project root.', {
19481
21003
  edits: external_exports.array(external_exports.object({
19482
- path: external_exports.string().describe("Dot-path into tokens.json, e.g. colors.primary.value"),
19483
- value: external_exports.union([external_exports.string(), external_exports.number()]).describe("The new value")
21004
+ path: external_exports.string().optional().describe("DTCG dot-path into tokens.json, e.g. color.brand.primary.$value"),
21005
+ segments: external_exports.array(external_exports.string()).optional().describe("Explicit path segments \u2014 use instead of path when a key contains a dot (e.g. a $extensions vendor key)"),
21006
+ value: external_exports.union([external_exports.string(), external_exports.number(), external_exports.array(external_exports.string())]).describe("The new value (array for fontFamily)")
19484
21007
  })).describe("Edits to apply"),
19485
21008
  regenerateCss: external_exports.boolean().optional().describe("Regenerate tokens.css from the result (default: true)")
19486
21009
  }, async (args) => {
19487
21010
  const root = needRoot();
19488
21011
  let tokens = await loadTokens(root);
19489
- for (const e of args.edits)
19490
- tokens = setTokenPath(tokens, e.path, e.value);
21012
+ for (const e of args.edits) {
21013
+ if (e.segments?.length)
21014
+ tokens = setTokenSegments(tokens, e.segments, e.value);
21015
+ else if (e.path)
21016
+ tokens = setTokenPath(tokens, e.path, e.value);
21017
+ }
19491
21018
  const validated = DesignTokensSchema.safeParse(tokens);
19492
21019
  if (!validated.success)
19493
21020
  return text(`Edit produced an invalid tokens document: ${validated.error.message}`, true);
19494
21021
  const regen = args.regenerateCss !== false;
19495
- await saveTokens(root, validated.data, regen);
19496
- return text(`Updated ${args.edits.length} token(s): ${args.edits.map((e) => e.path).join(", ")}${regen ? " and regenerated tokens.css" : ""}.`);
21022
+ await saveTokens(root, tokens, regen);
21023
+ const names = args.edits.map((e) => e.path ?? e.segments?.join(".") ?? "?").join(", ");
21024
+ return text(`Updated ${args.edits.length} token(s): ${names}${regen ? " and regenerated tokens.css" : ""}.`);
21025
+ }),
21026
+ tool2("apply_design_pack", `Apply a curated design pack (a full color+typography+spacing+radius+shadow vibe, light+dark) to the project design system and regenerate tokens.css. Pass packId for a bundled pack (${PACK_IDS}) OR an inline DTCG tokens document. mode: merge (override only the paths the pack defines, keep the rest incl. components \u2014 default), replace (swap the whole token tree, keep $meta/$components), palette (recolour + change font families only).`, {
21027
+ packId: external_exports.string().optional().describe('Bundled pack id, e.g. "premium-dark"'),
21028
+ tokens: DesignTokensSchema.optional().describe("Inline DTCG tokens to apply instead of a bundled pack"),
21029
+ name: external_exports.string().optional().describe("Display name when applying inline tokens"),
21030
+ mode: external_exports.enum(["merge", "replace", "palette"]).optional().describe("Apply strategy (default: merge)")
21031
+ }, async (args) => {
21032
+ const root = needRoot();
21033
+ const mode = args.mode ?? "merge";
21034
+ let packTokens;
21035
+ let info;
21036
+ if (args.packId) {
21037
+ const pack = getPack(args.packId);
21038
+ if (!pack)
21039
+ return text(`Unknown packId "${args.packId}". Bundled: ${PACK_IDS}.`, true);
21040
+ packTokens = pack.tokens;
21041
+ info = { id: pack.id, name: pack.name };
21042
+ } else if (args.tokens) {
21043
+ packTokens = args.tokens;
21044
+ info = { id: "inline", name: args.name ?? "Custom pack" };
21045
+ } else {
21046
+ return text("Provide either packId or tokens.", true);
21047
+ }
21048
+ const result = applyDesignPack(await loadTokens(root), packTokens, info, { mode });
21049
+ const validated = DesignTokensSchema.safeParse(result);
21050
+ if (!validated.success)
21051
+ return text(`Applying the pack produced an invalid document: ${validated.error.message}`, true);
21052
+ await saveTokens(root, result, true);
21053
+ return text(`Applied "${info.name}" (${mode}) and regenerated tokens.css.`);
19497
21054
  }),
19498
21055
  tool2("capture_element_styles", "Read the computed CSS of an element on the live preview by CSS selector (cheap \u2014 returns text, not a screenshot). Use to learn what styles/tokens an element currently uses before editing.", {
19499
21056
  selector: external_exports.string().describe("CSS selector of the element to inspect"),
@@ -19516,7 +21073,7 @@ function buildDesignTools(deps) {
19516
21073
  return text(`Preview announced: ${args.url}`);
19517
21074
  }),
19518
21075
  tool2("list_components", "List the design-system components recorded in tokens.json (name, source files, tokens used).", {}, async () => {
19519
- const comps = (await loadTokens(needRoot())).components ?? {};
21076
+ const comps = (await loadTokens(needRoot())).$components ?? {};
19520
21077
  const names = Object.keys(comps);
19521
21078
  if (!names.length)
19522
21079
  return text('No components recorded yet. Run the "Import Design System" skill to populate them.');
@@ -19529,12 +21086,14 @@ function buildDesignTools(deps) {
19529
21086
  })
19530
21087
  ];
19531
21088
  }
19532
- var STYLE_PROPS, text;
21089
+ var PACK_IDS, STYLE_PROPS, text;
19533
21090
  var init_design_tools = __esm({
19534
21091
  "../../packages/agent-core/dist/design-tools.js"() {
19535
21092
  "use strict";
19536
21093
  init_zod();
19537
- init_design_tokens();
21094
+ init_design_tokens2();
21095
+ init_dist3();
21096
+ PACK_IDS = PACKS.map((p) => p.id).join(", ");
19538
21097
  STYLE_PROPS = [
19539
21098
  "color",
19540
21099
  "background-color",
@@ -20471,7 +22030,7 @@ var init_agent_manager = __esm({
20471
22030
  init_dist();
20472
22031
  init_cron_tools();
20473
22032
  init_design_tools();
20474
- init_design_tokens();
22033
+ init_design_tokens2();
20475
22034
  init_narrator();
20476
22035
  init_plan_splitter();
20477
22036
  init_trace_store();
@@ -22129,24 +23688,41 @@ __export(dist_exports, {
22129
23688
  AgentManager: () => AgentManager,
22130
23689
  DESIGN_CLAUDE_MD: () => DESIGN_CLAUDE_MD,
22131
23690
  DESIGN_DIR: () => DESIGN_DIR,
23691
+ DTCG_TYPES: () => DTCG_TYPES,
22132
23692
  DesignTokensSchema: () => DesignTokensSchema,
23693
+ DtcgTokensSchema: () => DtcgTokensSchema,
22133
23694
  SessionStore: () => SessionStore,
22134
23695
  TOKENS_CSS_FILE: () => TOKENS_CSS_FILE,
22135
23696
  TOKENS_FILE: () => TOKENS_FILE,
23697
+ applyDesignPack: () => applyDesignPack,
22136
23698
  buildClaudeNarrationLlm: () => buildClaudeNarrationLlm,
23699
+ bumpVersion: () => bumpVersion,
23700
+ contrastRatio: () => contrastRatio,
23701
+ diffTokens: () => diffTokens,
22137
23702
  exportSession: () => exportSession,
23703
+ flattenForDisplay: () => flattenForDisplay,
22138
23704
  getTokenPath: () => getTokenPath,
23705
+ getTokenSegments: () => getTokenSegments,
22139
23706
  importSession: () => importSession,
23707
+ isToken: () => isToken,
22140
23708
  log: () => log,
23709
+ normalizeTokens: () => normalizeTokens,
23710
+ parseColorToRgb: () => parseColorToRgb,
22141
23711
  resolveOauthToken: () => resolveOauthToken,
22142
23712
  sanitizeProjectDir: () => sanitizeProjectDir,
22143
23713
  sessionDir: () => sessionDir,
22144
23714
  sessionFile: () => sessionFile,
22145
23715
  setTokenPath: () => setTokenPath,
23716
+ setTokenSegments: () => setTokenSegments,
23717
+ stringifyValue: () => stringifyValue,
23718
+ tokenCssVarName: () => tokenCssVarName,
22146
23719
  tokensToCss: () => tokensToCss,
22147
- transferSession: () => transferSession
23720
+ tokensToTailwindConfig: () => tokensToTailwindConfig,
23721
+ tokensToTailwindTheme: () => tokensToTailwindTheme,
23722
+ transferSession: () => transferSession,
23723
+ walkTokens: () => walkTokens
22148
23724
  });
22149
- var init_dist2 = __esm({
23725
+ var init_dist4 = __esm({
22150
23726
  "../../packages/agent-core/dist/index.js"() {
22151
23727
  "use strict";
22152
23728
  init_agent_manager();
@@ -22154,7 +23730,7 @@ var init_dist2 = __esm({
22154
23730
  init_session_usage();
22155
23731
  init_session_transfer();
22156
23732
  init_log();
22157
- init_design_tokens();
23733
+ init_design_tokens2();
22158
23734
  }
22159
23735
  });
22160
23736
 
@@ -42011,7 +43587,7 @@ import { join as join15 } from "node:path";
42011
43587
 
42012
43588
  // ../../packages/host-core/dist/agent-backend.js
42013
43589
  async function createClaudeCodeBackend(send2, onBrowserRequest, loadPluginRuntime2) {
42014
- const { AgentManager: AgentManager2, SessionStore: SessionStore2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
43590
+ const { AgentManager: AgentManager2, SessionStore: SessionStore2 } = await Promise.resolve().then(() => (init_dist4(), dist_exports));
42015
43591
  const manager2 = new AgentManager2(send2, onBrowserRequest);
42016
43592
  const store = new SessionStore2();
42017
43593
  const refreshPlugins = async (projectDir) => {
@@ -42437,7 +44013,7 @@ async function createBackend(engineId, send2, onBrowserRequest, resolver, loadPl
42437
44013
  }
42438
44014
 
42439
44015
  // ../../packages/host-core/dist/daemon-agent.js
42440
- init_dist2();
44016
+ init_dist4();
42441
44017
 
42442
44018
  // ../../packages/host-core/dist/plugin-tools.js
42443
44019
  import { existsSync as existsSync3 } from "node:fs";
@@ -43120,477 +44696,14 @@ import { readFileSync as readFileSync7 } from "node:fs";
43120
44696
  import { join as join14 } from "node:path";
43121
44697
 
43122
44698
  // ../../packages/host-core/dist/runners/resolve.js
44699
+ init_dist2();
43123
44700
  import { readFileSync as readFileSync5, existsSync as existsSync6, statSync, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
43124
44701
  import { homedir as homedir5 } from "node:os";
43125
44702
  import { join as join11 } from "node:path";
43126
44703
  import { createHash as createHash2 } from "node:crypto";
43127
44704
 
43128
- // ../../packages/shared/dist/ws-protocol.js
43129
- var MIRRORED_AGENT_EVENTS = /* @__PURE__ */ new Set([
43130
- "chat:stream",
43131
- "agent:tool_use",
43132
- "agent:tool_result",
43133
- // M4 H10 — co-viewers must see tool OUTPUT, not just the call
43134
- "agent:file_edit",
43135
- "chat:complete",
43136
- "chat:error",
43137
- "agent:status",
43138
- "agent:mode_changed",
43139
- // M4 H11 — co-viewer run-mode badge must flip on plan/edit
43140
- "agent:session_state",
43141
- // M4 H11 — co-viewer spinner must clear on idle
43142
- "agent:todos",
43143
- // plan sidebar — co-viewers see the live checklist
43144
- "agent:plan_sections",
43145
- // plan review — co-viewers see the sectioned plan
43146
- "agent:narration",
43147
- // live status strip — co-viewers see "what it's doing now"
43148
- "agent:preview_ready",
43149
- // co-viewers (incl. mobile) see the preview the moment it's ready
43150
- "agent:elicitation_complete",
43151
- // M5 — co-viewers clear a resolved url-mode card
43152
- "chat:echoed",
43153
- "chat:scheduled_fired"
43154
- // cron — co-viewers see the synthetic "Scheduled" user turn
43155
- // NOT mirrored: agent:capabilities (host-local model/MCP metadata — mirroring
43156
- // would stomp a co-viewer's own picker with the driver's host); session:forked
43157
- // and agent:context_usage are driver-only correlation/host-local replies.
43158
- ]);
43159
-
43160
- // ../../packages/shared/dist/plans.js
43161
- var NO_QUOTAS = { computeHours: 0, storageGb: 0, egressGb: 0 };
43162
- var NO_FEATURES = {
43163
- sync: false,
43164
- mobile: false,
43165
- cloudWorkspace: false,
43166
- cloudServer: false,
43167
- remoteAgents: false,
43168
- voice: false,
43169
- team: false,
43170
- parallelAgents: false,
43171
- advancedBrowser: false,
43172
- hosting: false,
43173
- plugins: false,
43174
- scheduling: false,
43175
- api: false,
43176
- sso: false,
43177
- seats: 1,
43178
- maxMachines: 1
43179
- };
43180
- var PLAN_CATALOG = [
43181
- {
43182
- id: "free",
43183
- name: "Free",
43184
- monthlyUsd: 0,
43185
- tagline: "Your machine, your phone, your voice.",
43186
- features: [
43187
- "Unlimited agent usage",
43188
- "Full IDE: editor, files, agent, browser tool",
43189
- "Voice mode",
43190
- "Mobile app \u2014 reach your computer from your phone",
43191
- "Cloud workspace \u2014 your machine and recent projects in one view",
43192
- "One machine",
43193
- "Deploy to your own machine or server",
43194
- "Community support"
43195
- ],
43196
- featurePolicy: { ...NO_FEATURES, voice: true, mobile: true, cloudWorkspace: true },
43197
- quotas: { ...NO_QUOTAS }
43198
- },
43199
- {
43200
- id: "standard",
43201
- name: "Pro",
43202
- monthlyUsd: 20,
43203
- tagline: "Your workspace, everywhere.",
43204
- features: [
43205
- "Everything in Free",
43206
- "Unlimited machines \u2014 run agents on all of them",
43207
- "Tesseract cloud server \u2014 a managed always-on agent in the cloud",
43208
- "Deploy to the cloud \u2014 your app on a *.tesseract.dev URL",
43209
- "Includes ~1 always-on service + 20 GB storage + 100 GB bandwidth (overage metered)",
43210
- "Sync settings across your devices",
43211
- "Email support"
43212
- ],
43213
- featurePolicy: {
43214
- ...NO_FEATURES,
43215
- sync: true,
43216
- mobile: true,
43217
- cloudWorkspace: true,
43218
- cloudServer: true,
43219
- remoteAgents: true,
43220
- voice: true,
43221
- hosting: true,
43222
- plugins: true,
43223
- scheduling: true,
43224
- maxMachines: 0
43225
- },
43226
- // ~1 small always-on service (~720 compute-hours/mo, rounded) + 20 GB storage + 100 GB egress.
43227
- quotas: { computeHours: 750, storageGb: 20, egressGb: 100 }
43228
- },
43229
- {
43230
- id: "pro",
43231
- name: "Team",
43232
- monthlyUsd: 40,
43233
- perSeat: true,
43234
- tagline: "For teams shipping together.",
43235
- features: [
43236
- "Everything in Pro, per seat",
43237
- "Team seats + shared workspaces",
43238
- "Parallel agents",
43239
- "Advanced browser automation",
43240
- "API access",
43241
- "SSO, audit logs, centralized billing",
43242
- "Pooled cloud hosting \u2014 bigger shared quota",
43243
- "Priority support"
43244
- ],
43245
- featurePolicy: {
43246
- sync: true,
43247
- mobile: true,
43248
- cloudWorkspace: true,
43249
- cloudServer: true,
43250
- remoteAgents: true,
43251
- voice: true,
43252
- team: true,
43253
- parallelAgents: true,
43254
- advancedBrowser: true,
43255
- hosting: true,
43256
- plugins: true,
43257
- scheduling: true,
43258
- api: true,
43259
- sso: true,
43260
- seats: 2,
43261
- maxMachines: 0
43262
- },
43263
- // Pooled across the team — ~4× Pro's starter quota.
43264
- quotas: { computeHours: 3e3, storageGb: 100, egressGb: 500 }
43265
- }
43266
- ];
43267
-
43268
- // ../../packages/shared/dist/settings.js
43269
- var MODEL_OPTIONS = [
43270
- { id: "claude-opus-4-8", label: "Claude Opus 4.8" },
43271
- { id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
43272
- { id: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5" }
43273
- ];
43274
-
43275
- // ../../packages/shared/dist/engines.js
43276
- var ENGINE_CATALOG = {
43277
- "claude-code": {
43278
- id: "claude-code",
43279
- label: "Claude Code",
43280
- description: "Anthropic's Claude Code \u2014 the default engine, deepest tool + browser integration.",
43281
- cliBinary: "claude",
43282
- // Claude's token is injected via CLAUDE_CODE_OAUTH_TOKEN, so oauth needs no auth file.
43283
- supportedModes: ["oauth", "apiKey", "localCli"],
43284
- apiKeyEnv: "ANTHROPIC_API_KEY",
43285
- models: MODEL_OPTIONS,
43286
- capabilities: { permissionGating: true, browserControl: true, liveRunMode: true, resume: true, fork: true, contextUsage: true, scheduling: true },
43287
- homepageUrl: "https://docs.claude.com/en/docs/claude-code",
43288
- installCommand: "npm install -g @anthropic-ai/claude-code",
43289
- installHint: "Bundled with the app; install the standalone CLI for local-instance mode."
43290
- },
43291
- "openai-codex": {
43292
- id: "openai-codex",
43293
- label: "OpenAI Codex",
43294
- description: "OpenAI's Codex CLI. Sign in with ChatGPT or use an API key.",
43295
- cliBinary: "codex",
43296
- supportedModes: ["oauth", "apiKey", "localCli"],
43297
- apiKeyEnv: "OPENAI_API_KEY",
43298
- authFileRel: "auth.json",
43299
- // under $CODEX_HOME
43300
- models: [
43301
- { id: "gpt-5.5-codex", label: "GPT-5.5 Codex" },
43302
- { id: "gpt-5.5", label: "GPT-5.5" }
43303
- ],
43304
- capabilities: { permissionGating: false, browserControl: false, liveRunMode: false, resume: true },
43305
- homepageUrl: "https://developers.openai.com/codex/cli",
43306
- installCommand: "npm install -g @openai/codex",
43307
- installHint: "npm i -g @openai/codex (or brew install codex)"
43308
- },
43309
- opencode: {
43310
- id: "opencode",
43311
- label: "OpenCode",
43312
- description: "Open-source agent over 75+ providers. Log in per provider.",
43313
- cliBinary: "opencode",
43314
- supportedModes: ["oauth", "apiKey", "localCli"],
43315
- // OpenCode reads provider keys from env / its own auth.json; no single apiKeyEnv.
43316
- authFileRel: "auth.json",
43317
- // under ~/.local/share/opencode
43318
- models: [],
43319
- // provider+model is configured inside OpenCode; "" ⇒ its default
43320
- capabilities: { permissionGating: false, browserControl: false, liveRunMode: false, resume: true },
43321
- homepageUrl: "https://opencode.ai",
43322
- installCommand: "npm install -g opencode-ai",
43323
- installHint: "npm i -g opencode-ai (see opencode.ai/docs)"
43324
- },
43325
- "gemini-cli": {
43326
- id: "gemini-cli",
43327
- label: "Gemini CLI",
43328
- description: "Google's Gemini CLI. Sign in with Google or use a Gemini API key.",
43329
- cliBinary: "gemini",
43330
- supportedModes: ["oauth", "apiKey", "localCli"],
43331
- apiKeyEnv: "GEMINI_API_KEY",
43332
- models: [
43333
- { id: "gemini-3.1-pro", label: "Gemini 3.1 Pro" },
43334
- { id: "gemini-2.5-flash", label: "Gemini 2.5 Flash" }
43335
- ],
43336
- capabilities: { permissionGating: false, browserControl: false, liveRunMode: false, resume: false },
43337
- homepageUrl: "https://github.com/google-gemini/gemini-cli",
43338
- installCommand: "npm install -g @google/gemini-cli",
43339
- installHint: "npm i -g @google/gemini-cli"
43340
- },
43341
- openclaw: {
43342
- id: "openclaw",
43343
- label: "OpenClaw",
43344
- description: "OpenClaw runtime \u2014 runs your installed channels, model providers, and plugins natively.",
43345
- cliBinary: "openclaw",
43346
- // OpenClaw manages its own provider auth (`openclaw onboard` / openclaw.json), so the
43347
- // only mode is "use the installed, already-onboarded CLI" — like OpenCode.
43348
- supportedModes: ["localCli"],
43349
- models: [],
43350
- // provider+model is configured inside OpenClaw; '' ⇒ its default
43351
- capabilities: { permissionGating: false, browserControl: false, liveRunMode: false, resume: false },
43352
- homepageUrl: "https://docs.openclaw.ai",
43353
- installCommand: "npm install -g openclaw",
43354
- installHint: "npm i -g openclaw, then run `openclaw onboard` (see docs.openclaw.ai)"
43355
- }
43356
- };
43357
- var ENGINE_IDS = Object.keys(ENGINE_CATALOG);
43358
- function engineById(id) {
43359
- return ENGINE_CATALOG[id];
43360
- }
43361
-
43362
- // ../../packages/shared/dist/providers.js
43363
- var PROVIDER_CATALOG = {
43364
- anthropic: {
43365
- id: "anthropic",
43366
- label: "Anthropic",
43367
- description: "Claude models, direct from Anthropic. The native backend for Claude Code.",
43368
- baseUrl: "https://api.anthropic.com",
43369
- api: "anthropic-messages",
43370
- claudeNative: true,
43371
- authEnvVars: ["ANTHROPIC_API_KEY"],
43372
- authModes: ["oauth", "apiKey"],
43373
- models: [
43374
- { id: "claude-opus-4-8", label: "Claude Opus 4.8", role: "main" },
43375
- { id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6", role: "main" },
43376
- { id: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5", role: "fast" }
43377
- ],
43378
- homepageUrl: "https://docs.claude.com/en/docs/about-claude/models"
43379
- },
43380
- openai: {
43381
- id: "openai",
43382
- label: "OpenAI",
43383
- description: "OpenAI models. The native backend for the Codex engine.",
43384
- baseUrl: "https://api.openai.com/v1",
43385
- api: "openai-completions",
43386
- claudeNative: false,
43387
- authEnvVars: ["OPENAI_API_KEY"],
43388
- authModes: ["oauth", "apiKey"],
43389
- models: [
43390
- { id: "gpt-5.5-codex", label: "GPT-5.5 Codex", role: "main" },
43391
- { id: "gpt-5.5", label: "GPT-5.5", role: "main" }
43392
- ],
43393
- homepageUrl: "https://platform.openai.com/docs/models"
43394
- },
43395
- google: {
43396
- id: "google",
43397
- label: "Google Gemini",
43398
- description: "Gemini models. The native backend for the Gemini engine.",
43399
- baseUrl: "https://generativelanguage.googleapis.com",
43400
- api: "gemini",
43401
- claudeNative: false,
43402
- authEnvVars: ["GEMINI_API_KEY"],
43403
- authModes: ["oauth", "apiKey"],
43404
- models: [
43405
- { id: "gemini-3.1-pro", label: "Gemini 3.1 Pro", role: "main" },
43406
- { id: "gemini-2.5-flash", label: "Gemini 2.5 Flash", role: "fast" }
43407
- ],
43408
- homepageUrl: "https://ai.google.dev/gemini-api/docs/models"
43409
- },
43410
- openrouter: {
43411
- id: "openrouter",
43412
- label: "OpenRouter",
43413
- description: "One key, hundreds of models. Exposes an Anthropic-compatible route \u2014 no proxy needed for Claude Code.",
43414
- // OpenAI-style base; the Anthropic-compatible base is `…/api` (no `/v1`).
43415
- baseUrl: "https://openrouter.ai/api/v1",
43416
- anthropicBaseUrl: "https://openrouter.ai/api",
43417
- api: "openai-completions",
43418
- claudeNative: true,
43419
- authEnvVars: ["OPENROUTER_API_KEY"],
43420
- headers: {
43421
- "HTTP-Referer": "https://app.tesseract.dev",
43422
- "X-Title": "Tesseract"
43423
- },
43424
- authModes: ["apiKey"],
43425
- // Any OpenRouter slug is valid; these are stable starters (free entry in UI).
43426
- models: [
43427
- { id: "deepseek/deepseek-chat", label: "DeepSeek Chat", role: "fast" },
43428
- { id: "deepseek/deepseek-r1", label: "DeepSeek R1", role: "main" },
43429
- { id: "google/gemini-2.5-flash", label: "Gemini 2.5 Flash", role: "fast" },
43430
- { id: "google/gemini-2.5-pro", label: "Gemini 2.5 Pro", role: "main" }
43431
- ],
43432
- homepageUrl: "https://openrouter.ai/docs"
43433
- },
43434
- ollama: {
43435
- id: "ollama",
43436
- label: "Ollama (local)",
43437
- description: "Run open models locally. No API key. Models are discovered from your running Ollama.",
43438
- baseUrl: "http://127.0.0.1:11434",
43439
- api: "ollama",
43440
- claudeNative: false,
43441
- authEnvVars: [],
43442
- authModes: ["apiKey"],
43443
- // optional bearer for remote Ollama; usually none
43444
- models: [],
43445
- dynamicModels: true,
43446
- homepageUrl: "https://ollama.com",
43447
- installCommand: "curl -fsSL https://ollama.com/install.sh | sh"
43448
- },
43449
- deepseek: {
43450
- id: "deepseek",
43451
- label: "DeepSeek",
43452
- description: "DeepSeek Chat + Reasoner. Cheap and capable. Reached via the proxy for Claude Code.",
43453
- baseUrl: "https://api.deepseek.com",
43454
- api: "openai-completions",
43455
- claudeNative: false,
43456
- authEnvVars: ["DEEPSEEK_API_KEY"],
43457
- authModes: ["apiKey"],
43458
- models: [
43459
- { id: "deepseek-chat", label: "DeepSeek Chat", role: "fast" },
43460
- { id: "deepseek-reasoner", label: "DeepSeek Reasoner", role: "main" }
43461
- ],
43462
- homepageUrl: "https://api-docs.deepseek.com"
43463
- },
43464
- moonshot: {
43465
- id: "moonshot",
43466
- label: "Kimi (Moonshot)",
43467
- description: "Kimi K2 models. Use the coding endpoint (Anthropic-compatible, no proxy) or the OpenAI endpoint.",
43468
- // Default to the OpenAI-style endpoint; the per-credential `baseUrl` can switch
43469
- // to the Anthropic-compatible coding endpoint below.
43470
- baseUrl: "https://api.moonshot.ai/v1",
43471
- anthropicBaseUrl: "https://api.kimi.com/coding/",
43472
- api: "openai-completions",
43473
- claudeNative: true,
43474
- authEnvVars: ["MOONSHOT_API_KEY", "KIMI_API_KEY"],
43475
- authModes: ["apiKey"],
43476
- models: [
43477
- { id: "kimi-code", label: "Kimi Code (coding endpoint)", role: "main" },
43478
- { id: "kimi-k2.5", label: "Kimi K2.5", role: "main" },
43479
- { id: "kimi-k2-thinking", label: "Kimi K2 Thinking", role: "main" }
43480
- ],
43481
- homepageUrl: "https://platform.moonshot.ai/docs"
43482
- },
43483
- "custom-openai": {
43484
- id: "custom-openai",
43485
- label: "Custom (OpenAI-compatible)",
43486
- description: "Any OpenAI-compatible endpoint (LM Studio, llama.cpp, vLLM, a private gateway). Set the base URL per key.",
43487
- baseUrl: "",
43488
- api: "openai-completions",
43489
- claudeNative: false,
43490
- authEnvVars: ["OPENAI_API_KEY"],
43491
- authModes: ["apiKey"],
43492
- models: [],
43493
- homepageUrl: "https://platform.openai.com/docs/api-reference"
43494
- },
43495
- litellm: {
43496
- id: "litellm",
43497
- label: "LiteLLM Proxy",
43498
- description: "Your LiteLLM proxy fronting 100+ providers. Point it at the anthropic route for direct Claude Code use.",
43499
- baseUrl: "",
43500
- anthropicBaseUrl: "",
43501
- api: "openai-completions",
43502
- // Configurable: LiteLLM can expose an Anthropic-shaped route. Treated as
43503
- // claudeNative so users can point Claude Code straight at it.
43504
- claudeNative: true,
43505
- authEnvVars: ["LITELLM_API_KEY"],
43506
- authModes: ["apiKey"],
43507
- models: [],
43508
- homepageUrl: "https://docs.litellm.ai/docs/simple_proxy"
43509
- }
43510
- };
43511
- var PROVIDER_IDS = Object.keys(PROVIDER_CATALOG);
43512
- var NATIVE_PROVIDER_IDS = ["anthropic", "openai", "google"];
43513
- function providerById(id) {
43514
- return PROVIDER_CATALOG[id];
43515
- }
43516
-
43517
- // ../../packages/shared/dist/runtimes.js
43518
- var RUNTIME_CATALOG = [
43519
- ...ENGINE_IDS.map((id) => ({
43520
- id,
43521
- label: ENGINE_CATALOG[id].label,
43522
- cliBinary: ENGINE_CATALOG[id].cliBinary,
43523
- installCommand: ENGINE_CATALOG[id].installCommand,
43524
- kind: "engine"
43525
- })),
43526
- { id: "ollama", label: "Ollama", cliBinary: "ollama", installCommand: "curl -fsSL https://ollama.com/install.sh | sh", kind: "tool" },
43527
- { id: "ccr", label: "Claude Code Router", cliBinary: "ccr", installCommand: "npm install -g @musistudio/claude-code-router", kind: "tool" }
43528
- ];
43529
- var RUNTIME_IDS = RUNTIME_CATALOG.map((r) => r.id);
43530
-
43531
- // ../../packages/shared/dist/rotation.js
43532
- var COOLDOWN_BASE_MS = 6e4;
43533
- var COOLDOWN_MAX_MS = 36e5;
43534
- function refreshCredentials(creds, now) {
43535
- return creds.map((c) => {
43536
- if (c.status === "cooldown" && (c.cooldownUntil == null || c.cooldownUntil <= now)) {
43537
- return { ...c, status: "active", cooldownUntil: void 0 };
43538
- }
43539
- if (c.status === "active" && c.expiresAt != null && c.expiresAt <= now) {
43540
- return { ...c, status: "expired" };
43541
- }
43542
- return c;
43543
- });
43544
- }
43545
- function selectRotatable(items, now, isUsable = () => true) {
43546
- const usable = refreshCredentials(items, now).filter((c) => c.status === "active" && (c.expiresAt == null || c.expiresAt > now) && isUsable(c));
43547
- if (usable.length === 0)
43548
- return void 0;
43549
- return usable.sort((a, b) => a.priority - b.priority || (a.lastUsedAt ?? 0) - (b.lastUsedAt ?? 0))[0];
43550
- }
43551
- function classifyError(raw) {
43552
- const s = raw.toLowerCase();
43553
- if (/\b429\b|rate[ _-]?limit|too many requests/.test(s))
43554
- return "rate_limit";
43555
- if (/quota|insufficient[_ ]?quota|credit|billing|payment required|\b402\b|usage limit|exceeded your/.test(s))
43556
- return "quota_exceeded";
43557
- if (/expired|token (?:has )?expired|refresh|re-?authenticate|session expired/.test(s))
43558
- return "auth_expired";
43559
- if (/\b401\b|\b403\b|invalid (?:api )?key|unauthorized|invalid token|authentication/.test(s))
43560
- return "invalid_key";
43561
- if (/\beai_again\b|\benotfound\b|getaddrinfo|network is unreachable|\benetunreach\b|\benetdown\b|offline|no address associated|dns/.test(s))
43562
- return "network_down";
43563
- if (/\beconnreset\b|\beconnrefused\b|\betimedout\b|\bepipe\b|socket hang ?up|connection (?:closed|reset|error|aborted)|\b50[0234]\b|\b529\b|overloaded|service unavailable|bad gateway|gateway time-?out|temporarily unavailable/.test(s))
43564
- return "transient";
43565
- return "unknown";
43566
- }
43567
- function recordFailure(creds, id, errorCode, now, opts) {
43568
- if (errorCode === "unknown" || errorCode === "transient" || errorCode === "network_down") {
43569
- return { next: creds, advanced: false };
43570
- }
43571
- let advanced = false;
43572
- const next = creds.map((c) => {
43573
- if (c.id !== id)
43574
- return c;
43575
- advanced = true;
43576
- const consecutiveFailures = (c.consecutiveFailures ?? 0) + 1;
43577
- if (errorCode === "auth_expired") {
43578
- return { ...c, status: "expired", lastErrorCode: errorCode, consecutiveFailures };
43579
- }
43580
- if (errorCode === "invalid_key") {
43581
- return { ...c, status: "revoked", lastErrorCode: errorCode, consecutiveFailures };
43582
- }
43583
- const backoff = Math.min(COOLDOWN_BASE_MS * 2 ** (consecutiveFailures - 1), COOLDOWN_MAX_MS);
43584
- const cooldownUntil = opts?.cooldownUntil ?? now + backoff;
43585
- return { ...c, status: "cooldown", cooldownUntil, lastErrorCode: errorCode, consecutiveFailures };
43586
- });
43587
- return { next, advanced };
43588
- }
43589
- function recordSuccess(creds, id, now) {
43590
- return creds.map((c) => c.id === id ? { ...c, status: "active", cooldownUntil: void 0, consecutiveFailures: 0, lastUsedAt: now, lastErrorCode: void 0 } : c);
43591
- }
43592
-
43593
44705
  // ../../packages/host-core/dist/runners/proxy-router.js
44706
+ init_dist2();
43594
44707
  import { spawn as spawn3, execFile as execFile2, execSync as execSync2 } from "node:child_process";
43595
44708
  import { createRequire as createRequire2 } from "node:module";
43596
44709
  import { randomUUID as randomUUID4, createHash } from "node:crypto";
@@ -43870,6 +44983,7 @@ function resolveOverrideEngineEnv() {
43870
44983
  }
43871
44984
 
43872
44985
  // ../../packages/host-core/dist/runners/pool.js
44986
+ init_dist2();
43873
44987
  import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, existsSync as existsSync7, statSync as statSync2, mkdirSync as mkdirSync5, chmodSync as chmodSync2, renameSync as renameSync4 } from "node:fs";
43874
44988
  import { join as join12 } from "node:path";
43875
44989
  import { randomUUID as randomUUID5 } from "node:crypto";
@@ -44055,6 +45169,7 @@ function setActiveConfig(id) {
44055
45169
  }
44056
45170
 
44057
45171
  // ../../packages/host-core/dist/daemon-engine-spawn.js
45172
+ init_dist2();
44058
45173
  import { execFileSync } from "node:child_process";
44059
45174
  import { homedir as homedir6 } from "node:os";
44060
45175
  import { join as join13 } from "node:path";
@@ -49287,7 +50402,7 @@ function routeInboundLinkFrame(frame) {
49287
50402
  }
49288
50403
 
49289
50404
  // ../../packages/host-core/dist/control-link.js
49290
- init_dist2();
50405
+ init_dist4();
49291
50406
 
49292
50407
  // ../../packages/host-core/dist/pty-manager.js
49293
50408
  import { existsSync as existsSync14 } from "node:fs";
@@ -49531,6 +50646,7 @@ function clampDim(v, dflt) {
49531
50646
  }
49532
50647
 
49533
50648
  // ../../packages/host-core/dist/control-link.js
50649
+ init_dist2();
49534
50650
  var SERVER_HOST_ID = "server";
49535
50651
  var cfg = null;
49536
50652
  var deviceId = "";
@@ -50527,6 +51643,7 @@ function stopControlLink() {
50527
51643
  }
50528
51644
 
50529
51645
  // ../../packages/host-core/dist/local-server.js
51646
+ init_dist2();
50530
51647
  var connSeq = 0;
50531
51648
  async function startLocalServer(opts) {
50532
51649
  const log3 = opts.log ?? (() => {