@tangle-network/sandbox-ui 0.23.2 → 0.23.4

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.
package/dist/chat.d.ts CHANGED
@@ -3,9 +3,18 @@ export { AgentTimeline, AgentTimelineArtifactItem, AgentTimelineCustomItem, Agen
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as React from 'react';
5
5
  import { M as ModelInfo } from './model-picker-DUfMTQo5.js';
6
- import { e as HarnessType } from './harness-picker-C1W3rTeb.js';
6
+ import { e as HarnessType } from './harness-picker-ppDe7ap-.js';
7
7
 
8
- type ReasoningLevel = "auto" | "low" | "medium" | "high";
8
+ /**
9
+ * Thinking-effort ladder — the superset of the per-harness reasoning scales so
10
+ * one control covers every backend. Consumers map each level onto what the
11
+ * chosen harness/model supports (and degrade unsupported ones):
12
+ * - OpenAI / Codex reasoning_effort: minimal · low · medium · high · xhigh
13
+ * - Anthropic (Claude) extended thinking: … · high · max
14
+ * - Claude Code: … · high · max · ultracode
15
+ * - generic: low · medium · high
16
+ */
17
+ type ReasoningLevel = "auto" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | "ultracode";
9
18
  interface ReasoningLevelOption {
10
19
  value: ReasoningLevel;
11
20
  label: string;
package/dist/chat.js CHANGED
@@ -16,9 +16,9 @@ import {
16
16
  modelProvider,
17
17
  snapHarnessToModel,
18
18
  snapModelToHarness
19
- } from "./chunk-TAAYDQGM.js";
20
- import "./chunk-ESRYVGHF.js";
21
- import "./chunk-4KAPMTPU.js";
19
+ } from "./chunk-KANKBACI.js";
20
+ import "./chunk-HXIYUQN2.js";
21
+ import "./chunk-JDMX4HHN.js";
22
22
  import "./chunk-EI44GEQ5.js";
23
23
  export {
24
24
  AgentSessionControls,
@@ -0,0 +1,253 @@
1
+ import {
2
+ moonshot_default
3
+ } from "./chunk-JDMX4HHN.js";
4
+ import {
5
+ cn
6
+ } from "./chunk-EI44GEQ5.js";
7
+
8
+ // src/dashboard/backend-selector.tsx
9
+ import { ChevronDown } from "lucide-react";
10
+ import * as Select from "@radix-ui/react-select";
11
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
+ function BackendSelector({
13
+ backends,
14
+ selected,
15
+ onChange,
16
+ label = "Model",
17
+ placeholder = "Select a model",
18
+ className
19
+ }) {
20
+ const current = backends.find((b) => b.type === selected);
21
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-1.5", className), children: [
22
+ label && /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground uppercase tracking-[0.06em]", children: label }),
23
+ /* @__PURE__ */ jsxs(Select.Root, { value: selected, onValueChange: onChange, children: [
24
+ /* @__PURE__ */ jsxs(
25
+ Select.Trigger,
26
+ {
27
+ className: cn(
28
+ "flex w-full items-center justify-between gap-2 rounded-[var(--radius-md)]",
29
+ "border border-border bg-card",
30
+ "px-3 py-2.5 text-sm text-left",
31
+ "transition-colors duration-[var(--transition-fast)]",
32
+ "hover:border-primary/20 hover:bg-accent/30",
33
+ "focus:outline-none focus:border-primary/30",
34
+ "data-[state=open]:border-primary/30 data-[state=open]:bg-accent/30"
35
+ ),
36
+ children: [
37
+ /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: current ? /* @__PURE__ */ jsxs(Fragment, { children: [
38
+ current.icon,
39
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 truncate", children: [
40
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: current.label }),
41
+ current.description && /* @__PURE__ */ jsx("span", { className: "ml-2 text-xs text-muted-foreground", children: current.description })
42
+ ] })
43
+ ] }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder }) }),
44
+ /* @__PURE__ */ jsx(Select.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-[var(--transition-fast)] data-[state=open]:rotate-180" }) })
45
+ ]
46
+ }
47
+ ),
48
+ /* @__PURE__ */ jsx(Select.Portal, { children: /* @__PURE__ */ jsx(
49
+ Select.Content,
50
+ {
51
+ position: "popper",
52
+ sideOffset: 4,
53
+ className: cn(
54
+ "z-50 w-[var(--radix-select-trigger-width)] overflow-hidden",
55
+ "rounded-[var(--radius-md)] border border-border",
56
+ "bg-card shadow-[var(--shadow-dropdown)]",
57
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
58
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
59
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
60
+ "data-[side=bottom]:slide-in-from-top-1"
61
+ ),
62
+ children: /* @__PURE__ */ jsx(Select.Viewport, { className: "p-1", children: backends.map((backend) => /* @__PURE__ */ jsxs(
63
+ Select.Item,
64
+ {
65
+ value: backend.type,
66
+ className: cn(
67
+ "relative flex cursor-pointer select-none items-start gap-2.5 rounded-[var(--radius-sm)]",
68
+ "px-3 py-2.5 text-sm outline-none",
69
+ "transition-colors duration-[var(--transition-fast)]",
70
+ "hover:bg-accent/50 focus:bg-accent/50",
71
+ "data-[state=checked]:bg-[var(--accent-surface-soft)] data-[state=checked]:text-[var(--brand-primary)]"
72
+ ),
73
+ children: [
74
+ backend.icon && /* @__PURE__ */ jsx("span", { className: "mt-0.5 shrink-0", children: backend.icon }),
75
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col", children: [
76
+ /* @__PURE__ */ jsx(Select.ItemText, { children: /* @__PURE__ */ jsx("span", { className: "font-medium", children: backend.label }) }),
77
+ backend.description && /* @__PURE__ */ jsx("span", { className: "mt-0.5 text-xs text-muted-foreground data-[state=checked]:text-[var(--accent-text)]", children: backend.description })
78
+ ] })
79
+ ]
80
+ },
81
+ backend.type
82
+ )) })
83
+ }
84
+ ) })
85
+ ] })
86
+ ] });
87
+ }
88
+
89
+ // src/dashboard/harness-logo.tsx
90
+ import { Bot, Plug, Terminal } from "lucide-react";
91
+
92
+ // node_modules/.pnpm/@lobehub+icons-static-svg@1.90.0/node_modules/@lobehub/icons-static-svg/icons/amp.svg
93
+ var amp_default = 'data:image/svg+xml,<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Amp</title><path d="M15.087 23.18L12.03 24l-2.097-7.823-5.738 5.738-2.251-2.251 5.718-5.719-7.769-2.082.82-3.057 11.294 3.08 3.08 11.295z"></path><path d="M19.505 18.762l-3.057.82-2.564-9.573-9.572-2.564.819-3.057 11.295 3.079 3.08 11.295z"></path><path d="M23.893 14.374l-3.057.82-2.565-9.572L8.7 3.057 9.52 0l11.295 3.08 3.079 11.294z"></path></svg>';
94
+
95
+ // node_modules/.pnpm/@lobehub+icons-static-svg@1.90.0/node_modules/@lobehub/icons-static-svg/icons/claudecode.svg
96
+ var claudecode_default = 'data:image/svg+xml,<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude Code</title><path clip-rule="evenodd" d="M20.998 10.949H24v3.102h-3v3.028h-1.487V20H18v-2.921h-1.487V20H15v-2.921H9V20H7.488v-2.921H6V20H4.487v-2.921H3V14.05H0V10.95h3V5h17.998v5.949zM6 10.949h1.488V8.102H6v2.847zm10.51 0H18V8.102h-1.49v2.847z"></path></svg>';
97
+
98
+ // node_modules/.pnpm/@lobehub+icons-static-svg@1.90.0/node_modules/@lobehub/icons-static-svg/icons/codex.svg
99
+ var codex_default = 'data:image/svg+xml,<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Codex</title><path clip-rule="evenodd" d="M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z"></path></svg>';
100
+
101
+ // node_modules/.pnpm/@lobehub+icons-static-svg@1.90.0/node_modules/@lobehub/icons-static-svg/icons/hermesagent.svg
102
+ var hermesagent_default = 'data:image/svg+xml,<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Hermes Agent</title><path d="M5.938 12.835c.127-.039.285.02.373.143.028.038.036.092.046.14.003.014-.02.033-.04.05-.124-.098-.24-.194-.354-.291-.011-.01-.016-.027-.025-.042zM8.396 9.412c.195-.032.39-.06.588-.05a.54.54 0 01.148.026c.202.071.402.147.601.224.028.01.05.036.075.055l-.013.027a9.203 9.203 0 01-.26-.089c-.115-.038-.213-.077-.315-.098-.25-.05-.25-.046-.292-.014l.574.144c.275.139.55.276.823.417.042.022.09.057.107.098.026.06.063.076.117.072.066-.006.132-.017.213-.027l-.04.086c.051.08.142.02.216.064-.074.13-.247.09-.334.199l.061.074-.12.087c0 .106-.038.168-.306.243l.026.085-.196.042.07.124h-.25l-.007.137c-.081-.01-.161-.018-.244-.027l-.053.123c-.027-.008-.052-.011-.073-.023-.067-.038-.128-.056-.195.006-.019.017-.063.014-.093.008-.026-.006-.05-.029-.07-.042-.11.095-.11.095-.208.003-.057.046-.12.074-.186.011-.063.027-.123-.02-.178-.014-.07.007-.097-.035-.133-.07l-.13.033c-.013-.236-.194-.19-.34-.203.005-.072.05-.092.095-.094a.474.474 0 01.159.022c.164.05.32.12.496.138.203.021.405.029.601-.015.265-.059.52-.149.707-.365.049-.056.083-.127.117-.195.019-.038.02-.084-.02-.116a1.397 1.397 0 00-.382-.217c.024.12-.031.182-.115.221 0 .014-.004.025 0 .03.08.115.084.16-.007.267a1.39 1.39 0 01-.218.211.477.477 0 01-.641-.05 1.36 1.36 0 01-.133-.152c-.078-.107-.076-.108-.033-.236-.165-.08-.128-.226-.104-.364.008-.05.028-.096.049-.163-.04.014-.067.017-.087.032a.897.897 0 00-.316.357c-.007.016-.01.034-.02.047-.012.015-.034.038-.045.035-.02-.006-.037-.027-.05-.045-.008-.012-.007-.032-.012-.057h-.126l.053-.172a14.82 14.82 0 00-.039-.049l.11-.284c-.06.026-.091.044-.124.051-.03.007-.064 0-.095 0 0-.031-.01-.07.004-.092.149-.22.305-.428.593-.476z"></path><path d="M8.06 10.788c-.003-.038-.004-.075.037-.062.016.006.034.048.028.067-.01.04-.038.032-.064-.005z"></path><path clip-rule="evenodd" d="M11.981.009c.226-.012.453-.011.679 0 .247.01.495.024.74.062.401.064.798.157 1.19.273.463.138.92.299 1.356.511a7.31 7.31 0 012.948 2.642c.292.469.536.963.739 1.479.219.556.446 1.11.623 1.683.204.654.329 1.326.458 1.997.097.504.182 1.01.29 1.511.156.722.329 1.44.494 2.16.186.812.4 1.615.63 2.415.102.355.193.713.282 1.072.11.436.202.876.254 1.323.031.278.066.557.073.837a7.56 7.56 0 01-.017.88c-.037.413-.1.818-.226 1.212a5.017 5.017 0 01-.915 1.649l-.13.156.018.023c.043-.023.088-.041.127-.068.2-.138.373-.307.531-.49.4-.46.721-.973.975-1.529a3.59 3.59 0 00.325-1.72c-.024-.424-.097-.834-.3-1.213-.013-.027-.015-.06-.03-.121.05.035.082.048.101.072.107.13.22.258.315.398.33.494.46 1.052.486 1.64a3.75 3.75 0 01-.47 1.97c-.36.655-.887 1.14-1.526 1.506-.193.111-.394.21-.595.308-.157.078-.248.211-.318.365a.522.522 0 00-.033.406.359.359 0 01.013.139c-.005.077-.077.155-.14.162-.054.006-.125-.043-.15-.116a1.206 1.206 0 01-.06-.233c-.04-.314-.155-.6-.308-.87a3.906 3.906 0 00-.73-.91 2.129 2.129 0 00-.897-.524 4.093 4.093 0 00-.692-.131c-.075-.008-.15-.04-.22.01.18.06.363.11.538.18.434.173.82.43 1.18.728.308.255.58.543.794.884.098.155.186.315.227.496.027.123.042.25.067.375.013.062-.002.109-.053.144-.047.033-.122.034-.163-.01a.455.455 0 01-.08-.14c-.03-.073-.038-.159-.078-.225a7.314 7.314 0 00-1.423-1.664c-.16-.137-.329-.26-.537-.323-.376-.114-.753-.203-1.15-.154-.213.025-.427.032-.64.053a1.6 1.6 0 00-.736.278 5.14 5.14 0 00-.834.72c-.329.342-.642.699-.955 1.055-.136.155-.264.319-.314.531a5.227 5.227 0 00-.012.051.096.096 0 01-.09.076h-.31c-.046 0-.082-.048-.072-.094.023-.108.045-.216.07-.324.075-.325.19-.635.368-.917.024-.039.04-.088.104-.08l.01.049.027.077c.28-.435.571-.834.996-1.135.283-.204.584-.378.89-.55a.196.196 0 00-.098-.002c-.162.043-.325.084-.485.134-.402.124-.764.33-1.11.566-.147.1-.298.193-.414.333a7.314 7.314 0 00-1.07 1.767.845.845 0 00-.04.12.075.075 0 01-.072.056h-.494c-.04 0-.062-.051-.036-.082.123-.14.246-.282.377-.415.275-.281.58-.532.777-.884.027-.048.063-.09.095-.135.238-.333.54-.607.818-.902.082-.086.175-.16.26-.24.029-.027.053-.057.079-.085l-.018-.025-.135.041c-.034.017-.07.031-.102.05-.248.144-.494.292-.743.433-.408.23-.825.439-1.209.711-.281.2-.591.358-.889.533-.02.012-.044.015-.08.028-.015-.135.143-.201.108-.336-.033.014-.064.02-.085.038-.111.096-.227.19-.328.296-.148.157-.284.325-.425.488-.125.143-.25.286-.373.431A.153.153 0 019.89 24H8.762a.316.316 0 00.016-.042c.028-.09.085-.172.083-.28-.091-.018-.162.001-.212.077a4.45 4.45 0 00-.136.215c-.01.016-.024.03-.042.03h-.093c-.019 0-.029-.022-.017-.037.071-.088.14-.178.209-.268.001-.002-.006-.012-.012-.024-.014.004-.03.006-.045.013-.176.09-.352.181-.527.274a.363.363 0 01-.168.042H5.202c-.026 0-.039-.036-.019-.053.21-.178.402-.374.558-.605.335-.496.538-1.047.667-1.629.004-.02-.003-.043-.006-.091-.037.048-.059.072-.076.1a1.943 1.943 0 01-.334.415c-.28.258-.59.448-.983.464-.297.012-.588 0-.865-.127-.46-.21-.722-.57-.794-1.072-.025-.17-.017-.171-.182-.219A3.513 3.513 0 011.97 20.6a2.286 2.286 0 01-.808-1.13 3.569 3.569 0 01-.16-1.245c.002-.034.016-.067.024-.1.032.023.046.043.05.066.033.153.059.308.096.46.086.355.257.664.516.92.258.256.571.419.91.532.358.118.717.138 1.07-.016a1.89 1.89 0 00.621-.452c.328-.348.533-.76.648-1.223.009-.034.005-.071.007-.11-.015.006-.026.006-.03.011-.031.05-.064.1-.093.152-.284.502-.679.887-1.196 1.135-.351.17-.718.255-1.11.159a1.607 1.607 0 01-.971-.64 2.006 2.006 0 01-.368-.924 2.903 2.903 0 01.02-.886c.05-.439.466-1.17.742-1.271-.02.063-.035.112-.053.16-.043.116-.097.227-.13.345a1.901 1.901 0 00-.05.82c.033.212.09.416.204.6.147.236.346.407.62.465.11.023.225.014.338.018a.576.576 0 00.386-.131c.164-.128.282-.292.366-.481.168-.375.24-.777.309-1.179.05-.296.093-.594.133-.893.039-.281.071-.563.104-.845.026-.232.048-.464.074-.696.024-.228.052-.455.076-.683.024-.227.047-.455.069-.683.013-.14.022-.28.034-.42l.037-.417c.022-.25.041-.5.065-.748.008-.082-.02-.132-.09-.177a2.46 2.46 0 01-.492-.418c-.1-.109-.188-.228-.282-.342-.035-.042-.056-.097-.116-.118a2.084 2.084 0 00.275.597c.06.092.131.176.196.265.063.086.182.115.234.226-.028.003-.046.01-.06.006a4.74 4.74 0 01-.22-.057 2.71 2.71 0 01-1.287-.819c-.435-.487-.656-1.076-.71-1.723a5.206 5.206 0 01.014-1.06c.072-.602.22-1.186.45-1.745.155-.376.338-.741.526-1.102.205-.393.466-.75.765-1.076.512-.559 1.104-1.024 1.726-1.448.717-.49 1.478-.898 2.277-1.233C8.244.828 8.767.632 9.31.494c.655-.166 1.31-.33 1.982-.415.229-.03.458-.058.688-.07zm-1.847 22.82c-.07.06-.147.111-.207.18-.238.27-.464.549-.668.869l-.044.108a.177.177 0 00.093-.057c.174-.19.351-.378.519-.574.104-.122.195-.255.288-.386.024-.034.03-.08.046-.12l-.027-.02zm1.65-3.695a5.51 5.51 0 00-.653.593l-.37.386a.963.963 0 01-.377.25 1.372 1.372 0 01-.467.09c-.044 0-.087.006-.151.012.028.058.043.097.064.131.15.242.301.482.45.724.136.22.276.438.399.666.068.125.105.267.156.404.077.027.14-.018.202-.048.29-.135.579-.274.867-.412.213-.101.437-.186.636-.31.347-.215.68-.455 1.018-.685.015-.01.026-.028.042-.046-.023-.019-.038-.037-.056-.044-.287-.111-.527-.3-.77-.482a5.319 5.319 0 01-.506-.42 1.757 1.757 0 01-.41-.653c-.019-.049-.045-.095-.075-.156zm-5.847.264c-.06.096-.097.194-.132.293a3.38 3.38 0 01-.555 1.01c-.2.25-.455.412-.762.493-.23.06-.464.076-.7.07-.048-.002-.097.002-.158.005.016.04.021.066.035.085.1.145.23.246.4.295.157.046.316.034.498.023.181-.037.343-.115.485-.234.238-.199.402-.454.536-.732.175-.363.264-.751.342-1.144.01-.053.008-.11.011-.164zm14.945-4.586c.008.029.016.057.027.107.024.155.051.31.072.464.03.219.067.437.078.657.017.344.027.689-.014 1.033-.037.315-.063.633-.116.946a6.153 6.153 0 01-.46 1.518c-.008.018-.01.039-.02.082.047-.03.077-.042.098-.064.085-.083.17-.167.248-.255.271-.305.458-.66.596-1.043.18-.498.228-1.011.145-1.531-.103-.65-.33-1.263-.597-1.881a9.055 9.055 0 00-.024-.055l-.033.022zM5.797 8.29a.26.26 0 00.018.153c.124.251.25.501.379.75.025.049.066.09.03.163-.284.06-.578.119-.88.255.059.038.097.06.132.087.042.032.112.058.09.12-.01.033-.075.048-.117.072.017.01.043.021.067.036.166.102.33.207.447.368.138.192.229.404.188.644-.079.469-.306.85-.69 1.132-.054.04-.106.083-.161.122a.243.243 0 00-.103.245.77.77 0 00.055.195c.083.196.22.35.375.492.083.076.159.164.222.257a.37.37 0 01.025.377c-.023.05-.05.099-.076.148-.03.06-.028.111.022.162.041.042.08.089.112.138.038.058.078.079.147.05a.486.486 0 01.333-.006c.16.046.302.126.444.21.13.077.264.149.4.219.067.035.14.05.219.026.071-.022.124.01.145.076.02.064-.003.108-.074.139-.07.03-.137.063-.209.088-.1.035-.201.073-.314.077-.013-.107.11-.088.127-.159-.206-.126-.643-.145-.801-.034.063.112.035.21-.096.313-.13-.1-.025-.202.002-.3a.209.209 0 00-.249.17c-.015.101.067.216.178.224.108.007.218-.005.326-.012.06-.005.12-.027.199 0-.103.123-.248.127-.357.19.002.05.07.086.019.131-.053.048-.095-.001-.132-.03-.08-.063-.16-.126-.231-.197a.474.474 0 01-.157-.311.52.52 0 00-.043-.172c-.032-.074-.032-.137.033-.19-.018-.03-.028-.053-.045-.072a1.222 1.222 0 01-.196-.369c-.053-.137-.046-.264.048-.381.024-.03.05-.06.064-.095a.664.664 0 00.047-.168c.017-.165-.064-.287-.182-.387-.186-.156-.36-.322-.46-.551-.005-.011-.024-.017-.037-.026-.011.017-.024.027-.025.038-.019.185-.045.37-.052.557-.014.377.058.743.162 1.104.118.41.289.798.488 1.173.267.502.537 1.002.812 1.5.055.098.13.189.208.27.198.202.452.272.724.273.202 0 .404-.006.605-.026.295-.03.59-.073.884-.113.183-.025.365-.057.548-.08.21-.026.38.073.522.21.16.156.305.327.447.5.22.265.397.56.554.867.05.098.07.1.147.03.13-.121.26-.242.394-.36.067-.059.088-.12.067-.213a3.535 3.535 0 01-.085-.796c.002-.157.006-.314.018-.471.015-.224.03-.45.06-.672a59.114 59.114 0 01.362-2.298c.087-.493.182-.984.268-1.477.06-.347.118-.694.162-1.043.034-.273.055-.55.063-.825.011-.332.003-.665.002-.998 0-.077.004-.155-.01-.23-.028-.142-.01-.155-.162-.19a5.826 5.826 0 00-.607-.107c-.146-.018-.207-.053-.221-.19-.006-.049-.025-.098-.041-.146-.009-.025-.024-.048-.046-.09l-.025.264c-.009.096-.029.116-.127.115-.055 0-.11-.008-.164-.008-.476 0-.952-.008-1.426.032-.095.008-.173-.015-.226-.103-.04-.066-.088-.126-.134-.186-.063-.084-.086-.093-.182-.06-.195.068-.388.138-.582.21a2.71 2.71 0 00-.675.394.986.986 0 01-.323.168c-.033.01-.07.008-.127.013.02-.066.024-.114.047-.15.064-.105.135-.205.205-.306.023-.033.049-.063.073-.095l-.015-.023-.201.037c-.146.04-.296.07-.437.122-.148.053-.266.023-.386-.072a3.623 3.623 0 01-.733-.786l-.093-.132zm8.592 8.963l-.147.09c-.22.134-.44.266-.659.402-.093.058-.184.12-.27.188-.085.07-.124.161-.072.272.047.1.093.2.147.294.047.08.124.138.213.147.11.01.228.012.336-.012.217-.05.372-.205.528-.357a.291.291 0 00.087-.308c-.046-.18-.079-.365-.118-.547-.011-.052-.027-.103-.045-.169zm-.257-2.409c-.12.291-.205.597-.325.91-.151.433-.294.87-.435 1.323.036-.01.054-.01.067-.018.261-.16.522-.324.785-.484.054-.033.071-.078.065-.138-.012-.13-.024-.262-.034-.393l-.068-.886c-.008-.103-.02-.206-.029-.31-.009 0-.017-.002-.026-.004zm3.081-8.13l.099.285c.08.231.159.463.24.714l.58 1.952c.187.63.372 1.262.558 1.893.114.382.235.762.343 1.146.072.257.126.519.186.799.044.206.087.413.127.64.034.106.023.226.077.325l.025-.006-.068-.362c-.038-.206-.077-.412-.113-.638-.015-.07-.029-.141-.046-.211-.095-.396-.177-.796-.29-1.187-.196-.685-.413-1.364-.618-2.046-.165-.549-.322-1.1-.488-1.648-.069-.227-.15-.45-.226-.695l-.117-.336c-.037-.107-.075-.216-.115-.322-.04-.106-.084-.21-.127-.314a7.558 7.558 0 01-.027.01zM6.225 14.304c-.063-.001-.115.014-.134.083a.35.35 0 00.41.012 4.533 4.533 0 00-.276-.095zM5.23 11.98c-.026-.027-.057-.048-.075.002-.012.032-.007.07-.01.113.082-.037.082-.037.085-.115zm.062-1.189a.135.135 0 00-.088.056.197.197 0 00-.025.11c.005.152.01.306.026.457a.751.751 0 00.066.218c.061.136.157.167.288.101.055-.027.06-.054.025-.11a4.52 4.52 0 01-.129-.211c-.015-.068-.066-.131-.033-.207.04-.09-.076-.116-.074-.19V10.874c-.003-.038-.006-.087-.056-.083zm-.017-.968a.867.867 0 00-.467.127c-.076.045-.084.07-.05.158.034.087.07.173.115.254.064.117.09.125.21.077a.657.657 0 01.336-.053c.202.022.357.136.504.264l.092.077c.007-.006.014-.013.022-.018-.019-.105-.035-.226-.149-.264-.157-.053-.324-.075-.508-.117l-.24-.005c.24-.169.452-.044.687.009-.063-.115-.153-.147-.23-.193-.082-.05-.17-.092-.25-.144-.06-.037-.12-.08-.072-.172zm10.233.325c-.23-.01-.427.08-.608.211-.034.026-.06.065-.105.117.087.026.15.046.232.065.044-.015.088-.03.13-.046.306-.114.61-.115.904.031.126.063.237.04.366-.005-.02-.031-.03-.054-.045-.071a.986.986 0 00-.448-.273c-.14-.044-.284-.024-.426-.03zM7.99 6.483a.308.308 0 00.002.133c.08.321.156.643.242.962.104.387.27.75.456 1.103.02.037.061.08.098.087a.404.404 0 00.253-.051l-.472-.84c-.23-.448-.405-.92-.579-1.394zM10.397.497c-.2-.008-.405.004-.603.034-.236.035-.47.087-.7.152-.287.08-.569.18-.852.273-.04.013-.074.038-.11.058.028.014.05.018.07.014.287-.068.58-.085.873-.09.134-.002.269.009.402.025.19.024.382.048.57.09.456.104.874.3 1.265.556.464.306.888.66 1.257 1.078.205.232.395.475.56.739.17.274.315.561.449.856.273.601.456 1.232.6 1.876.04.173.07.348.1.524.017.104.065.167.17.19.122.028.2.105.22.251-.003.102-.06.174-.129.24a1.065 1.065 0 00-.268.358.164.164 0 00.083-.039c.08-.086.162-.172.235-.265a.56.56 0 00.13-.333c.009-.05.022-.1.024-.15.007-.124-.017-.15-.143-.168-.025-.004-.049-.014-.073-.015-.082-.007-.125-.063-.137-.131-.033-.198-.004-.355.247-.408.086-.018.174-.03.26-.042.158-.023.315-.053.473-.067.14-.012.19.033.226.167.008.029.018.057.021.087.019.179-.008.225-.141.288-.027.013-.055.024-.078.042a.148.148 0 00-.051.067c-.039.144.073.382.206.445l.673.32c.023.011.05.015.075.023l.018-.026c-.015-.008-.032-.013-.044-.024a2.27 2.27 0 00-.544-.32 4.898 4.898 0 00-.173-.075.203.203 0 01-.126-.191c-.003-.085.045-.154.128-.187l.059-.025c.099-.044.118-.076.112-.187a.384.384 0 00-.008-.063c-.067-.294-.123-.59-.205-.88a9.478 9.478 0 00-.826-2.036 7.465 7.465 0 00-1.39-1.805 4.536 4.536 0 00-1.177-.824 3.656 3.656 0 00-1.016-.328 6.155 6.155 0 00-.712-.074zm6.719 5.955c.01.014.018.028.038.034l-.022-.044-.016.01zM4.103 3.917a.062.062 0 01-.03.012.455.455 0 01-.04.039c-.01.01-.02.02-.045.04l-.363.354c-.088.085-.17.178-.266.253-.284.22-.425.53-.544.855a.132.132 0 00-.007.071c.013.055.033.108.052.168l.074.026c-.017.056-.03.105-.047.152-.058.164-.118.327-.175.491-.005.015.008.036.019.077.08-.175.158-.33.225-.489.228-.544.484-1.074.819-1.561.09-.133.182-.266.283-.401.004-.006.007-.013.022-.03.001-.016.003-.032.015-.04l.008-.017zm12.976 2.408a.023.023 0 01.009.019.073.073 0 00-.006.01.188.188 0 00.007.02l.018.022c.002-.007.007-.016.005-.021-.003-.01-.012-.018-.02-.038a1.331 1.331 0 01-.013-.012zM4.199 4.48c-.003.004-.008.008-.027.014-.005.013-.011.025-.031.047a2.085 2.085 0 01-.124.167c-.048.07-.116.055-.181.041-.134-.028-.228.016-.287.143-.089.187-.187.37-.273.56-.049.108-.11.216-.118.36.081.003.154.007.228.008h.228a2.563 2.563 0 01-.079.264c-.01.052-.022.103-.033.155l.02.004c.018-.046.037-.092.067-.153.066-.142.13-.285.2-.426.02-.04.034-.1.116-.092 0 .043.004.084 0 .124-.005.045-.017.09-.028.143.141.043.086.174.115.269.102-.022.104-.195.248-.144v.205l.017.002.439-1.059c-.13 0-.246-.02-.358.033-.024.011-.058-.001-.108-.004.075-.15.139-.278.211-.417a.128.128 0 01.025-.036c0-.015-.001-.03.008-.038l.006-.02c-.005.006-.01.011-.028.017-.004.012-.009.024-.026.045a.085.085 0 01-.032.033c-.123.157-.09.164-.258.106-.079-.027-.078-.028-.047-.144.028-.046.056-.093.098-.15 0-.016-.001-.032.007-.042L4.2 4.48zm2.073-.67c-.003.006-.007.011-.027.016-.094.125-.194.246-.28.377-.155.238-.301.481-.451.723-.14.224-.345.368-.575.481-.017.008-.04.006-.079.011.012-.059.016-.109.033-.153a6.076 6.076 0 01.229-.518l-.007-.02a.138.138 0 01-.035.025c-.028.05-.055.1-.093.164-.26.424-.443.817-.442.95.024.004.048.011.073.013.177.013.188.007.26-.165.03-.07.077-.12.147-.15l.175-.07c.044-.018.085-.057.146-.032.003.05-.01.11.014.145.042.062.044.125.047.193.002.049.017.098.026.147.029-.034.039-.065.05-.097.142-.39.277-.782.428-1.17.1-.256.22-.504.33-.756.013-.03.013-.067.03-.092V3.81zm3.987-.34c0 .045.01.084.021.123.042.16.094.318.124.48.024.133.023.27.028.406 0 .033-.019.067-.032.11-.094-.058-.047-.158-.106-.215h-.125c-.015.072-.01.152-.046.2-.066.085-.155.154-.236.227-.043.038-.078.018-.103-.025l-.046-.087c-.065.035-.117.069-.172.093-.116.051-.235.095-.35.147-.085.038-.09.053-.07.147.014.075.034.148.047.223.013.072.05.109.123.124.233.05.462.115.657.265.058-.102.058-.102.168-.151.03-.014.06-.03.092-.042.08-.03.115-.017.15.06.023.048.041.098.066.158.06-.14-.042-.267.017-.416.157.18.24.39.375.567a.235.235 0 00.022-.098c.002-.124 0-.247.002-.371 0-.034.013-.067.02-.1l.032-.003c.11.155.13.354.226.52a3.036 3.036 0 00-.01-.392c-.004-.045 0-.074.05-.088.08.036.116.14.215.158-.03-.275-.423-1.137-.798-1.635-.114-.127-.2-.28-.34-.386zm-2.667.696c-.019.034-.03.05-.037.067-.061.185-.125.37-.18.556-.031.105-.087.169-.195.19-.09.019-.178.052-.268.073-.038.009-.089.015-.118-.003-.024-.016-.025-.069-.036-.106-.064.076-.082.087-.17.047-.133-.062-.262-.135-.393-.201-.048-.025-.093-.063-.17-.03-.043.12-.091.25-.137.382-.099.28-.087.242.095.453.046.048.102.03.154.023.054-.009.106-.03.16-.036.13-.013.26-.08.367-.015.204-.064.387-.122.571-.178.05-.015.089.005.114.054.022.042.034.093.082.121.038-.056-.013-.128.063-.178l.14.241-.042-1.46zm.278.358c-.096-.01-.107.01-.11.108-.002.038-.003.078.002.115.03.2.099.386.174.57.002.006.012.01.022.015l.078-.05c.052.036.081.088.153.088.205-.002.41.014.616.012.099-.001.158.042.205.12.018.03.024.077.088.066l-.08-.394c-.05-.195-.085-.395-.172-.589-.057.057-.114.068-.18.046a.72.72 0 00-.135-.028c-.22-.028-.44-.059-.66-.08zm10.254-1.727c.089.163.155.316.139.491-.016.168.026.342-.044.516-.047-.033-.088-.082-.112-.075-.117.035-.164-.057-.227-.115a4.772 4.772 0 01-.286-.29l-.104-.113a4.856 4.856 0 01-.023.019c.035.046.07.093.11.156.04.064.084.127.122.193.034.058.065.118.031.205-.082-.01-.164-.019-.246-.032-.06-.01-.101 0-.124.07-.031.098-.037.096-.15.09.02.042.036.08.057.116.041.074.03.138-.03.196-.06.06-.118.122-.178.181a.175.175 0 01-.185.046c-.222-.061-.447-.113-.67-.174-.032-.009-.063-.04-.086-.068-.03-.04-.052-.087-.08-.13-.044-.07-.09-.138-.136-.207a.18.18 0 00-.014.105c.012.127.03.253.035.38.005.1-.024.12-.121.104-.104-.017-.206-.04-.31-.058-.064-.012-.131-.028-.202.03l.081.208c.09 0 .166-.01.237.002a.819.819 0 01.458.251c.078.083.154.168.241.26l.018-.005c-.004-.006-.008-.013-.01-.04.014-.056-.062-.118.018-.178.031.03.064.057.088.09.058.078.111.159.169.257l.089.141.024-.013a2093.819 2093.819 0 01-.427-.934c.055.007.083.007.108.016.193.07.385.142.577.216.074.028.147.06.219.094.062.028.112.018.157-.033.05-.056.102-.112.154-.167.05-.051.095-.046.132.014.016.025.026.053.04.08.071.138.143.277.217.433l.159.308.025-.011c-.044-.106-.07-.218-.138-.334-.057-.182-.168-.346-.206-.545.136.034.362.326.567.732l.057.074.018-.011a1.563 1.563 0 01-.052-.127c-.046-.145-.097-.29-.136-.436-.022-.083-.036-.173.022-.26l.109.058-.026-.207.027-.016c.022.02.05.036.065.06.073.108.143.22.215.33.01.016.029.029.043.043-.036-.217-.2-.38-.229-.626l.155.112c.014-.166.012-.319.042-.465.032-.158-.023-.297-.063-.445.024.004.036.006.055.025.092.124.183.249.277.371.02.027.05.047.069.087l.04.063.019-.015a.293.293 0 01-.053-.082 27.922 27.922 0 01-.332-.49c-.221-.311-.363-.467-.485-.521zm-6.57.327c-.003.161.092.275.069.415l-.368.087c.09.139.032.237-.052.331-.05.057-.092.122-.143.178-.037.04-.046.078-.018.126l.16.275c.029.048.072.066.128.064.076-.003.152 0 .228-.001.116-.003.216.022.275.137.006.014.02.024.044.052.004-.059-.003-.098.01-.13.016-.04.04-.099.072-.108.084-.023.173-.024.26-.03.013-.001.027.018.04.029l.071.065c.019-.11-.082-.198-.024-.31l.126.04c-.026-.123-.07-.245-.071-.366 0-.123.051-.243.115-.36.107.062.16.156.234.253.183.265.36.533.494.834.165-.078.27.068.407.088-.003-.106-.133-.441-.197-.492a.142.142 0 00-.102-.028c-.06.011-.119.039-.191.063-.025-.039-.056-.078-.077-.122a3.936 3.936 0 00-.473-.783c-.076-.094-.16-.182-.228-.26l-.391.285c-.049.035-.094.03-.132-.017l-.169-.207c-.025-.03-.053-.059-.097-.108z"></path></svg>';
103
+
104
+ // node_modules/.pnpm/@lobehub+icons-static-svg@1.90.0/node_modules/@lobehub/icons-static-svg/icons/openclaw.svg
105
+ var openclaw_default = 'data:image/svg+xml,<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>OpenClaw</title><g clip-path="url(%23a)"><path d="M9.046 7.104a.527.527 0 110 1.055.527.527 0 010-1.055z"></path><path d="M15.376 7.104a.528.528 0 110 1.056.528.528 0 010-1.056z"></path><path clip-rule="evenodd" d="M16.877 1.912c.58-.27 1.14-.323 1.616-.037a.317.317 0 01-.326.542c-.227-.136-.547-.153-1.022.068-.352.165-.765.45-1.234.866 2.683 1.17 4.4 3.5 5.148 5.921a6.421 6.421 0 00-.704.184c-.578.016-1.174.204-1.502.735-.338.55-.268 1.276.072 2.069l.005.012.007.014c.523 1.045 1.318 1.91 2.2 2.284-.912 3.274-3.44 6.144-5.972 6.988v2.109h-2.11v-2.11c-1.043.417-2.086.01-2.11 0v2.11h-2.11v-2.11c-2.531-.843-5.061-3.713-5.973-6.987.882-.373 1.678-1.238 2.2-2.284l.007-.014.006-.012c.34-.793.41-1.518.071-2.069-.327-.531-.923-.719-1.503-.735a6.409 6.409 0 00-.704-.183c.749-2.421 2.466-4.751 5.149-5.922-.47-.416-.88-.701-1.234-.866-.474-.221-.794-.204-1.021-.068a.318.318 0 01-.435-.109.317.317 0 01.109-.433c.476-.286 1.036-.233 1.615.037.49.229 1.031.628 1.621 1.182A9.924 9.924 0 0112 2.568c1.199 0 2.284.19 3.256.526.59-.554 1.13-.953 1.62-1.182zM8.835 6.577a1.266 1.266 0 100 2.532 1.266 1.266 0 000-2.532zm6.33 0a1.267 1.267 0 100 2.533 1.267 1.267 0 000-2.533z"></path><path d="M.395 13.118c-.966-1.932-.163-3.863 2.41-3.365v-.001l.05.01c.084.018.17.038.26.06.033.009.067.017.1.027.084.022.168.048.255.076l.09.027c.528 0 .95.158 1.16.501.212.343.212.87-.105 1.61-.085.17-.178.333-.276.489l-.01.017a4.967 4.967 0 01-.62.791l-.019.02c-1.092 1.117-2.496 1.336-3.295-.262z"></path><path d="M21.193 9.753c2.574-.5 3.378 1.433 2.411 3.365-.58 1.159-1.476 1.361-2.342.96l-.011-.005a2.419 2.419 0 01-.114-.056l-.019-.01a2.751 2.751 0 01-.115-.067l-.023-.014c-.035-.022-.071-.044-.106-.068l-.05-.035c-.55-.388-1.062-1.007-1.44-1.76-.276-.647-.311-1.132-.174-1.472.176-.439.636-.639 1.23-.639.032-.011.066-.02.099-.03.08-.026.16-.05.238-.072l.117-.03a5.502 5.502 0 01.3-.067z"></path></g><defs><linearGradient gradientUnits="userSpaceOnUse" id="b" x1="-.659" x2="27.023" y1=".458" y2="22.855"><stop stop-color="%23FF4D4D"></stop><stop offset="1" stop-color="%23991B1B"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="c" x1="-.659" x2="27.023" y1=".458" y2="22.855"><stop stop-color="%23FF4D4D"></stop><stop offset="1" stop-color="%23991B1B"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="d" x1="-.659" x2="27.023" y1=".458" y2="22.855"><stop stop-color="%23FF4D4D"></stop><stop offset="1" stop-color="%23991B1B"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="e" x1="-.659" x2="27.023" y1=".458" y2="22.855"><stop stop-color="%23FF4D4D"></stop><stop offset="1" stop-color="%23991B1B"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="f" x1="-.659" x2="27.023" y1=".458" y2="22.855"><stop stop-color="%23FF4D4D"></stop><stop offset="1" stop-color="%23991B1B"></stop></linearGradient><clipPath id="a"><path d="M0 0h24v24H0z"></path></clipPath></defs></svg>';
106
+
107
+ // node_modules/.pnpm/@lobehub+icons-static-svg@1.90.0/node_modules/@lobehub/icons-static-svg/icons/opencode.svg
108
+ var opencode_default = 'data:image/svg+xml,<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>opencode</title><path d="M16 6H8v12h8V6zm4 16H4V2h16v20z"></path></svg>';
109
+
110
+ // src/dashboard/harness-logo.tsx
111
+ import { jsx as jsx2 } from "react/jsx-runtime";
112
+ var HARNESS_BRAND = {
113
+ opencode: { label: "OpenCode", logoUrl: opencode_default },
114
+ "claude-code": { label: "Claude Code", logoUrl: claudecode_default },
115
+ codex: { label: "Codex", logoUrl: codex_default },
116
+ amp: { label: "AMP", logoUrl: amp_default },
117
+ "kimi-code": { label: "Kimi Code", logoUrl: moonshot_default },
118
+ openclaw: { label: "OpenClaw", logoUrl: openclaw_default },
119
+ hermes: { label: "Hermes", logoUrl: hermesagent_default },
120
+ // No published brand mark — honest lucide glyphs.
121
+ "factory-droids": { label: "Factory Droids", icon: Bot },
122
+ nanoclaw: { label: "NanoClaw", icon: Plug },
123
+ "cli-base": { label: "CLI base", icon: Terminal }
124
+ };
125
+ function HarnessLogo({ type, size = 16, className }) {
126
+ const brand = HARNESS_BRAND[type];
127
+ const Icon2 = brand.icon;
128
+ return /* @__PURE__ */ jsx2(
129
+ "span",
130
+ {
131
+ title: brand.label,
132
+ "aria-label": brand.label,
133
+ className: cn(
134
+ "inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-background shadow-sm ring-1 ring-border",
135
+ className
136
+ ),
137
+ style: { height: size, width: size },
138
+ children: brand.logoUrl ? /* @__PURE__ */ jsx2(
139
+ "span",
140
+ {
141
+ "aria-hidden": true,
142
+ className: "h-[72%] w-[72%]",
143
+ style: {
144
+ backgroundColor: "hsl(var(--foreground))",
145
+ maskImage: cssUrl(brand.logoUrl),
146
+ maskSize: "contain",
147
+ maskRepeat: "no-repeat",
148
+ maskPosition: "center",
149
+ WebkitMaskImage: cssUrl(brand.logoUrl),
150
+ WebkitMaskSize: "contain",
151
+ WebkitMaskRepeat: "no-repeat",
152
+ WebkitMaskPosition: "center"
153
+ }
154
+ }
155
+ ) : Icon2 ? /* @__PURE__ */ jsx2(Icon2, { className: "h-[72%] w-[72%] text-muted-foreground" }) : null
156
+ }
157
+ );
158
+ }
159
+ function cssUrl(url) {
160
+ return `url("${url.replace(/[\\"'#\n]/g, (char) => encodeURIComponent(char))}")`;
161
+ }
162
+
163
+ // src/dashboard/harness-picker.tsx
164
+ import { jsx as jsx3 } from "react/jsx-runtime";
165
+ var HARNESS_OPTIONS = [
166
+ {
167
+ type: "opencode",
168
+ label: "OpenCode",
169
+ description: "Default agent \u2014 broad model support, deterministic streaming"
170
+ },
171
+ {
172
+ type: "claude-code",
173
+ label: "Claude Code",
174
+ description: "Native Claude skills and tools (requires ANTHROPIC_API_KEY)"
175
+ },
176
+ {
177
+ type: "codex",
178
+ label: "Codex",
179
+ description: "OpenAI Codex CLI (requires OPENAI_API_KEY)"
180
+ },
181
+ {
182
+ type: "amp",
183
+ label: "AMP",
184
+ description: "Sourcegraph AMP agent"
185
+ },
186
+ {
187
+ type: "factory-droids",
188
+ label: "Factory Droids",
189
+ description: "Factory Droid agent"
190
+ },
191
+ {
192
+ type: "kimi-code",
193
+ label: "Kimi Code",
194
+ description: "Moonshot Kimi Code CLI (Kimi subscription OAuth or MOONSHOT_API_KEY)"
195
+ },
196
+ {
197
+ type: "openclaw",
198
+ label: "OpenClaw",
199
+ description: "Dispatcher routing to Claude / Codex / Gemini CLIs"
200
+ },
201
+ {
202
+ type: "nanoclaw",
203
+ label: "NanoClaw",
204
+ description: "Local socket-bridge agent backend"
205
+ },
206
+ {
207
+ type: "hermes",
208
+ label: "Hermes",
209
+ description: "Hermes inference-router agent"
210
+ },
211
+ {
212
+ type: "cli-base",
213
+ label: "CLI base (no agent)",
214
+ description: "Shell tools only \u2014 for non-AI scheduled tasks"
215
+ }
216
+ ];
217
+ function HarnessPicker({
218
+ value,
219
+ onChange,
220
+ available,
221
+ optionsOverride,
222
+ label = "Agent harness",
223
+ ...rest
224
+ }) {
225
+ const allowed = new Set(available ?? HARNESS_OPTIONS.map((h) => h.type));
226
+ const backends = HARNESS_OPTIONS.filter((h) => allowed.has(h.type)).map((h) => {
227
+ const override = optionsOverride?.[h.type];
228
+ return {
229
+ type: h.type,
230
+ label: override?.label ?? h.label,
231
+ description: override?.description ?? h.description,
232
+ icon: /* @__PURE__ */ jsx3(HarnessLogo, { type: h.type, size: 20 })
233
+ };
234
+ });
235
+ return /* @__PURE__ */ jsx3(
236
+ BackendSelector,
237
+ {
238
+ backends,
239
+ selected: value,
240
+ onChange: (next) => onChange(next),
241
+ label,
242
+ ...rest
243
+ }
244
+ );
245
+ }
246
+
247
+ export {
248
+ BackendSelector,
249
+ HARNESS_BRAND,
250
+ HarnessLogo,
251
+ HARNESS_OPTIONS,
252
+ HarnessPicker
253
+ };
@@ -5,6 +5,48 @@ import {
5
5
  // src/dashboard/model-picker.tsx
6
6
  import * as React from "react";
7
7
  import { TangleKnot } from "@tangle-network/brand";
8
+
9
+ // src/dashboard/provider-logo.tsx
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ var LOGOS = {
12
+ anthropic: { viewBox: "0 0 24 24", fill: "#D97757", paths: ["M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z"] },
13
+ google: { viewBox: "0 0 24 24", fill: "#8E75B2", paths: ["M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81"] },
14
+ deepseek: { viewBox: "0 0 24 24", fill: "#4D6BFE", paths: ["M23.748 4.651c-.254-.124-.364.113-.512.233-.051.04-.094.09-.137.137-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.155-.708-.311-.955-.65-.172-.24-.219-.509-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.094.172.187.129.323-.082.28-.18.553-.266.833-.055.179-.137.218-.328.14a5.5 5.5 0 0 1-1.737-1.179c-.857-.828-1.631-1.743-2.597-2.46a12 12 0 0 0-.689-.47c-.985-.957.13-1.743.387-1.836.27-.098.094-.433-.778-.428-.872.003-1.67.295-2.687.685a3 3 0 0 1-.465.136 9.6 9.6 0 0 0-2.883-.101c-1.885.21-3.39 1.1-4.497 2.622C.082 8.776-.231 10.854.152 13.02c.403 2.284 1.568 4.175 3.36 5.653 1.857 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.132-.284 4.994-1.86.47.234.962.328 1.78.398.629.058 1.235-.031 1.705-.129.735-.155.684-.836.418-.961-2.155-1.004-1.682-.595-2.112-.926 1.095-1.295 2.768-3.598 3.284-6.733.05-.346.115-.834.108-1.114-.004-.171.035-.238.23-.257a4.2 4.2 0 0 0 1.545-.475c1.397-.763 1.96-2.016 2.093-3.517.02-.23-.004-.467-.247-.588M11.58 18.168c-2.088-1.642-3.101-2.183-3.52-2.16-.39.024-.32.472-.234.763.09.288.207.487.371.74.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.168-1.361-.801-2.5-1.86-3.301-3.306-.775-1.393-1.225-2.888-1.299-4.482-.02-.385.094-.522.477-.592a4.7 4.7 0 0 1 1.53-.038c2.131.311 3.946 1.264 5.467 2.774.868.86 1.525 1.887 2.202 2.89.72 1.066 1.494 2.082 2.48 2.915.348.291.626.513.892.677-.802.09-2.14.109-3.055-.615zm1.001-6.44a.306.306 0 0 1 .415-.287.3.3 0 0 1 .113.074.3.3 0 0 1 .086.214c0 .17-.136.307-.308.307a.303.303 0 0 1-.306-.307m3.11 1.596c-.2.081-.4.151-.591.16a1.25 1.25 0 0 1-.798-.254c-.274-.23-.47-.358-.551-.758a1.7 1.7 0 0 1 .015-.588c.07-.327-.007-.537-.238-.727-.188-.156-.426-.199-.689-.199a.6.6 0 0 1-.254-.078.253.253 0 0 1-.114-.358 1 1 0 0 1 .192-.21c.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.392.451.462.576.685.915.176.264.336.536.446.848.066.194-.02.353-.25.45"] },
15
+ mistral: { viewBox: "0 0 24 24", fill: "#FA520F", paths: ["M17.143 3.429v3.428h-3.429v3.429h-3.428V6.857H6.857V3.43H3.43v13.714H0v3.428h10.286v-3.428H6.857v-3.429h3.429v3.429h3.429v-3.429h3.428v3.429h-3.428v3.428H24v-3.428h-3.43V3.429z"] },
16
+ xai: { viewBox: "0 0 24 24", fill: "#000000", paths: ["M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z"] },
17
+ nvidia: { viewBox: "0 0 24 24", fill: "#76B900", paths: ["M8.948 8.798v-1.43a6.7 6.7 0 0 1 .424-.018c3.922-.124 6.493 3.374 6.493 3.374s-2.774 3.851-5.75 3.851c-.398 0-.787-.062-1.158-.185v-4.346c1.528.185 1.837.857 2.747 2.385l2.04-1.714s-1.492-1.952-4-1.952a6.016 6.016 0 0 0-.796.035m0-4.735v2.138l.424-.027c5.45-.185 9.01 4.47 9.01 4.47s-4.08 4.964-8.33 4.964c-.37 0-.733-.035-1.095-.097v1.325c.3.035.61.062.91.062 3.957 0 6.82-2.023 9.593-4.408.459.371 2.34 1.263 2.73 1.652-2.633 2.208-8.772 3.984-12.253 3.984-.335 0-.653-.018-.971-.053v1.864H24V4.063zm0 10.326v1.131c-3.657-.654-4.673-4.46-4.673-4.46s1.758-1.944 4.673-2.262v1.237H8.94c-1.528-.186-2.73 1.245-2.73 1.245s.68 2.412 2.739 3.11M2.456 10.9s2.164-3.197 6.5-3.533V6.201C4.153 6.59 0 10.653 0 10.653s2.35 6.802 8.948 7.42v-1.237c-4.84-.6-6.492-5.936-6.492-5.936z"] },
18
+ meta: { viewBox: "0 0 24 24", fill: "#0467DF", paths: ["M6.915 4.03c-1.968 0-3.683 1.28-4.871 3.113C.704 9.208 0 11.883 0 14.449c0 .706.07 1.369.21 1.973a6.624 6.624 0 0 0 .265.86 5.297 5.297 0 0 0 .371.761c.696 1.159 1.818 1.927 3.593 1.927 1.497 0 2.633-.671 3.965-2.444.76-1.012 1.144-1.626 2.663-4.32l.756-1.339.186-.325c.061.1.121.196.183.3l2.152 3.595c.724 1.21 1.665 2.556 2.47 3.314 1.046.987 1.992 1.22 3.06 1.22 1.075 0 1.876-.355 2.455-.843a3.743 3.743 0 0 0 .81-.973c.542-.939.861-2.127.861-3.745 0-2.72-.681-5.357-2.084-7.45-1.282-1.912-2.957-2.93-4.716-2.93-1.047 0-2.088.467-3.053 1.308-.652.57-1.257 1.29-1.82 2.05-.69-.875-1.335-1.547-1.958-2.056-1.182-.966-2.315-1.303-3.454-1.303zm10.16 2.053c1.147 0 2.188.758 2.992 1.999 1.132 1.748 1.647 4.195 1.647 6.4 0 1.548-.368 2.9-1.839 2.9-.58 0-1.027-.23-1.664-1.004-.496-.601-1.343-1.878-2.832-4.358l-.617-1.028a44.908 44.908 0 0 0-1.255-1.98c.07-.109.141-.224.211-.327 1.12-1.667 2.118-2.602 3.358-2.602zm-10.201.553c1.265 0 2.058.791 2.675 1.446.307.327.737.871 1.234 1.579l-1.02 1.566c-.757 1.163-1.882 3.017-2.837 4.338-1.191 1.649-1.81 1.817-2.486 1.817-.524 0-1.038-.237-1.383-.794-.263-.426-.464-1.13-.464-2.046 0-2.221.63-4.535 1.66-6.088.454-.687.964-1.226 1.533-1.533a2.264 2.264 0 0 1 1.088-.285z"] },
19
+ moonshotai: { viewBox: "0 0 24 24", fill: "#16191E", paths: ["m1.053 16.91 9.538 2.55a21 20.981 0 0 0 .06 2.031l5.956 1.592a12 11.99 0 0 1-15.554-6.172m-1.02-5.79 11.352 3.035a21 20.981 0 0 0-.469 2.01l10.817 2.89a12 11.99 0 0 1-1.845 2.004L.658 15.918a12 11.99 0 0 1-.625-4.796m1.593-5.146L13.573 9.17a21 20.981 0 0 0-1.01 1.874l11.297 3.02a21 20.981 0 0 1-.67 2.362l-11.55-3.087L.125 10.26a12 11.99 0 0 1 1.499-4.285ZM6.067 1.58l11.285 3.016a21 20.981 0 0 0-1.688 1.719l7.824 2.091a21 20.981 0 0 1 .513 2.664L2.107 5.218a12 11.99 0 0 1 3.96-3.638M21.68 4.866 7.222 1.003A12 11.99 0 0 1 21.68 4.866"] },
20
+ openai: { viewBox: "0 0 256 260", fill: "#10A37F", paths: ["M239.184 106.203a64.72 64.72 0 0 0-5.576-53.103C219.452 28.459 191 15.784 163.213 21.74A65.586 65.586 0 0 0 52.096 45.22a64.72 64.72 0 0 0-43.23 31.36c-14.31 24.602-11.061 55.634 8.033 76.74a64.67 64.67 0 0 0 5.525 53.102c14.174 24.65 42.644 37.324 70.446 31.36a64.72 64.72 0 0 0 48.754 21.744c28.481.025 53.714-18.361 62.414-45.481a64.77 64.77 0 0 0 43.229-31.36c14.137-24.558 10.875-55.423-8.083-76.483m-97.56 136.338a48.4 48.4 0 0 1-31.105-11.255l1.535-.87l51.67-29.825a8.6 8.6 0 0 0 4.247-7.367v-72.85l21.845 12.636c.218.111.37.32.409.563v60.367c-.056 26.818-21.783 48.545-48.601 48.601M37.158 197.93a48.35 48.35 0 0 1-5.781-32.589l1.534.921l51.722 29.826a8.34 8.34 0 0 0 8.441 0l63.181-36.425v25.221a.87.87 0 0 1-.358.665l-52.335 30.184c-23.257 13.398-52.97 5.431-66.404-17.803M23.549 85.38a48.5 48.5 0 0 1 25.58-21.333v61.39a8.29 8.29 0 0 0 4.195 7.316l62.874 36.272l-21.845 12.636a.82.82 0 0 1-.767 0L41.353 151.53c-23.211-13.454-31.171-43.144-17.804-66.405zm179.466 41.695l-63.08-36.63L161.73 77.86a.82.82 0 0 1 .768 0l52.233 30.184a48.6 48.6 0 0 1-7.316 87.635v-61.391a8.54 8.54 0 0 0-4.4-7.213m21.742-32.69l-1.535-.922l-51.619-30.081a8.39 8.39 0 0 0-8.492 0L99.98 99.808V74.587a.72.72 0 0 1 .307-.665l52.233-30.133a48.652 48.652 0 0 1 72.236 50.391zM88.061 139.097l-21.845-12.585a.87.87 0 0 1-.41-.614V65.685a48.652 48.652 0 0 1 79.757-37.346l-1.535.87l-51.67 29.825a8.6 8.6 0 0 0-4.246 7.367zm11.868-25.58L128.067 97.3l28.188 16.218v32.434l-28.086 16.218l-28.188-16.218z"] }
21
+ };
22
+ var ALIASES = {
23
+ moonshot: "moonshotai",
24
+ deepseek_ai: "deepseek",
25
+ "x-ai": "xai",
26
+ "meta-llama": "meta"
27
+ };
28
+ var MONOGRAM = {
29
+ cohere: { bg: "#fae8ff", fg: "#c026d3" },
30
+ groq: { bg: "#fce7f3", fg: "#db2777" },
31
+ cerebras: { bg: "#ccfbf1", fg: "#0d9488" },
32
+ zai: { bg: "#ede9fe", fg: "#7c3aed" },
33
+ "z-ai": { bg: "#ede9fe", fg: "#7c3aed" },
34
+ tuner: { bg: "#dbeafe", fg: "#2563eb" }
35
+ };
36
+ function ProviderLogo({ provider, size = 16 }) {
37
+ const key = ALIASES[provider ?? ""] ?? provider ?? "";
38
+ const logo = LOGOS[key];
39
+ if (logo) {
40
+ return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: logo.viewBox, role: "img", "aria-label": key, children: logo.paths.map((d, i) => /* @__PURE__ */ jsx("path", { d, fill: logo.fill }, i)) });
41
+ }
42
+ const mono = MONOGRAM[key] ?? { bg: "#f3f4f6", fg: "#6b7280" };
43
+ return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 16 16", role: "img", "aria-label": key || "model", children: [
44
+ /* @__PURE__ */ jsx("rect", { width: "16", height: "16", rx: "4", fill: mono.bg }),
45
+ /* @__PURE__ */ jsx("text", { x: "8", y: "11.6", textAnchor: "middle", fill: mono.fg, fontSize: "9", fontWeight: "700", fontFamily: "system-ui, sans-serif", children: (key || "?").charAt(0).toUpperCase() })
46
+ ] });
47
+ }
48
+
49
+ // src/dashboard/model-picker.tsx
8
50
  import { ChevronDown, Search, Sparkles, Loader2 } from "lucide-react";
9
51
  import * as Popover from "@radix-ui/react-dropdown-menu";
10
52
 
@@ -96,7 +138,7 @@ var xai_default = 'data:image/svg+xml,<svg fill="currentColor" fill-rule="evenod
96
138
  var zai_default = 'data:image/svg+xml,<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Z.ai</title><path d="M12.105 2L9.927 4.953H.653L2.83 2h9.276zM23.254 19.048L21.078 22h-9.242l2.174-2.952h9.244zM24 2L9.264 22H0L14.736 2H24z"></path></svg>';
97
139
 
98
140
  // src/dashboard/model-picker.tsx
99
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
141
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
100
142
  function canonicalModelId(model) {
101
143
  const id = model.id;
102
144
  if (id.includes("/")) return id;
@@ -234,15 +276,15 @@ function ModelPicker({
234
276
  setQuery("");
235
277
  };
236
278
  const triggerLabel = label ? `${label}: ${currentLabel || placeholder}` : currentLabel || placeholder;
237
- const trigger = variant === "pill" ? /* @__PURE__ */ jsxs(
279
+ const trigger = variant === "pill" ? /* @__PURE__ */ jsxs2(
238
280
  "button",
239
281
  {
240
282
  type: "button",
241
283
  "aria-label": triggerLabel,
242
284
  disabled,
243
285
  className: cn(
244
- "inline-flex items-center gap-1.5 rounded-full border border-border bg-card",
245
- "px-2.5 py-1 text-xs font-medium text-foreground",
286
+ "inline-flex h-8 items-center gap-1.5 rounded-lg border border-border bg-card",
287
+ "px-2.5 text-xs font-medium text-foreground shadow-sm",
246
288
  "transition-colors duration-[var(--transition-fast)]",
247
289
  "hover:border-primary/30 hover:bg-accent/30",
248
290
  "focus:outline-none focus:border-primary/40",
@@ -252,12 +294,12 @@ function ModelPicker({
252
294
  triggerClassName
253
295
  ),
254
296
  children: [
255
- currentIdentity ? /* @__PURE__ */ jsx(ModelBrandStack, { identity: currentIdentity, size: "sm" }) : /* @__PURE__ */ jsx(Sparkles, { className: "h-3 w-3 text-muted-foreground" }),
256
- /* @__PURE__ */ jsx("span", { className: "truncate max-w-[160px]", children: currentLabel || placeholder }),
257
- /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 text-muted-foreground transition-transform data-[state=open]:rotate-180" })
297
+ currentIdentity ? /* @__PURE__ */ jsx2(ModelBrandStack, { identity: currentIdentity, size: "sm" }) : /* @__PURE__ */ jsx2(Sparkles, { className: "h-3 w-3 text-muted-foreground" }),
298
+ /* @__PURE__ */ jsx2("span", { className: "truncate max-w-[160px]", children: currentLabel || placeholder }),
299
+ /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3 w-3 text-muted-foreground transition-transform data-[state=open]:rotate-180" })
258
300
  ]
259
301
  }
260
- ) : /* @__PURE__ */ jsxs(
302
+ ) : /* @__PURE__ */ jsxs2(
261
303
  "button",
262
304
  {
263
305
  type: "button",
@@ -275,19 +317,19 @@ function ModelPicker({
275
317
  triggerClassName
276
318
  ),
277
319
  children: [
278
- /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
279
- currentIdentity && /* @__PURE__ */ jsx(ModelBrandStack, { identity: currentIdentity, size: "sm" }),
280
- /* @__PURE__ */ jsx("span", { className: cn("truncate", current ? "text-foreground font-medium" : "text-muted-foreground"), children: currentLabel || placeholder })
320
+ /* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 items-center gap-2", children: [
321
+ currentIdentity && /* @__PURE__ */ jsx2(ModelBrandStack, { identity: currentIdentity, size: "sm" }),
322
+ /* @__PURE__ */ jsx2("span", { className: cn("truncate", current ? "text-foreground font-medium" : "text-muted-foreground"), children: currentLabel || placeholder })
281
323
  ] }),
282
- /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform data-[state=open]:rotate-180" })
324
+ /* @__PURE__ */ jsx2(ChevronDown, { className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform data-[state=open]:rotate-180" })
283
325
  ]
284
326
  }
285
327
  );
286
- return /* @__PURE__ */ jsxs("div", { className: cn(variant === "field" ? "space-y-1.5" : "inline-flex", variant === "field" ? className : void 0), children: [
287
- variant === "field" && label && /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground uppercase tracking-[0.06em]", children: label }),
288
- /* @__PURE__ */ jsxs(Popover.Root, { open, onOpenChange: setOpen, modal: false, children: [
289
- /* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: trigger }),
290
- /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(
328
+ return /* @__PURE__ */ jsxs2("div", { className: cn(variant === "field" ? "space-y-1.5" : "inline-flex", variant === "field" ? className : void 0), children: [
329
+ variant === "field" && label && /* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-muted-foreground uppercase tracking-[0.06em]", children: label }),
330
+ /* @__PURE__ */ jsxs2(Popover.Root, { open, onOpenChange: setOpen, modal: false, children: [
331
+ /* @__PURE__ */ jsx2(Popover.Trigger, { asChild: true, children: trigger }),
332
+ /* @__PURE__ */ jsx2(Popover.Portal, { children: /* @__PURE__ */ jsxs2(
291
333
  Popover.Content,
292
334
  {
293
335
  sideOffset: 4,
@@ -301,9 +343,9 @@ function ModelPicker({
301
343
  "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
302
344
  ),
303
345
  children: [
304
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b border-border bg-background/80 px-3 py-2", children: [
305
- /* @__PURE__ */ jsx(Search, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
306
- /* @__PURE__ */ jsx(
346
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 border-b border-border bg-background/80 px-3 py-2", children: [
347
+ /* @__PURE__ */ jsx2(Search, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
348
+ /* @__PURE__ */ jsx2(
307
349
  "input",
308
350
  {
309
351
  ref: searchInputRef,
@@ -318,10 +360,10 @@ function ModelPicker({
318
360
  className: "flex-1 bg-transparent text-sm font-medium outline-none placeholder:font-normal placeholder:text-muted-foreground"
319
361
  }
320
362
  ),
321
- loading && /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin text-muted-foreground" })
363
+ loading && /* @__PURE__ */ jsx2(Loader2, { className: "h-3.5 w-3.5 animate-spin text-muted-foreground" })
322
364
  ] }),
323
- /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto", children: [
324
- !query && popularModels.length > 0 && /* @__PURE__ */ jsx(Section, { label: "Top models", tone: "featured", children: popularModels.map((m) => /* @__PURE__ */ jsx(
365
+ /* @__PURE__ */ jsxs2("div", { className: "flex-1 overflow-y-auto", children: [
366
+ !query && popularModels.length > 0 && /* @__PURE__ */ jsx2(Section, { label: "Top models", tone: "featured", children: popularModels.map((m) => /* @__PURE__ */ jsx2(
325
367
  ModelRow,
326
368
  {
327
369
  model: m,
@@ -331,7 +373,7 @@ function ModelPicker({
331
373
  },
332
374
  `popular-${canonicalModelId(m)}`
333
375
  )) }),
334
- !query && recentIds.length > 0 && /* @__PURE__ */ jsx(Section, { label: "Recent", children: recentIds.map((m) => /* @__PURE__ */ jsx(
376
+ !query && recentIds.length > 0 && /* @__PURE__ */ jsx2(Section, { label: "Recent", children: recentIds.map((m) => /* @__PURE__ */ jsx2(
335
377
  ModelRow,
336
378
  {
337
379
  model: m,
@@ -340,7 +382,7 @@ function ModelPicker({
340
382
  },
341
383
  `recent-${canonicalModelId(m)}`
342
384
  )) }),
343
- grouped.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-8 text-center text-xs text-muted-foreground", children: loading ? "Loading models..." : query ? "No models match." : "No models available." }) : grouped.map(([groupKey, list]) => /* @__PURE__ */ jsx(Section, { label: modelGroupLabel(groupKey), children: list.map((m) => /* @__PURE__ */ jsx(
385
+ grouped.length === 0 ? /* @__PURE__ */ jsx2("div", { className: "px-3 py-8 text-center text-xs text-muted-foreground", children: loading ? "Loading models..." : query ? "No models match." : "No models available." }) : grouped.map(([groupKey, list]) => /* @__PURE__ */ jsx2(Section, { label: modelGroupLabel(groupKey), children: list.map((m) => /* @__PURE__ */ jsx2(
344
386
  ModelRow,
345
387
  {
346
388
  model: m,
@@ -350,7 +392,7 @@ function ModelPicker({
350
392
  canonicalModelId(m)
351
393
  )) }, groupKey))
352
394
  ] }),
353
- /* @__PURE__ */ jsxs("div", { className: "border-t border-border px-3 py-1.5 text-[10px] text-muted-foreground", children: [
395
+ /* @__PURE__ */ jsxs2("div", { className: "border-t border-border px-3 py-1.5 text-[10px] text-muted-foreground", children: [
354
396
  filtered.length,
355
397
  " of ",
356
398
  models.length,
@@ -365,8 +407,8 @@ function ModelPicker({
365
407
  }
366
408
  function Section({ label, children, tone }) {
367
409
  const identity = brandInfo(normalizeBrandKey(label));
368
- return /* @__PURE__ */ jsxs("div", { className: "py-1", children: [
369
- /* @__PURE__ */ jsxs(
410
+ return /* @__PURE__ */ jsxs2("div", { className: "py-1", children: [
411
+ /* @__PURE__ */ jsxs2(
370
412
  "div",
371
413
  {
372
414
  className: cn(
@@ -374,12 +416,12 @@ function Section({ label, children, tone }) {
374
416
  tone === "featured" ? "text-primary" : "text-muted-foreground"
375
417
  ),
376
418
  children: [
377
- identity.key !== "unknown" && /* @__PURE__ */ jsx(BrandLogo, { brand: identity, size: "xs" }),
378
- /* @__PURE__ */ jsx("span", { children: label })
419
+ identity.key !== "unknown" && /* @__PURE__ */ jsx2(BrandLogo, { brand: identity, size: "xs" }),
420
+ /* @__PURE__ */ jsx2("span", { children: label })
379
421
  ]
380
422
  }
381
423
  ),
382
- /* @__PURE__ */ jsx("div", { children })
424
+ /* @__PURE__ */ jsx2("div", { children })
383
425
  ] });
384
426
  }
385
427
  function PickerItem({
@@ -388,7 +430,7 @@ function PickerItem({
388
430
  featured,
389
431
  children
390
432
  }) {
391
- return /* @__PURE__ */ jsx(
433
+ return /* @__PURE__ */ jsx2(
392
434
  Popover.Item,
393
435
  {
394
436
  onSelect: (e) => {
@@ -416,47 +458,59 @@ function ModelRow({
416
458
  const pricing = formatPricing(model.pricing);
417
459
  const ctx = formatContext(model.context_length);
418
460
  const identity = resolveModelBrandIdentity(model);
419
- return /* @__PURE__ */ jsxs(PickerItem, { onSelect: () => onSelect(id), active, featured, children: [
420
- /* @__PURE__ */ jsx(ModelBrandStack, { identity, size: "md" }),
421
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
422
- /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [
423
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium truncate", children: model.name ?? model.id }),
424
- ctx && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: ctx })
461
+ return /* @__PURE__ */ jsxs2(PickerItem, { onSelect: () => onSelect(id), active, featured, children: [
462
+ /* @__PURE__ */ jsx2(ModelBrandStack, { identity, size: "md" }),
463
+ /* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
464
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-baseline justify-between gap-2", children: [
465
+ /* @__PURE__ */ jsx2("span", { className: "text-sm font-medium truncate", children: model.name ?? model.id }),
466
+ ctx && /* @__PURE__ */ jsx2("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: ctx })
425
467
  ] }),
426
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[11px] text-muted-foreground", children: [
427
- /* @__PURE__ */ jsx("span", { className: "truncate", children: id }),
428
- !identity.combined && /* @__PURE__ */ jsxs(Fragment, { children: [
429
- /* @__PURE__ */ jsx("span", { className: "shrink-0", children: "\xB7" }),
430
- /* @__PURE__ */ jsxs("span", { className: "shrink-0", children: [
468
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 text-[11px] text-muted-foreground", children: [
469
+ /* @__PURE__ */ jsx2("span", { className: "truncate", children: id }),
470
+ !identity.combined && /* @__PURE__ */ jsxs2(Fragment, { children: [
471
+ /* @__PURE__ */ jsx2("span", { className: "shrink-0", children: "\xB7" }),
472
+ /* @__PURE__ */ jsxs2("span", { className: "shrink-0", children: [
431
473
  identity.host.label,
432
474
  " \u2192 ",
433
475
  identity.lab.label
434
476
  ] })
435
477
  ] }),
436
- pricing && /* @__PURE__ */ jsxs(Fragment, { children: [
437
- /* @__PURE__ */ jsx("span", { className: "shrink-0", children: "\xB7" }),
438
- /* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono", children: pricing })
478
+ pricing && /* @__PURE__ */ jsxs2(Fragment, { children: [
479
+ /* @__PURE__ */ jsx2("span", { className: "shrink-0", children: "\xB7" }),
480
+ /* @__PURE__ */ jsx2("span", { className: "shrink-0 font-mono", children: pricing })
439
481
  ] })
440
482
  ] })
441
483
  ] })
442
484
  ] });
443
485
  }
444
486
  function ModelBrandStack({ identity, size }) {
445
- if (identity.combined) return /* @__PURE__ */ jsx(BrandLogo, { brand: identity.lab, size });
487
+ if (identity.combined) return /* @__PURE__ */ jsx2(BrandLogo, { brand: identity.lab, size });
446
488
  const hasHostLogo = hasRealLogo(identity.host);
447
489
  const hasLabLogo = hasRealLogo(identity.lab);
448
490
  if (!hasHostLogo && !hasLabLogo) return null;
449
- if (!hasHostLogo) return /* @__PURE__ */ jsx(BrandLogo, { brand: identity.lab, size });
450
- if (!hasLabLogo) return /* @__PURE__ */ jsx(BrandLogo, { brand: identity.host, size });
451
- return /* @__PURE__ */ jsxs("div", { className: cn("relative shrink-0", size === "sm" ? "h-4 w-6" : "h-7 w-9"), "aria-label": `${identity.host.label} hosting ${identity.lab.label}`, children: [
452
- /* @__PURE__ */ jsx(BrandLogo, { brand: identity.host, size: size === "sm" ? "xs" : "sm", className: "absolute left-0 top-0" }),
453
- /* @__PURE__ */ jsx(BrandLogo, { brand: identity.lab, size: size === "sm" ? "xs" : "sm", className: "absolute bottom-0 right-0 ring-2 ring-card" })
491
+ if (!hasHostLogo) return /* @__PURE__ */ jsx2(BrandLogo, { brand: identity.lab, size });
492
+ if (!hasLabLogo) return /* @__PURE__ */ jsx2(BrandLogo, { brand: identity.host, size });
493
+ return /* @__PURE__ */ jsxs2("div", { className: cn("relative shrink-0", size === "sm" ? "h-4 w-6" : "h-7 w-9"), "aria-label": `${identity.host.label} hosting ${identity.lab.label}`, children: [
494
+ /* @__PURE__ */ jsx2(BrandLogo, { brand: identity.host, size: size === "sm" ? "xs" : "sm", className: "absolute left-0 top-0" }),
495
+ /* @__PURE__ */ jsx2(BrandLogo, { brand: identity.lab, size: size === "sm" ? "xs" : "sm", className: "absolute bottom-0 right-0 ring-2 ring-card" })
454
496
  ] });
455
497
  }
498
+ var COLOR_MARK_PROVIDERS = /* @__PURE__ */ new Set([
499
+ "anthropic",
500
+ "openai",
501
+ "google",
502
+ "deepseek",
503
+ "mistral",
504
+ "xai",
505
+ "nvidia",
506
+ "meta",
507
+ "moonshot"
508
+ ]);
456
509
  function BrandLogo({ brand, size, className }) {
457
510
  if (!hasRealLogo(brand)) return null;
458
511
  const pixelSize = size === "xs" ? 14 : size === "sm" ? 16 : 28;
459
- return /* @__PURE__ */ jsx(
512
+ const useColorMark = brand.logo !== "tangle" && COLOR_MARK_PROVIDERS.has(brand.key);
513
+ return /* @__PURE__ */ jsx2(
460
514
  "span",
461
515
  {
462
516
  title: brand.label,
@@ -468,7 +522,7 @@ function BrandLogo({ brand, size, className }) {
468
522
  size === "md" && "h-7 w-7",
469
523
  className
470
524
  ),
471
- children: brand.logo === "tangle" ? /* @__PURE__ */ jsx(TangleKnot, { size: pixelSize, className: "h-full w-full" }) : brand.logoUrl && brand.monochrome ? /* @__PURE__ */ jsx(
525
+ children: brand.logo === "tangle" ? /* @__PURE__ */ jsx2(TangleKnot, { size: pixelSize, className: "h-full w-full" }) : useColorMark ? /* @__PURE__ */ jsx2(ProviderLogo, { provider: brand.key, size: Math.round(pixelSize * 0.72) }) : brand.logoUrl && brand.monochrome ? /* @__PURE__ */ jsx2(
472
526
  "span",
473
527
  {
474
528
  "aria-hidden": true,
@@ -485,7 +539,7 @@ function BrandLogo({ brand, size, className }) {
485
539
  WebkitMaskPosition: "center"
486
540
  }
487
541
  }
488
- ) : brand.logoUrl ? /* @__PURE__ */ jsx("img", { src: brand.logoUrl, alt: "", className: "h-[72%] w-[72%] object-contain" }) : null
542
+ ) : brand.logoUrl ? /* @__PURE__ */ jsx2("img", { src: brand.logoUrl, alt: "", className: "h-[72%] w-[72%] object-contain" }) : null
489
543
  }
490
544
  );
491
545
  }
@@ -659,6 +713,7 @@ var BRAND_INFO = {
659
713
  };
660
714
 
661
715
  export {
716
+ moonshot_default,
662
717
  canonicalModelId,
663
718
  formatPricing,
664
719
  formatContext,
@@ -1,10 +1,11 @@
1
1
  import {
2
- HARNESS_OPTIONS
3
- } from "./chunk-ESRYVGHF.js";
2
+ HARNESS_OPTIONS,
3
+ HarnessLogo
4
+ } from "./chunk-HXIYUQN2.js";
4
5
  import {
5
6
  ModelPicker,
6
7
  canonicalModelId
7
- } from "./chunk-4KAPMTPU.js";
8
+ } from "./chunk-JDMX4HHN.js";
8
9
  import {
9
10
  cn
10
11
  } from "./chunk-EI44GEQ5.js";
@@ -22,13 +23,53 @@ import {
22
23
 
23
24
  // src/chat/reasoning-level-picker.tsx
24
25
  import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
25
- import { Brain, ChevronDown } from "lucide-react";
26
+ import { Brain, ChevronDown, Sparkles } from "lucide-react";
26
27
  import { jsx, jsxs } from "react/jsx-runtime";
28
+ var REASONING_LADDER = [
29
+ "minimal",
30
+ "low",
31
+ "medium",
32
+ "high",
33
+ "xhigh",
34
+ "max",
35
+ "ultracode"
36
+ ];
37
+ function ReasoningGlyph({ level }) {
38
+ if (level === "auto") {
39
+ return /* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5 text-muted-foreground" });
40
+ }
41
+ const BARS = 4;
42
+ const rank = REASONING_LADDER.indexOf(level) + 1;
43
+ const filled = Math.max(1, Math.ceil(rank / REASONING_LADDER.length * BARS));
44
+ return /* @__PURE__ */ jsx(
45
+ "span",
46
+ {
47
+ "aria-hidden": true,
48
+ className: "inline-flex h-3.5 items-end gap-px",
49
+ style: { width: 16 },
50
+ children: Array.from({ length: BARS }).map((_, i) => /* @__PURE__ */ jsx(
51
+ "span",
52
+ {
53
+ className: cn(
54
+ "w-1 rounded-[1px]",
55
+ i < filled ? "bg-foreground" : "bg-border"
56
+ ),
57
+ style: { height: `${35 + i * 22}%` }
58
+ },
59
+ i
60
+ ))
61
+ }
62
+ );
63
+ }
27
64
  var DEFAULT_REASONING_LEVEL_OPTIONS = [
28
65
  { value: "auto", label: "Auto", description: "Let the agent pick the right depth." },
66
+ { value: "minimal", label: "Minimal", description: "Almost no deliberation \u2014 fastest, cheapest." },
29
67
  { value: "low", label: "Low", description: "Fast, direct answers." },
30
68
  { value: "medium", label: "Medium", description: "Inspect context before acting." },
31
- { value: "high", label: "High", description: "Deeper planning and edge-case checks." }
69
+ { value: "high", label: "High", description: "Deeper planning and edge-case checks." },
70
+ { value: "xhigh", label: "Extra High", description: "Extended reasoning for hard problems (Codex/OpenAI)." },
71
+ { value: "max", label: "Max", description: "Maximum extended thinking budget (Claude)." },
72
+ { value: "ultracode", label: "Ultracode", description: "Exhaustive multi-pass reasoning (Claude Code)." }
32
73
  ];
33
74
  function ReasoningLevelPicker({
34
75
  value,
@@ -83,13 +124,16 @@ function ReasoningLevelPicker({
83
124
  onChange(option.value);
84
125
  },
85
126
  className: cn(
86
- "flex cursor-pointer flex-col gap-0.5 rounded-md px-2.5 py-2 outline-none",
127
+ "flex cursor-pointer items-start gap-2.5 rounded-md px-2.5 py-2 outline-none",
87
128
  "transition-colors hover:bg-accent/40 focus:bg-accent/40",
88
129
  option.value === value && "bg-[var(--accent-surface-soft)] text-[var(--accent-text)]"
89
130
  ),
90
131
  children: [
91
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: option.label }),
92
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: option.description })
132
+ /* @__PURE__ */ jsx("span", { className: "mt-0.5 flex w-3.5 shrink-0 justify-center", children: /* @__PURE__ */ jsx(ReasoningGlyph, { level: option.value }) }),
133
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
134
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: option.label }),
135
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: option.description })
136
+ ] })
93
137
  ]
94
138
  },
95
139
  option.value
@@ -101,7 +145,7 @@ function ReasoningLevelPicker({
101
145
 
102
146
  // src/chat/agent-session-controls.tsx
103
147
  import * as DropdownMenu2 from "@radix-ui/react-dropdown-menu";
104
- import { Bot, ChevronDown as ChevronDown2, Lock } from "lucide-react";
148
+ import { ChevronDown as ChevronDown2, Lock } from "lucide-react";
105
149
 
106
150
  // src/chat/harness-model-compat.ts
107
151
  var HARNESS_MODEL_POLICIES = {
@@ -122,11 +166,19 @@ var HARNESS_MODEL_POLICIES = {
122
166
  },
123
167
  amp: { providers: null, preferred: [] },
124
168
  "factory-droids": { providers: null, preferred: [] },
125
- "cli-base": { providers: null, preferred: [] }
169
+ "cli-base": { providers: null, preferred: [] },
170
+ "kimi-code": {
171
+ providers: ["moonshot"],
172
+ preferred: [/^moonshot\//]
173
+ },
174
+ openclaw: { providers: null, preferred: [] },
175
+ nanoclaw: { providers: null, preferred: [] },
176
+ hermes: { providers: null, preferred: [] }
126
177
  };
127
178
  var PROVIDER_PREFERRED_HARNESS = {
128
179
  anthropic: "claude-code",
129
- openai: "codex"
180
+ openai: "codex",
181
+ moonshot: "kimi-code"
130
182
  };
131
183
  function modelProvider(modelId) {
132
184
  const slash = modelId.indexOf("/");
@@ -193,7 +245,7 @@ function HarnessDropdown({
193
245
  ),
194
246
  "aria-label": "Agent harness",
195
247
  children: [
196
- locked ? /* @__PURE__ */ jsx2(Lock, { className: "h-3 w-3 text-muted-foreground" }) : /* @__PURE__ */ jsx2(Bot, { className: "h-3.5 w-3.5 text-muted-foreground" }),
248
+ locked ? /* @__PURE__ */ jsx2(Lock, { className: "h-3 w-3 text-muted-foreground" }) : /* @__PURE__ */ jsx2(HarnessLogo, { type: value, size: 16 }),
197
249
  /* @__PURE__ */ jsx2("span", { children: selected?.label ?? value }),
198
250
  !locked && /* @__PURE__ */ jsx2(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
199
251
  ]
@@ -219,13 +271,16 @@ function HarnessDropdown({
219
271
  onChange(option.type);
220
272
  },
221
273
  className: cn(
222
- "flex cursor-pointer flex-col gap-0.5 rounded-md px-2.5 py-2 outline-none",
274
+ "flex cursor-pointer items-start gap-2.5 rounded-md px-2.5 py-2 outline-none",
223
275
  "transition-colors hover:bg-accent/40 focus:bg-accent/40",
224
276
  option.type === value && "bg-[var(--accent-surface-soft)] text-[var(--accent-text)]"
225
277
  ),
226
278
  children: [
227
- /* @__PURE__ */ jsx2("span", { className: "text-sm font-medium", children: option.label }),
228
- option.description && /* @__PURE__ */ jsx2("span", { className: "text-xs text-muted-foreground", children: option.description })
279
+ /* @__PURE__ */ jsx2(HarnessLogo, { type: option.type, size: 20, className: "mt-0.5" }),
280
+ /* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
281
+ /* @__PURE__ */ jsx2("span", { className: "text-sm font-medium", children: option.label }),
282
+ option.description && /* @__PURE__ */ jsx2("span", { className: "text-xs text-muted-foreground", children: option.description })
283
+ ] })
229
284
  ]
230
285
  },
231
286
  option.type
@@ -300,7 +355,7 @@ function AgentSessionControls({
300
355
 
301
356
  // src/chat/artifact-agent-dock.tsx
302
357
  import * as React from "react";
303
- import { Sparkles, Send, Square, X } from "lucide-react";
358
+ import { Sparkles as Sparkles2, Send, Square, X } from "lucide-react";
304
359
  import { ChatMessage } from "@tangle-network/ui/chat";
305
360
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
306
361
  function defaultScopeLabel(scope) {
@@ -479,7 +534,7 @@ function ArtifactAgentDock({
479
534
  children: [
480
535
  /* @__PURE__ */ jsxs3("header", { className: "flex items-center justify-between border-b border-border bg-background/60 px-4 py-3", children: [
481
536
  /* @__PURE__ */ jsxs3("div", { className: "flex min-w-0 items-center gap-2", children: [
482
- /* @__PURE__ */ jsx3(Sparkles, { className: "h-4 w-4 shrink-0 text-primary" }),
537
+ /* @__PURE__ */ jsx3(Sparkles2, { className: "h-4 w-4 shrink-0 text-primary" }),
483
538
  /* @__PURE__ */ jsxs3("div", { className: "min-w-0", children: [
484
539
  /* @__PURE__ */ jsx3("div", { className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground", children: "Discussing" }),
485
540
  /* @__PURE__ */ jsx3("div", { className: "truncate text-sm font-semibold text-foreground", children: heading })
@@ -497,7 +552,7 @@ function ArtifactAgentDock({
497
552
  )
498
553
  ] }),
499
554
  /* @__PURE__ */ jsx3("div", { ref: scrollRef, className: "flex-1 overflow-y-auto px-3 py-4", children: loading ? /* @__PURE__ */ jsx3("div", { className: "px-3 py-8 text-center text-xs text-muted-foreground", children: "Loading conversation\u2026" }) : messages.length === 0 && !streamContent ? /* @__PURE__ */ jsxs3("div", { className: "px-3 py-12 text-center", children: [
500
- /* @__PURE__ */ jsx3(Sparkles, { className: "mx-auto mb-3 h-5 w-5 text-muted-foreground/40" }),
555
+ /* @__PURE__ */ jsx3(Sparkles2, { className: "mx-auto mb-3 h-5 w-5 text-muted-foreground/40" }),
501
556
  /* @__PURE__ */ jsxs3("p", { className: "text-sm text-foreground", children: [
502
557
  "Ask the agent about this ",
503
558
  scope.kind === "vault-file" ? "document" : scope.kind,
@@ -1,6 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- export { B as Backend, a as BackendSelector, b as BackendSelectorProps, H as HARNESS_OPTIONS, c as HarnessPicker, d as HarnessPickerProps, e as HarnessType } from './harness-picker-C1W3rTeb.js';
3
+ import { e as HarnessType } from './harness-picker-ppDe7ap-.js';
4
+ export { B as Backend, a as BackendSelector, b as BackendSelectorProps, H as HARNESS_OPTIONS, c as HarnessPicker, d as HarnessPickerProps } from './harness-picker-ppDe7ap-.js';
4
5
  export { M as ModelInfo, a as ModelPicker, b as ModelPickerProps, c as ModelPickerVariant, d as canonicalModelId, f as formatContext, e as formatPricing } from './model-picker-DUfMTQo5.js';
5
6
  export { B as BillingBalance, a as BillingDashboard, b as BillingDashboardProps, c as BillingSubscription, d as BillingUsage, P as PricingPage, e as PricingPageProps, f as PricingTier, T as TemplateCard, g as TemplateCardData, h as TemplateCardProps, U as UsageChart, i as UsageChartProps, j as UsageDataPoint, k as formatPrice } from './template-card-UhV3pmRC.js';
6
7
 
@@ -434,6 +435,34 @@ interface PlanCardsProps {
434
435
  }
435
436
  declare function PlanCards({ plans, className }: PlanCardsProps): react_jsx_runtime.JSX.Element;
436
437
 
438
+ /**
439
+ * Per-harness brand glyph. `logoUrl` is a bundled lobehub data-url rendered
440
+ * as a CSS mask filled with the foreground token (single-color brand mark,
441
+ * theme-safe). `icon` is an honest lucide fallback for harnesses that have
442
+ * no published brand mark — never an invented logo.
443
+ */
444
+ interface HarnessBrand {
445
+ label: string;
446
+ logoUrl?: string;
447
+ icon?: React.ComponentType<{
448
+ className?: string;
449
+ }>;
450
+ }
451
+ declare const HARNESS_BRAND: Record<HarnessType, HarnessBrand>;
452
+ interface HarnessLogoProps {
453
+ type: HarnessType;
454
+ /** Chip edge length in px. Default 16 (matches the model pill glyph). */
455
+ size?: number;
456
+ className?: string;
457
+ }
458
+ /**
459
+ * Brand chip for a harness, matching {@link BrandLogo}'s render contract in
460
+ * model-picker: a rounded `bg-background ring-1 ring-border` chip wrapping
461
+ * either a foreground-filled CSS-mask of the brand SVG or a lucide fallback
462
+ * glyph. Keeps harness pills visually consistent with model pills.
463
+ */
464
+ declare function HarnessLogo({ type, size, className }: HarnessLogoProps): react_jsx_runtime.JSX.Element;
465
+
437
466
  type ProductVariant = "sandbox";
438
467
  interface NavItem {
439
468
  id: string;
@@ -815,4 +844,4 @@ interface InfoPanelProps {
815
844
  }
816
845
  declare function InfoPanel({ label, title, description, className }: InfoPanelProps): react_jsx_runtime.JSX.Element;
817
846
 
818
- export { ActivityFeed, type ActivityFeedProps, type ActivityItem, BackendConfig, type BackendConfigProps, type BackendStatusData, ClusterStatusBar, type ClusterStatusBarProps, type ClusterStatusItem, CreditBalance, type CreditBalanceProps, DashboardLayout, type DashboardLayoutProps, type Profile as DashboardProfile, type SnapshotInfo as DashboardSnapshotInfo, type DashboardUser, type ExposedPort, type GitCommitData, GitPanel, type GitPanelProps, type GitStatusData, INSUFFICIENT_BALANCE_CODE, InfoPanel, type InfoPanelProps, type InsufficientBalance, type Invoice, InvoiceTable, type InvoiceTableProps, type McpServer, MetricAreaChart, type MetricAreaChartProps, type MetricChartPoint, type MetricChartTone, type NavItem, NetworkConfig, type NetworkConfigData, type NetworkConfigProps, NewSandboxCard, type NewSandboxCardProps, OutOfCreditsModal, type OutOfCreditsModalProps, type PlanCardData, PlanCards, type PlanCardsProps, type PlanFeature, PortsList, type PortsListProps, type ProcessInfo, ProcessList, type ProcessListProps, type ProductVariant, ProfileAvatar, type ProfileAvatarProps, ProfileComparison, type ProfileComparisonProps, ProfileSelector, type ProfileSelectorProps, PromoBanner, type PromoBannerProps, RailButton, type RailButtonProps, RailModeButton, type RailModeButtonProps, RailSeparator, type RailSeparatorProps, ResourceMeter, type ResourceMeterProps, ResourceSnapshot, type ResourceSnapshotItem, type ResourceSnapshotProps, SIDEBAR_MOBILE_WIDTH, SIDEBAR_PANEL_WIDTH, SIDEBAR_RAIL_WIDTH, SIDEBAR_TOTAL_WIDTH, SandboxCard, type SandboxCardData, type SandboxCardProps, type SandboxStatus, SandboxTable, type SandboxTableProps, Sidebar, SidebarContent, type SidebarContentProps, SidebarLayout, type SidebarLayoutNavItem, type SidebarLayoutProps, SidebarPanel, SidebarPanelContent, type SidebarPanelContentProps, SidebarPanelHeader, type SidebarPanelHeaderProps, type SidebarPanelProps, type SidebarProps, SidebarProvider, type SidebarProviderProps, SidebarRail, SidebarRailFooter, type SidebarRailFooterProps, SidebarRailHeader, type SidebarRailHeaderProps, SidebarRailNav, type SidebarRailNavProps, type SidebarRailProps, type SidebarUser, SnapshotList, type SnapshotListProps, SystemLogsViewer, type SystemLogsViewerProps, type TeamRole, UsageSummary, type UsageSummaryData, type UsageSummaryProps, type Variant, VariantList, type VariantListProps, type VariantOutcome, type VariantStatus, canAdminSandbox, parseInsufficientBalance, useSidebar };
847
+ export { ActivityFeed, type ActivityFeedProps, type ActivityItem, BackendConfig, type BackendConfigProps, type BackendStatusData, ClusterStatusBar, type ClusterStatusBarProps, type ClusterStatusItem, CreditBalance, type CreditBalanceProps, DashboardLayout, type DashboardLayoutProps, type Profile as DashboardProfile, type SnapshotInfo as DashboardSnapshotInfo, type DashboardUser, type ExposedPort, type GitCommitData, GitPanel, type GitPanelProps, type GitStatusData, HARNESS_BRAND, type HarnessBrand, HarnessLogo, type HarnessLogoProps, HarnessType, INSUFFICIENT_BALANCE_CODE, InfoPanel, type InfoPanelProps, type InsufficientBalance, type Invoice, InvoiceTable, type InvoiceTableProps, type McpServer, MetricAreaChart, type MetricAreaChartProps, type MetricChartPoint, type MetricChartTone, type NavItem, NetworkConfig, type NetworkConfigData, type NetworkConfigProps, NewSandboxCard, type NewSandboxCardProps, OutOfCreditsModal, type OutOfCreditsModalProps, type PlanCardData, PlanCards, type PlanCardsProps, type PlanFeature, PortsList, type PortsListProps, type ProcessInfo, ProcessList, type ProcessListProps, type ProductVariant, ProfileAvatar, type ProfileAvatarProps, ProfileComparison, type ProfileComparisonProps, ProfileSelector, type ProfileSelectorProps, PromoBanner, type PromoBannerProps, RailButton, type RailButtonProps, RailModeButton, type RailModeButtonProps, RailSeparator, type RailSeparatorProps, ResourceMeter, type ResourceMeterProps, ResourceSnapshot, type ResourceSnapshotItem, type ResourceSnapshotProps, SIDEBAR_MOBILE_WIDTH, SIDEBAR_PANEL_WIDTH, SIDEBAR_RAIL_WIDTH, SIDEBAR_TOTAL_WIDTH, SandboxCard, type SandboxCardData, type SandboxCardProps, type SandboxStatus, SandboxTable, type SandboxTableProps, Sidebar, SidebarContent, type SidebarContentProps, SidebarLayout, type SidebarLayoutNavItem, type SidebarLayoutProps, SidebarPanel, SidebarPanelContent, type SidebarPanelContentProps, SidebarPanelHeader, type SidebarPanelHeaderProps, type SidebarPanelProps, type SidebarProps, SidebarProvider, type SidebarProviderProps, SidebarRail, SidebarRailFooter, type SidebarRailFooterProps, SidebarRailHeader, type SidebarRailHeaderProps, SidebarRailNav, type SidebarRailNavProps, type SidebarRailProps, type SidebarUser, SnapshotList, type SnapshotListProps, SystemLogsViewer, type SystemLogsViewerProps, type TeamRole, UsageSummary, type UsageSummaryData, type UsageSummaryProps, type Variant, VariantList, type VariantListProps, type VariantOutcome, type VariantStatus, canAdminSandbox, parseInsufficientBalance, useSidebar };
package/dist/dashboard.js CHANGED
@@ -47,7 +47,7 @@ import {
47
47
  canAdminSandbox,
48
48
  parseInsufficientBalance,
49
49
  useSidebar
50
- } from "./chunk-MBYBQWRN.js";
50
+ } from "./chunk-76TCOY2R.js";
51
51
  import {
52
52
  BillingDashboard,
53
53
  InfoPanel,
@@ -59,15 +59,17 @@ import {
59
59
  import "./chunk-7ZA5SEK3.js";
60
60
  import {
61
61
  BackendSelector,
62
+ HARNESS_BRAND,
62
63
  HARNESS_OPTIONS,
64
+ HarnessLogo,
63
65
  HarnessPicker
64
- } from "./chunk-ESRYVGHF.js";
66
+ } from "./chunk-HXIYUQN2.js";
65
67
  import {
66
68
  ModelPicker,
67
69
  canonicalModelId,
68
70
  formatContext,
69
71
  formatPricing
70
- } from "./chunk-4KAPMTPU.js";
72
+ } from "./chunk-JDMX4HHN.js";
71
73
  import "./chunk-EI44GEQ5.js";
72
74
  export {
73
75
  ActivityFeed,
@@ -78,7 +80,9 @@ export {
78
80
  CreditBalance,
79
81
  DashboardLayout,
80
82
  GitPanel,
83
+ HARNESS_BRAND,
81
84
  HARNESS_OPTIONS,
85
+ HarnessLogo,
82
86
  HarnessPicker,
83
87
  INSUFFICIENT_BALANCE_CODE,
84
88
  InfoPanel,
package/dist/globals.css CHANGED
@@ -1508,6 +1508,9 @@
1508
1508
  .rounded-2xl {
1509
1509
  border-radius: var(--radius-2xl);
1510
1510
  }
1511
+ .rounded-\[1px\] {
1512
+ border-radius: 1px;
1513
+ }
1511
1514
  .rounded-\[2px\] {
1512
1515
  border-radius: 2px;
1513
1516
  }
@@ -1,9 +1,12 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
2
3
 
3
4
  interface Backend {
4
5
  type: string;
5
6
  label: string;
6
7
  description?: string;
8
+ /** Optional leading brand glyph (e.g. a HarnessLogo) shown in the trigger and rows. */
9
+ icon?: ReactNode;
7
10
  }
8
11
  interface BackendSelectorProps {
9
12
  backends: Backend[];
@@ -18,9 +21,11 @@ declare function BackendSelector({ backends, selected, onChange, label, placehol
18
21
  /**
19
22
  * Sandbox agent harness types — mirrors `BackendType` from
20
23
  * `@tangle-network/sandbox` SDK. Kept in lockstep with that enum:
21
- * if the SDK adds a backend, add it here too.
24
+ * if the SDK adds a backend, add it here too. The SDK's `pi`, `forge`,
25
+ * `acp`, and `cursor` backends are deliberately deferred (not yet
26
+ * surfaced in the picker) until their copy and compat policies land.
22
27
  */
23
- type HarnessType = "opencode" | "claude-code" | "codex" | "amp" | "factory-droids" | "cli-base";
28
+ type HarnessType = "opencode" | "claude-code" | "codex" | "amp" | "factory-droids" | "cli-base" | "kimi-code" | "openclaw" | "nanoclaw" | "hermes";
24
29
  interface HarnessOption extends Backend {
25
30
  type: HarnessType;
26
31
  }
package/dist/index.d.ts CHANGED
@@ -8,8 +8,8 @@ export { AgentSessionControls, AgentSessionControlsProps, AgentSessionHarnessCon
8
8
  export { ExpandedToolDetail, ExpandedToolDetailProps, InlineThinkingItem, InlineThinkingItemProps, InlineToolItem, InlineToolItemProps, LiveDuration, RunGroup, RunGroupProps } from '@tangle-network/ui/run';
9
9
  export { CommandPreview, DiffPreview, GlobResultsPreview, GrepResultsPreview, QuestionPreview, WebSearchPreview, WriteFilePreview } from '@tangle-network/ui/tool-previews';
10
10
  export { FileArtifactPane, FileArtifactPaneProps, FileNode, FilePreview, FilePreviewProps, FileTabData, FileTabs, FileTabsProps, FileTree, FileTreeProps, FileTreeVisibilityOptions, RichFileTree, RichFileTreeGitEntry, RichFileTreeGitStatus, RichFileTreeProps, RichFileTreeThemeVars, filterFileTree } from '@tangle-network/ui/files';
11
- export { ActivityFeed, ActivityFeedProps, ActivityItem, BackendConfig, BackendConfigProps, BackendStatusData, ClusterStatusBar, ClusterStatusBarProps, ClusterStatusItem, CreditBalance, CreditBalanceProps, DashboardLayout, DashboardLayoutProps, DashboardProfile, DashboardSnapshotInfo, DashboardUser, ExposedPort, GitCommitData, GitPanel, GitPanelProps, GitStatusData, INSUFFICIENT_BALANCE_CODE, InfoPanel, InfoPanelProps, InsufficientBalance, Invoice, InvoiceTable, InvoiceTableProps, McpServer, MetricAreaChart, MetricAreaChartProps, MetricChartPoint, MetricChartTone, NavItem, NetworkConfig, NetworkConfigData, NetworkConfigProps, NewSandboxCard, NewSandboxCardProps, OutOfCreditsModal, OutOfCreditsModalProps, PlanCardData, PlanCards, PlanCardsProps, PlanFeature, PortsList, PortsListProps, ProcessInfo, ProcessList, ProcessListProps, ProductVariant, ProfileAvatar, ProfileAvatarProps, ProfileComparison, ProfileComparisonProps, ProfileSelector, ProfileSelectorProps, PromoBanner, PromoBannerProps, RailButton, RailButtonProps, RailModeButton, RailModeButtonProps, RailSeparator, RailSeparatorProps, ResourceMeter, ResourceMeterProps, ResourceSnapshot, ResourceSnapshotItem, ResourceSnapshotProps, SIDEBAR_MOBILE_WIDTH, SIDEBAR_PANEL_WIDTH, SIDEBAR_RAIL_WIDTH, SIDEBAR_TOTAL_WIDTH, SandboxCard, SandboxCardData, SandboxCardProps, SandboxStatus, SandboxTable, SandboxTableProps, Sidebar, SidebarContent, SidebarContentProps, SidebarLayout, SidebarLayoutNavItem, SidebarLayoutProps, SidebarPanel, SidebarPanelContent, SidebarPanelContentProps, SidebarPanelHeader, SidebarPanelHeaderProps, SidebarPanelProps, SidebarProps, SidebarProvider, SidebarProviderProps, SidebarRail, SidebarRailFooter, SidebarRailFooterProps, SidebarRailHeader, SidebarRailHeaderProps, SidebarRailNav, SidebarRailNavProps, SidebarRailProps, SidebarUser, SnapshotList, SnapshotListProps, SystemLogsViewer, SystemLogsViewerProps, TeamRole, UsageSummary, UsageSummaryData, UsageSummaryProps, Variant, VariantList, VariantListProps, VariantOutcome, VariantStatus, canAdminSandbox, parseInsufficientBalance, useSidebar } from './dashboard.js';
12
- export { B as Backend, a as BackendSelector, b as BackendSelectorProps, H as HARNESS_OPTIONS, c as HarnessPicker, d as HarnessPickerProps, e as HarnessType } from './harness-picker-C1W3rTeb.js';
11
+ export { ActivityFeed, ActivityFeedProps, ActivityItem, BackendConfig, BackendConfigProps, BackendStatusData, ClusterStatusBar, ClusterStatusBarProps, ClusterStatusItem, CreditBalance, CreditBalanceProps, DashboardLayout, DashboardLayoutProps, DashboardProfile, DashboardSnapshotInfo, DashboardUser, ExposedPort, GitCommitData, GitPanel, GitPanelProps, GitStatusData, HARNESS_BRAND, HarnessBrand, HarnessLogo, HarnessLogoProps, INSUFFICIENT_BALANCE_CODE, InfoPanel, InfoPanelProps, InsufficientBalance, Invoice, InvoiceTable, InvoiceTableProps, McpServer, MetricAreaChart, MetricAreaChartProps, MetricChartPoint, MetricChartTone, NavItem, NetworkConfig, NetworkConfigData, NetworkConfigProps, NewSandboxCard, NewSandboxCardProps, OutOfCreditsModal, OutOfCreditsModalProps, PlanCardData, PlanCards, PlanCardsProps, PlanFeature, PortsList, PortsListProps, ProcessInfo, ProcessList, ProcessListProps, ProductVariant, ProfileAvatar, ProfileAvatarProps, ProfileComparison, ProfileComparisonProps, ProfileSelector, ProfileSelectorProps, PromoBanner, PromoBannerProps, RailButton, RailButtonProps, RailModeButton, RailModeButtonProps, RailSeparator, RailSeparatorProps, ResourceMeter, ResourceMeterProps, ResourceSnapshot, ResourceSnapshotItem, ResourceSnapshotProps, SIDEBAR_MOBILE_WIDTH, SIDEBAR_PANEL_WIDTH, SIDEBAR_RAIL_WIDTH, SIDEBAR_TOTAL_WIDTH, SandboxCard, SandboxCardData, SandboxCardProps, SandboxStatus, SandboxTable, SandboxTableProps, Sidebar, SidebarContent, SidebarContentProps, SidebarLayout, SidebarLayoutNavItem, SidebarLayoutProps, SidebarPanel, SidebarPanelContent, SidebarPanelContentProps, SidebarPanelHeader, SidebarPanelHeaderProps, SidebarPanelProps, SidebarProps, SidebarProvider, SidebarProviderProps, SidebarRail, SidebarRailFooter, SidebarRailFooterProps, SidebarRailHeader, SidebarRailHeaderProps, SidebarRailNav, SidebarRailNavProps, SidebarRailProps, SidebarUser, SnapshotList, SnapshotListProps, SystemLogsViewer, SystemLogsViewerProps, TeamRole, UsageSummary, UsageSummaryData, UsageSummaryProps, Variant, VariantList, VariantListProps, VariantOutcome, VariantStatus, canAdminSandbox, parseInsufficientBalance, useSidebar } from './dashboard.js';
12
+ export { B as Backend, a as BackendSelector, b as BackendSelectorProps, H as HARNESS_OPTIONS, c as HarnessPicker, d as HarnessPickerProps, e as HarnessType } from './harness-picker-ppDe7ap-.js';
13
13
  export { M as ModelInfo, a as ModelPicker, b as ModelPickerProps, c as ModelPickerVariant, d as canonicalModelId, f as formatContext, e as formatPricing } from './model-picker-DUfMTQo5.js';
14
14
  export { B as BillingBalance, a as BillingDashboard, b as BillingDashboardProps, c as BillingSubscription, d as BillingUsage, P as PricingPage, e as PricingPageProps, f as PricingTier, T as TemplateCard, g as TemplateCardData, h as TemplateCardProps, U as UsageChart, i as UsageChartProps, j as UsageDataPoint, k as formatPrice } from './template-card-UhV3pmRC.js';
15
15
  export { AuthHeader, AuthHeaderProps, GitHubLoginButton, GitHubLoginButtonProps, LoginLayout, LoginLayoutProps, SessionUser, UserMenu, UserMenuProps } from '@tangle-network/ui/auth';
package/dist/index.js CHANGED
@@ -104,7 +104,7 @@ import {
104
104
  modelProvider,
105
105
  snapHarnessToModel,
106
106
  snapModelToHarness
107
- } from "./chunk-TAAYDQGM.js";
107
+ } from "./chunk-KANKBACI.js";
108
108
  import {
109
109
  ExpandedToolDetail,
110
110
  InlineThinkingItem,
@@ -189,7 +189,7 @@ import {
189
189
  canAdminSandbox,
190
190
  parseInsufficientBalance,
191
191
  useSidebar
192
- } from "./chunk-MBYBQWRN.js";
192
+ } from "./chunk-76TCOY2R.js";
193
193
  import {
194
194
  BillingDashboard,
195
195
  InfoPanel,
@@ -287,15 +287,17 @@ import {
287
287
  } from "./chunk-7ZA5SEK3.js";
288
288
  import {
289
289
  BackendSelector,
290
+ HARNESS_BRAND,
290
291
  HARNESS_OPTIONS,
292
+ HarnessLogo,
291
293
  HarnessPicker
292
- } from "./chunk-ESRYVGHF.js";
294
+ } from "./chunk-HXIYUQN2.js";
293
295
  import {
294
296
  ModelPicker,
295
297
  canonicalModelId,
296
298
  formatContext,
297
299
  formatPricing
298
- } from "./chunk-4KAPMTPU.js";
300
+ } from "./chunk-JDMX4HHN.js";
299
301
  import "./chunk-EI44GEQ5.js";
300
302
 
301
303
  // src/index.ts
@@ -389,8 +391,10 @@ export {
389
391
  GitPanel,
390
392
  GlobResultsPreview,
391
393
  GrepResultsPreview,
394
+ HARNESS_BRAND,
392
395
  HARNESS_MODEL_POLICIES,
393
396
  HARNESS_OPTIONS,
397
+ HarnessLogo,
394
398
  HarnessPicker,
395
399
  INSUFFICIENT_BALANCE_CODE,
396
400
  InfoPanel,
package/dist/pages.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  Switch,
13
13
  Textarea
14
14
  } from "./chunk-7ZA5SEK3.js";
15
- import "./chunk-4KAPMTPU.js";
15
+ import "./chunk-JDMX4HHN.js";
16
16
  import {
17
17
  cn
18
18
  } from "./chunk-EI44GEQ5.js";
@@ -2893,7 +2893,7 @@ function StartupScriptsPage({ apiClient, className }) {
2893
2893
  }));
2894
2894
  };
2895
2895
  const activeCount = scripts.filter((s) => s.enabled).length;
2896
- return /* @__PURE__ */ jsxs7("div", { className: cn("space-y-6", className), children: [
2896
+ return /* @__PURE__ */ jsxs7("div", { className: cn("mx-auto w-full max-w-7xl space-y-6", className), children: [
2897
2897
  /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-4 md:flex-row md:items-end md:justify-between", children: [
2898
2898
  /* @__PURE__ */ jsxs7("div", { children: [
2899
2899
  /* @__PURE__ */ jsx7("h1", { className: "font-display text-3xl font-extrabold tracking-tight text-foreground", children: "Startup Scripts" }),
package/dist/styles.css CHANGED
@@ -1508,6 +1508,9 @@
1508
1508
  .rounded-2xl {
1509
1509
  border-radius: var(--radius-2xl);
1510
1510
  }
1511
+ .rounded-\[1px\] {
1512
+ border-radius: 1px;
1513
+ }
1511
1514
  .rounded-\[2px\] {
1512
1515
  border-radius: 2px;
1513
1516
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.23.2",
3
+ "version": "0.23.4",
4
4
  "description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,147 +0,0 @@
1
- import {
2
- cn
3
- } from "./chunk-EI44GEQ5.js";
4
-
5
- // src/dashboard/backend-selector.tsx
6
- import { ChevronDown } from "lucide-react";
7
- import * as Select from "@radix-ui/react-select";
8
- import { jsx, jsxs } from "react/jsx-runtime";
9
- function BackendSelector({
10
- backends,
11
- selected,
12
- onChange,
13
- label = "Model",
14
- placeholder = "Select a model",
15
- className
16
- }) {
17
- const current = backends.find((b) => b.type === selected);
18
- return /* @__PURE__ */ jsxs("div", { className: cn("space-y-1.5", className), children: [
19
- label && /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground uppercase tracking-[0.06em]", children: label }),
20
- /* @__PURE__ */ jsxs(Select.Root, { value: selected, onValueChange: onChange, children: [
21
- /* @__PURE__ */ jsxs(
22
- Select.Trigger,
23
- {
24
- className: cn(
25
- "flex w-full items-center justify-between gap-2 rounded-[var(--radius-md)]",
26
- "border border-border bg-card",
27
- "px-3 py-2.5 text-sm text-left",
28
- "transition-colors duration-[var(--transition-fast)]",
29
- "hover:border-primary/20 hover:bg-accent/30",
30
- "focus:outline-none focus:border-primary/30",
31
- "data-[state=open]:border-primary/30 data-[state=open]:bg-accent/30"
32
- ),
33
- children: [
34
- /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: current ? /* @__PURE__ */ jsxs("div", { children: [
35
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: current.label }),
36
- current.description && /* @__PURE__ */ jsx("span", { className: "ml-2 text-xs text-muted-foreground", children: current.description })
37
- ] }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder }) }),
38
- /* @__PURE__ */ jsx(Select.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-[var(--transition-fast)] data-[state=open]:rotate-180" }) })
39
- ]
40
- }
41
- ),
42
- /* @__PURE__ */ jsx(Select.Portal, { children: /* @__PURE__ */ jsx(
43
- Select.Content,
44
- {
45
- position: "popper",
46
- sideOffset: 4,
47
- className: cn(
48
- "z-50 w-[var(--radix-select-trigger-width)] overflow-hidden",
49
- "rounded-[var(--radius-md)] border border-border",
50
- "bg-card shadow-[var(--shadow-dropdown)]",
51
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
52
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
53
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
54
- "data-[side=bottom]:slide-in-from-top-1"
55
- ),
56
- children: /* @__PURE__ */ jsx(Select.Viewport, { className: "p-1", children: backends.map((backend) => /* @__PURE__ */ jsxs(
57
- Select.Item,
58
- {
59
- value: backend.type,
60
- className: cn(
61
- "relative flex cursor-pointer select-none flex-col rounded-[var(--radius-sm)]",
62
- "px-3 py-2.5 text-sm outline-none",
63
- "transition-colors duration-[var(--transition-fast)]",
64
- "hover:bg-accent/50 focus:bg-accent/50",
65
- "data-[state=checked]:bg-[var(--accent-surface-soft)] data-[state=checked]:text-[var(--brand-primary)]"
66
- ),
67
- children: [
68
- /* @__PURE__ */ jsx(Select.ItemText, { children: /* @__PURE__ */ jsx("span", { className: "font-medium", children: backend.label }) }),
69
- backend.description && /* @__PURE__ */ jsx("span", { className: "mt-0.5 text-xs text-muted-foreground data-[state=checked]:text-[var(--accent-text)]", children: backend.description })
70
- ]
71
- },
72
- backend.type
73
- )) })
74
- }
75
- ) })
76
- ] })
77
- ] });
78
- }
79
-
80
- // src/dashboard/harness-picker.tsx
81
- import { jsx as jsx2 } from "react/jsx-runtime";
82
- var HARNESS_OPTIONS = [
83
- {
84
- type: "opencode",
85
- label: "OpenCode",
86
- description: "Default agent \u2014 broad model support, deterministic streaming"
87
- },
88
- {
89
- type: "claude-code",
90
- label: "Claude Code",
91
- description: "Native Claude skills and tools (requires ANTHROPIC_API_KEY)"
92
- },
93
- {
94
- type: "codex",
95
- label: "Codex",
96
- description: "OpenAI Codex CLI (requires OPENAI_API_KEY)"
97
- },
98
- {
99
- type: "amp",
100
- label: "AMP",
101
- description: "Sourcegraph AMP agent"
102
- },
103
- {
104
- type: "factory-droids",
105
- label: "Factory Droids",
106
- description: "Factory Droid agent"
107
- },
108
- {
109
- type: "cli-base",
110
- label: "CLI base (no agent)",
111
- description: "Shell tools only \u2014 for non-AI scheduled tasks"
112
- }
113
- ];
114
- function HarnessPicker({
115
- value,
116
- onChange,
117
- available,
118
- optionsOverride,
119
- label = "Agent harness",
120
- ...rest
121
- }) {
122
- const allowed = new Set(available ?? HARNESS_OPTIONS.map((h) => h.type));
123
- const backends = HARNESS_OPTIONS.filter((h) => allowed.has(h.type)).map((h) => {
124
- const override = optionsOverride?.[h.type];
125
- return {
126
- type: h.type,
127
- label: override?.label ?? h.label,
128
- description: override?.description ?? h.description
129
- };
130
- });
131
- return /* @__PURE__ */ jsx2(
132
- BackendSelector,
133
- {
134
- backends,
135
- selected: value,
136
- onChange: (next) => onChange(next),
137
- label,
138
- ...rest
139
- }
140
- );
141
- }
142
-
143
- export {
144
- BackendSelector,
145
- HARNESS_OPTIONS,
146
- HarnessPicker
147
- };
File without changes