@workerdeck/ui 3.4.0 → 3.6.1

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/build/index.mjs CHANGED
@@ -2,11 +2,11 @@ import { $ as Composer, $t as Splitter, A as PermissionPrompt, An as badgeVarian
2
2
  import { C as rateLimitWindowSeconds, S as friendlyModel, _ as formatDuration, b as formatRelativeTime, c as tightestWindow, g as formatCountdown, h as formatCost, i as meterSeverity, m as formatBytes, o as modelLabel, p as formatAgoPrecise, r as meterColorClass, s as statusPresentation, t as contextSeverity, u as windowLabel, v as formatRateLimitWindow, w as toolInputPreview, x as formatTokens, y as formatRateLimitWindowLong } from "./status-kmsBhuFG.mjs";
3
3
  import { Fragment, useEffect, useMemo, useRef, useState } from "react";
4
4
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
5
- import { Anchor, ArrowRight, Atom, Beaker, BedDouble, BellRing, Bike, Binary, Blocks, Bot, Box, Brain, Briefcase, Brush, Bug, Building2, Cable, Camera, Car, Cat, Check, ChevronDown, Circle, CircleAlert, CircleSlash, CircuitBoard, Cloud, Code, Coffee, Cog, Compass, Container, Cpu, CreditCard, Database, Diamond, Dog, Eraser, Feather, Film, Filter, Flame, FlaskConical, Folder, FolderOpen, Gamepad2, Gauge, Gem, Ghost, Gift, GitBranch, Globe, GraduationCap, GripVertical, Hammer, Hexagon, House, Image, Key, Landmark, Laptop, Layers, Leaf, Library, Lightbulb, Lock, Mail, Map as Map$1, MessageCircle, Mic, Monitor, Moon, Mountain, Music, Network, Newspaper, Notebook, Orbit, Package, Palette, PauseCircle, PenTool, Pencil, Phone, PiggyBank, Plane, Plug, Plus, Puzzle, Radar, Radio, Receipt, Rocket, Ruler, Satellite, Scale, Scissors, Search, SearchX, Server, Shield, Ship, ShoppingCart, Signal, Smartphone, Sparkles, Sprout, Square, Star, Sun, Table, Tag, Target, Telescope, Terminal, TestTube, Trash2, TreePine, Trophy, Truck, Umbrella, Users, Wallet, Wand, Waves, Webhook, Wifi, Wrench, X, Zap } from "lucide-react";
5
+ import { Anchor, ArrowRight, Atom, Beaker, BedDouble, BellRing, Bike, Binary, Blocks, Bot, Box, Brain, Briefcase, Brush, Bug, Building2, Cable, Camera, Car, Cat, Check, ChevronDown, ChevronRight, Circle, CircleAlert, CircleSlash, CircuitBoard, Cloud, Code, Coffee, Cog, Compass, Container, Cpu, CreditCard, Database, Diamond, Dog, Eraser, Feather, Film, Filter, Flame, FlaskConical, Folder, FolderOpen, Gamepad2, Gauge, Gem, Ghost, Gift, GitBranch, Globe, GraduationCap, GripVertical, Hammer, Hexagon, House, Image, Key, Landmark, Laptop, Layers, Leaf, Library, Lightbulb, Lock, Mail, Map as Map$1, MessageCircle, Mic, Monitor, Moon, Mountain, Music, Network, Newspaper, Notebook, Orbit, Package, Palette, PauseCircle, PenTool, Pencil, Phone, PiggyBank, Plane, Plug, Plus, Puzzle, Radar, Radio, Receipt, Rocket, Ruler, Satellite, Scale, Scissors, Search, SearchX, Server, Shield, Ship, ShoppingCart, Signal, Smartphone, Sparkles, Sprout, Square, Star, Sun, Table, Tag, Target, Telescope, Terminal, TestTube, Trash2, TreePine, Trophy, Truck, Umbrella, Users, Wallet, Wand, Waves, Webhook, Wifi, Wrench, X, Zap } from "lucide-react";
6
6
  import { AlertDialog as AlertDialog$1 } from "@base-ui/react/alert-dialog";
7
7
  import { Popover as Popover$1 } from "@base-ui/react/popover";
8
8
  import { Toaster as Toaster$1, toast } from "sonner";
9
- import { STATE_LABELS, STATE_ORDER, adaptersOf, addCustomGroup, clearFilters, displayCustomized, displayedTasks, facetFilterCount, filterRows, groupRows, hasFacetFilter, isAgentRecord, moveCustomGroup, moveToCustomGroup, newCustomGroupId, projectLabel, projectName, projectSubpath, projectsOf, removeCustomGroup, renameCustomGroup, scopeActive, sessionKey, sessionLabel, subagentLabel, subsetSummary, taskSummary, visibleShells, visibleSubagents, visibleTasks } from "@workerdeck/protocol";
9
+ import { PROJECT_ACCENTS, STATE_LABELS, STATE_ORDER, adaptersOf, addCustomGroup, clearFilters, customGroupColor, displayCustomized, displayedTasks, facetFilterCount, filterRows, groupRows, hasFacetFilter, isAgentRecord, isTeamCollapsed, moveCustomGroup, moveToCustomGroup, newCustomGroupId, projectLabel, projectName, projectSubpath, projectsOf, removeCustomGroup, renameCustomGroup, scopeActive, sessionKey, sessionLabel, styleCustomGroup, subagentLabel, subsetSummary, taskSummary, teamSummary, toggleTeamCollapsed, visibleShells, visibleSubagents, visibleTasks } from "@workerdeck/protocol";
10
10
  //#region src/components/ui/Card.tsx
11
11
  function Card({ className, ...props }) {
12
12
  return /* @__PURE__ */ jsx("div", {
@@ -377,6 +377,174 @@ function SessionList({ sessions, activeId, onSelect, onDelete, emptyText = "No s
377
377
  });
378
378
  }
379
379
  //#endregion
380
+ //#region src/components/agent/EngineIcon.tsx
381
+ const PATHS = {
382
+ claude: {
383
+ title: "Claude",
384
+ d: "M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z"
385
+ },
386
+ codex: {
387
+ title: "OpenAI",
388
+ d: "M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"
389
+ },
390
+ gemini: {
391
+ title: "Gemini",
392
+ d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z"
393
+ },
394
+ deepseek: {
395
+ title: "DeepSeek",
396
+ d: "M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.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-.156-.708-.311-.955-.65-.172-.241-.219-.51-.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.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z"
397
+ },
398
+ moonshot: {
399
+ title: "Moonshot",
400
+ d: "M1.052 16.916l9.539 2.552a21.007 21.007 0 00.06 2.033l5.956 1.593a11.997 11.997 0 01-5.586.865l-.18-.016-.044-.004-.084-.009-.094-.01a11.605 11.605 0 01-.157-.02l-.107-.014-.11-.016a11.962 11.962 0 01-.32-.051l-.042-.008-.075-.013-.107-.02-.07-.015-.093-.019-.075-.016-.095-.02-.097-.023-.094-.022-.068-.017-.088-.022-.09-.024-.095-.025-.082-.023-.109-.03-.062-.02-.084-.025-.093-.028-.105-.034-.058-.019-.08-.026-.09-.031-.066-.024a6.293 6.293 0 01-.044-.015l-.068-.025-.101-.037-.057-.022-.08-.03-.087-.035-.088-.035-.079-.032-.095-.04-.063-.028-.063-.027a5.655 5.655 0 01-.041-.018l-.066-.03-.103-.047-.052-.024-.096-.046-.062-.03-.084-.04-.086-.044-.093-.047-.052-.027-.103-.055-.057-.03-.058-.032a6.49 6.49 0 01-.046-.026l-.094-.053-.06-.034-.051-.03-.072-.041-.082-.05-.093-.056-.052-.032-.084-.053-.061-.039-.079-.05-.07-.047-.053-.035a7.785 7.785 0 01-.054-.036l-.044-.03-.044-.03a6.066 6.066 0 01-.04-.028l-.057-.04-.076-.054-.069-.05-.074-.054-.056-.042-.076-.057-.076-.059-.086-.067-.045-.035-.064-.052-.074-.06-.089-.073-.046-.039-.046-.039a7.516 7.516 0 01-.043-.037l-.045-.04-.061-.053-.07-.062-.068-.06-.062-.058-.067-.062-.053-.05-.088-.084a13.28 13.28 0 01-.099-.097l-.029-.028-.041-.042-.069-.07-.05-.051-.05-.053a6.457 6.457 0 01-.168-.179l-.08-.088-.062-.07-.071-.08-.042-.049-.053-.062-.058-.068-.046-.056a7.175 7.175 0 01-.027-.033l-.045-.055-.066-.082-.041-.052-.05-.064-.02-.025a11.99 11.99 0 01-1.44-2.402zm-1.02-5.794l11.353 3.037a20.468 20.468 0 00-.469 2.011l10.817 2.894a12.076 12.076 0 01-1.845 2.005L.657 15.923l-.016-.046-.035-.104a11.965 11.965 0 01-.05-.153l-.007-.023a11.896 11.896 0 01-.207-.741l-.03-.126-.018-.08-.021-.097-.018-.081-.018-.09-.017-.084-.018-.094c-.026-.141-.05-.283-.071-.426l-.017-.118-.011-.083-.013-.102a12.01 12.01 0 01-.019-.161l-.005-.047a12.12 12.12 0 01-.034-2.145zm1.593-5.15l11.948 3.196c-.368.605-.705 1.231-1.01 1.875l11.295 3.022c-.142.82-.368 1.612-.668 2.365l-11.55-3.09L.124 10.26l.015-.1.008-.049.01-.067.015-.087.018-.098c.026-.148.056-.295.088-.442l.028-.124.02-.085.024-.097c.022-.09.045-.18.07-.268l.028-.102.023-.083.03-.1.025-.082.03-.096.026-.082.031-.095a11.896 11.896 0 011.01-2.232zm4.442-4.4L17.352 4.59a20.77 20.77 0 00-1.688 1.721l7.823 2.093c.267.852.442 1.744.513 2.665L2.106 5.213l.045-.065.027-.04.04-.055.046-.065.055-.076.054-.072.064-.086.05-.065.057-.073.055-.07.06-.074.055-.069.065-.077.054-.066.066-.077.053-.06.072-.082.053-.06.067-.074.054-.058.073-.078.058-.06.063-.067.168-.17.1-.098.059-.056.076-.071a12.084 12.084 0 012.272-1.677zM12.017 0h.097l.082.001.069.001.054.002.068.002.046.001.076.003.047.002.06.003.054.002.087.005.105.007.144.011.088.007.044.004.077.008.082.008.047.005.102.012.05.006.108.014.081.01.042.006.065.01.207.032.07.012.065.011.14.026.092.018.11.022.046.01.075.016.041.01L14.7.3l.042.01.065.015.049.012.071.017.096.024.112.03.113.03.113.032.05.015.07.02.078.024.073.023.05.016.05.016.076.025.099.033.102.036.048.017.064.023.093.034.11.041.116.045.1.04.047.02.06.024.041.018.063.026.04.018.057.025.11.048.1.046.074.035.075.036.06.028.092.046.091.045.102.052.053.028.049.026.046.024.06.033.041.022.052.029.088.05.106.06.087.051.057.034.053.032.096.059.088.055.098.062.036.024.064.041.084.056.04.027.062.042.062.043.023.017c.054.037.108.075.161.114l.083.06.065.048.056.043.086.065.082.064.04.03.05.041.086.069.079.065.085.071c.712.6 1.353 1.283 1.909 2.031L7.222.994l.062-.027.065-.028.081-.034.086-.035c.113-.045.227-.09.341-.131l.096-.035.093-.033.084-.03.096-.031c.087-.03.176-.058.264-.085l.091-.027.086-.025.102-.03.085-.023.1-.026L9.04.37l.09-.023.091-.022.095-.022.09-.02.098-.021.091-.02.095-.018.092-.018.1-.018.091-.016.098-.017.092-.014.097-.015.092-.013.102-.013.091-.012.105-.012.09-.01.105-.01c.093-.01.186-.018.28-.024l.106-.008.09-.005.11-.006.093-.004.1-.004.097-.002.099-.002.197-.002z"
401
+ }
402
+ };
403
+ function engineMark(engine, model) {
404
+ if (engine === "claude") return "claude";
405
+ if (engine === "codex") return "codex";
406
+ const id = model?.toLowerCase() ?? "";
407
+ if (!id) return;
408
+ if (id.includes("gemini")) return "gemini";
409
+ if (id.includes("deepseek")) return "deepseek";
410
+ if (id.includes("moonshot") || id.includes("kimi")) return "moonshot";
411
+ if (id.includes("claude")) return "claude";
412
+ if (id.startsWith("gpt") || id.startsWith("o1") || id.startsWith("o3") || id.includes("openai")) return "codex";
413
+ }
414
+ const VENDOR_MARK = {
415
+ claude: "text-vendor-claude",
416
+ codex: "text-vendor-openai"
417
+ };
418
+ const VENDOR_TEXT = { claude: "text-vendor-claude" };
419
+ function vendorMarkClass(engine, model) {
420
+ return VENDOR_MARK[engineMark(engine, model) ?? ""] ?? "text-fg-3";
421
+ }
422
+ function vendorTextClass(engine, model) {
423
+ return VENDOR_TEXT[engineMark(engine, model) ?? ""] ?? "text-fg-3";
424
+ }
425
+ function EngineIcon({ engine, model, className }) {
426
+ const mark = PATHS[engineMark(engine, model) ?? ""];
427
+ if (!mark) return /* @__PURE__ */ jsx("span", {
428
+ "aria-hidden": true,
429
+ title: engine,
430
+ className: cn("shrink-0 text-fg-3", className),
431
+ children: "·"
432
+ });
433
+ return /* @__PURE__ */ jsxs("svg", {
434
+ viewBox: "0 0 24 24",
435
+ fill: "currentColor",
436
+ fillRule: "evenodd",
437
+ role: "img",
438
+ "aria-label": mark.title,
439
+ className: cn("size-3 shrink-0 text-fg-3", className),
440
+ children: [/* @__PURE__ */ jsx("title", { children: mark.title }), /* @__PURE__ */ jsx("path", { d: mark.d })]
441
+ });
442
+ }
443
+ //#endregion
444
+ //#region src/components/agent/SessionStatusIcon.tsx
445
+ function SessionStatusIcon({ row, className }) {
446
+ const { info } = row;
447
+ const size = cn("size-4 shrink-0", className);
448
+ if (row.state === "attention") return /* @__PURE__ */ jsx(BellRing, { className: cn(size, "animate-pulse text-warning") });
449
+ if (row.state === "working") return /* @__PURE__ */ jsx(Spinner, { className: cn(size, "text-info") });
450
+ switch (info.status) {
451
+ case "failed": return /* @__PURE__ */ jsx(CircleAlert, { className: cn(size, "text-danger") });
452
+ case "closed": return /* @__PURE__ */ jsx(CircleSlash, { className: cn(size, "text-fg-4") });
453
+ case "parked": return /* @__PURE__ */ jsx(PauseCircle, { className: cn(size, "text-fg-3") });
454
+ default: return /* @__PURE__ */ jsx(Moon, { className: cn(size, "text-fg-4") });
455
+ }
456
+ }
457
+ //#endregion
458
+ //#region src/components/agent/AgentAvatar.tsx
459
+ function avatarOf(avatars, agent) {
460
+ return agent?.avatar === void 0 ? void 0 : avatars?.[agent.avatar];
461
+ }
462
+ function AgentAvatar({ row, image, size = 32, state, badge = true, className }) {
463
+ const { info } = row;
464
+ const shown = state ?? row.state;
465
+ const busy = shown === "working" && image?.busy && image.busy.durations.length > 1 ? image.busy : void 0;
466
+ const asleep = info.engineAsleep === true;
467
+ const engine = info.engine ?? "claude";
468
+ const badgeSize = size >= 28 ? 14 : 11;
469
+ return /* @__PURE__ */ jsxs("span", {
470
+ "data-slot": "agent-avatar",
471
+ className: cn("relative inline-flex shrink-0", className),
472
+ style: {
473
+ width: size,
474
+ height: size
475
+ },
476
+ title: info.agent?.name,
477
+ children: [busy ? /* @__PURE__ */ jsx("span", {
478
+ "aria-hidden": true,
479
+ className: "wd-avatar-strip size-full rounded-[4px]",
480
+ style: {
481
+ backgroundImage: `url(${busy.src})`,
482
+ backgroundSize: `${busy.durations.length * size}px ${size}px`,
483
+ "--wd-strip-end": `-${busy.durations.length * size}px`,
484
+ "--wd-strip-steps": busy.durations.length,
485
+ animationDuration: `${busy.durations.reduce((sum, ms) => sum + ms, 0)}ms`
486
+ }
487
+ }) : image ? /* @__PURE__ */ jsx("img", {
488
+ src: image.still,
489
+ alt: "",
490
+ draggable: false,
491
+ className: cn("size-full rounded-[4px] [image-rendering:pixelated]", asleep && "opacity-60 grayscale")
492
+ }) : /* @__PURE__ */ jsx("span", {
493
+ className: "flex size-full items-center justify-center rounded-[4px] border border-dashed border-border",
494
+ children: /* @__PURE__ */ jsx(EngineIcon, {
495
+ engine,
496
+ model: info.model,
497
+ className: cn("size-1/2", vendorMarkClass(engine, info.model))
498
+ })
499
+ }), badge && (shown !== "idle" || asleep) ? /* @__PURE__ */ jsx("span", {
500
+ className: "absolute -right-1 -bottom-1 flex items-center justify-center rounded-full bg-bg",
501
+ style: {
502
+ width: badgeSize,
503
+ height: badgeSize
504
+ },
505
+ children: /* @__PURE__ */ jsx(SessionStatusIcon, {
506
+ row: {
507
+ ...row,
508
+ state: shown
509
+ },
510
+ className: "size-full p-px"
511
+ })
512
+ }) : null]
513
+ });
514
+ }
515
+ function LeadChip({ className }) {
516
+ return /* @__PURE__ */ jsx("span", {
517
+ className: cn("shrink-0 rounded-[3px] border border-accent/50 px-1 text-[0.625rem] leading-3.5 font-medium tracking-wide text-accent", className),
518
+ children: "LEAD"
519
+ });
520
+ }
521
+ function AgentHeading({ row, image, conversation, className }) {
522
+ const agent = row.info.agent;
523
+ if (!agent) return null;
524
+ const n = conversation ?? agent.conversation ?? 1;
525
+ const detail = [agent.lead !== void 0 && agent.team ? `${agent.team} team` : void 0, `conversation ${n}`].filter(Boolean).join(" · ");
526
+ return /* @__PURE__ */ jsxs("span", {
527
+ "data-slot": "agent-heading",
528
+ className: cn("flex min-w-0 items-center gap-2", className),
529
+ children: [
530
+ /* @__PURE__ */ jsx(AgentAvatar, {
531
+ row,
532
+ image,
533
+ size: 24
534
+ }),
535
+ /* @__PURE__ */ jsx("span", {
536
+ className: "truncate text-body-sm font-medium text-fg-1",
537
+ children: agent.name
538
+ }),
539
+ agent.leads ? /* @__PURE__ */ jsx(LeadChip, {}) : null,
540
+ detail ? /* @__PURE__ */ jsx("span", {
541
+ className: "shrink-0 text-label text-fg-4",
542
+ children: detail
543
+ }) : null
544
+ ]
545
+ });
546
+ }
547
+ //#endregion
380
548
  //#region src/components/agent/ProjectIcon.tsx
381
549
  const GLYPHS = {
382
550
  anchor: Anchor,
@@ -827,84 +995,6 @@ function ContextRing({ usage, engine, size = 11, className }) {
827
995
  });
828
996
  }
829
997
  //#endregion
830
- //#region src/components/agent/EngineIcon.tsx
831
- const PATHS = {
832
- claude: {
833
- title: "Claude",
834
- d: "M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z"
835
- },
836
- codex: {
837
- title: "OpenAI",
838
- d: "M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"
839
- },
840
- gemini: {
841
- title: "Gemini",
842
- d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z"
843
- },
844
- deepseek: {
845
- title: "DeepSeek",
846
- d: "M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.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-.156-.708-.311-.955-.65-.172-.241-.219-.51-.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.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z"
847
- },
848
- moonshot: {
849
- title: "Moonshot",
850
- d: "M1.052 16.916l9.539 2.552a21.007 21.007 0 00.06 2.033l5.956 1.593a11.997 11.997 0 01-5.586.865l-.18-.016-.044-.004-.084-.009-.094-.01a11.605 11.605 0 01-.157-.02l-.107-.014-.11-.016a11.962 11.962 0 01-.32-.051l-.042-.008-.075-.013-.107-.02-.07-.015-.093-.019-.075-.016-.095-.02-.097-.023-.094-.022-.068-.017-.088-.022-.09-.024-.095-.025-.082-.023-.109-.03-.062-.02-.084-.025-.093-.028-.105-.034-.058-.019-.08-.026-.09-.031-.066-.024a6.293 6.293 0 01-.044-.015l-.068-.025-.101-.037-.057-.022-.08-.03-.087-.035-.088-.035-.079-.032-.095-.04-.063-.028-.063-.027a5.655 5.655 0 01-.041-.018l-.066-.03-.103-.047-.052-.024-.096-.046-.062-.03-.084-.04-.086-.044-.093-.047-.052-.027-.103-.055-.057-.03-.058-.032a6.49 6.49 0 01-.046-.026l-.094-.053-.06-.034-.051-.03-.072-.041-.082-.05-.093-.056-.052-.032-.084-.053-.061-.039-.079-.05-.07-.047-.053-.035a7.785 7.785 0 01-.054-.036l-.044-.03-.044-.03a6.066 6.066 0 01-.04-.028l-.057-.04-.076-.054-.069-.05-.074-.054-.056-.042-.076-.057-.076-.059-.086-.067-.045-.035-.064-.052-.074-.06-.089-.073-.046-.039-.046-.039a7.516 7.516 0 01-.043-.037l-.045-.04-.061-.053-.07-.062-.068-.06-.062-.058-.067-.062-.053-.05-.088-.084a13.28 13.28 0 01-.099-.097l-.029-.028-.041-.042-.069-.07-.05-.051-.05-.053a6.457 6.457 0 01-.168-.179l-.08-.088-.062-.07-.071-.08-.042-.049-.053-.062-.058-.068-.046-.056a7.175 7.175 0 01-.027-.033l-.045-.055-.066-.082-.041-.052-.05-.064-.02-.025a11.99 11.99 0 01-1.44-2.402zm-1.02-5.794l11.353 3.037a20.468 20.468 0 00-.469 2.011l10.817 2.894a12.076 12.076 0 01-1.845 2.005L.657 15.923l-.016-.046-.035-.104a11.965 11.965 0 01-.05-.153l-.007-.023a11.896 11.896 0 01-.207-.741l-.03-.126-.018-.08-.021-.097-.018-.081-.018-.09-.017-.084-.018-.094c-.026-.141-.05-.283-.071-.426l-.017-.118-.011-.083-.013-.102a12.01 12.01 0 01-.019-.161l-.005-.047a12.12 12.12 0 01-.034-2.145zm1.593-5.15l11.948 3.196c-.368.605-.705 1.231-1.01 1.875l11.295 3.022c-.142.82-.368 1.612-.668 2.365l-11.55-3.09L.124 10.26l.015-.1.008-.049.01-.067.015-.087.018-.098c.026-.148.056-.295.088-.442l.028-.124.02-.085.024-.097c.022-.09.045-.18.07-.268l.028-.102.023-.083.03-.1.025-.082.03-.096.026-.082.031-.095a11.896 11.896 0 011.01-2.232zm4.442-4.4L17.352 4.59a20.77 20.77 0 00-1.688 1.721l7.823 2.093c.267.852.442 1.744.513 2.665L2.106 5.213l.045-.065.027-.04.04-.055.046-.065.055-.076.054-.072.064-.086.05-.065.057-.073.055-.07.06-.074.055-.069.065-.077.054-.066.066-.077.053-.06.072-.082.053-.06.067-.074.054-.058.073-.078.058-.06.063-.067.168-.17.1-.098.059-.056.076-.071a12.084 12.084 0 012.272-1.677zM12.017 0h.097l.082.001.069.001.054.002.068.002.046.001.076.003.047.002.06.003.054.002.087.005.105.007.144.011.088.007.044.004.077.008.082.008.047.005.102.012.05.006.108.014.081.01.042.006.065.01.207.032.07.012.065.011.14.026.092.018.11.022.046.01.075.016.041.01L14.7.3l.042.01.065.015.049.012.071.017.096.024.112.03.113.03.113.032.05.015.07.02.078.024.073.023.05.016.05.016.076.025.099.033.102.036.048.017.064.023.093.034.11.041.116.045.1.04.047.02.06.024.041.018.063.026.04.018.057.025.11.048.1.046.074.035.075.036.06.028.092.046.091.045.102.052.053.028.049.026.046.024.06.033.041.022.052.029.088.05.106.06.087.051.057.034.053.032.096.059.088.055.098.062.036.024.064.041.084.056.04.027.062.042.062.043.023.017c.054.037.108.075.161.114l.083.06.065.048.056.043.086.065.082.064.04.03.05.041.086.069.079.065.085.071c.712.6 1.353 1.283 1.909 2.031L7.222.994l.062-.027.065-.028.081-.034.086-.035c.113-.045.227-.09.341-.131l.096-.035.093-.033.084-.03.096-.031c.087-.03.176-.058.264-.085l.091-.027.086-.025.102-.03.085-.023.1-.026L9.04.37l.09-.023.091-.022.095-.022.09-.02.098-.021.091-.02.095-.018.092-.018.1-.018.091-.016.098-.017.092-.014.097-.015.092-.013.102-.013.091-.012.105-.012.09-.01.105-.01c.093-.01.186-.018.28-.024l.106-.008.09-.005.11-.006.093-.004.1-.004.097-.002.099-.002.197-.002z"
851
- }
852
- };
853
- function engineMark(engine, model) {
854
- if (engine === "claude") return "claude";
855
- if (engine === "codex") return "codex";
856
- const id = model?.toLowerCase() ?? "";
857
- if (!id) return;
858
- if (id.includes("gemini")) return "gemini";
859
- if (id.includes("deepseek")) return "deepseek";
860
- if (id.includes("moonshot") || id.includes("kimi")) return "moonshot";
861
- if (id.includes("claude")) return "claude";
862
- if (id.startsWith("gpt") || id.startsWith("o1") || id.startsWith("o3") || id.includes("openai")) return "codex";
863
- }
864
- const VENDOR_MARK = {
865
- claude: "text-vendor-claude",
866
- codex: "text-vendor-openai"
867
- };
868
- const VENDOR_TEXT = { claude: "text-vendor-claude" };
869
- function vendorMarkClass(engine, model) {
870
- return VENDOR_MARK[engineMark(engine, model) ?? ""] ?? "text-fg-3";
871
- }
872
- function vendorTextClass(engine, model) {
873
- return VENDOR_TEXT[engineMark(engine, model) ?? ""] ?? "text-fg-3";
874
- }
875
- function EngineIcon({ engine, model, className }) {
876
- const mark = PATHS[engineMark(engine, model) ?? ""];
877
- if (!mark) return /* @__PURE__ */ jsx("span", {
878
- "aria-hidden": true,
879
- title: engine,
880
- className: cn("shrink-0 text-fg-3", className),
881
- children: "·"
882
- });
883
- return /* @__PURE__ */ jsxs("svg", {
884
- viewBox: "0 0 24 24",
885
- fill: "currentColor",
886
- fillRule: "evenodd",
887
- role: "img",
888
- "aria-label": mark.title,
889
- className: cn("size-3 shrink-0 text-fg-3", className),
890
- children: [/* @__PURE__ */ jsx("title", { children: mark.title }), /* @__PURE__ */ jsx("path", { d: mark.d })]
891
- });
892
- }
893
- //#endregion
894
- //#region src/components/agent/SessionStatusIcon.tsx
895
- function SessionStatusIcon({ row, className }) {
896
- const { info } = row;
897
- const size = cn("size-4 shrink-0", className);
898
- if (row.state === "attention") return /* @__PURE__ */ jsx(BellRing, { className: cn(size, "animate-pulse text-warning") });
899
- if (row.state === "working") return /* @__PURE__ */ jsx(Spinner, { className: cn(size, "text-info") });
900
- switch (info.status) {
901
- case "failed": return /* @__PURE__ */ jsx(CircleAlert, { className: cn(size, "text-danger") });
902
- case "closed": return /* @__PURE__ */ jsx(CircleSlash, { className: cn(size, "text-fg-4") });
903
- case "parked": return /* @__PURE__ */ jsx(PauseCircle, { className: cn(size, "text-fg-3") });
904
- default: return /* @__PURE__ */ jsx(Moon, { className: cn(size, "text-fg-4") });
905
- }
906
- }
907
- //#endregion
908
998
  //#region src/components/agent/SessionSteps.tsx
909
999
  function sessionSteps(info, onSelect, show = "all", shells, tasks) {
910
1000
  const agents = visibleSubagents(info, show).filter(isAgentRecord).map((sub) => ({
@@ -1046,7 +1136,7 @@ const NO_MODIFIERS = {
1046
1136
  ctrl: false,
1047
1137
  alt: false
1048
1138
  };
1049
- function SessionItem({ row, active = false, activeStepKey, showGateway, showProject = true, projectIcons, subagents = "active", shells = "active", tasks = "active", onSelect, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite, now, onRename, renameOn = "doubleClick", editing, onEditingChange, actions, className }) {
1139
+ function SessionItem({ row, active = false, activeStepKey, showGateway, showProject = true, projectIcons, subagents = "active", shells = "active", tasks = "active", onSelect, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite, now, onRename, renameOn = "doubleClick", editing, onEditingChange, actions, avatars, variant = "card", badgeState, teamUnseen = 0, teamTray, tile = false, className }) {
1050
1140
  const { info } = row;
1051
1141
  const [ownEditing, setOwnEditing] = useState(false);
1052
1142
  const isEditing = editing ?? ownEditing;
@@ -1066,11 +1156,18 @@ function SessionItem({ row, active = false, activeStepKey, showGateway, showProj
1066
1156
  cost === "-" ? void 0 : cost
1067
1157
  ].filter((part) => Boolean(part));
1068
1158
  const model = friendlyModel(info.model);
1159
+ const status = statusLine(info.statusLabel);
1160
+ const needsYou = row.state === "attention" || row.teamState === "attention" || badgeState === "attention";
1069
1161
  const parts = [];
1070
1162
  if (model) parts.push(/* @__PURE__ */ jsx("span", {
1071
1163
  className: vendorTextClass(engine, info.model),
1072
1164
  children: model
1073
1165
  }, "model"));
1166
+ if (status) parts.push(/* @__PURE__ */ jsx("span", {
1167
+ title: status,
1168
+ className: "text-fg-3",
1169
+ children: status
1170
+ }, "status"));
1074
1171
  if (project !== void 0) parts.push(/* @__PURE__ */ jsxs("span", {
1075
1172
  title: projectTitle,
1076
1173
  children: [/* @__PURE__ */ jsx(ProjectIcon, {
@@ -1094,6 +1191,31 @@ function SessionItem({ row, active = false, activeStepKey, showGateway, showProj
1094
1191
  onStop: onStopTask
1095
1192
  });
1096
1193
  const holdsOpenStep = steps.some((s) => s.key === activeStepKey);
1194
+ const agent = info.agent;
1195
+ const label = agent ? agent.name : sessionLabel(info);
1196
+ const editable = agent ? agent.name : info.title ?? "";
1197
+ const time = formatRelativeTime(info.lastActivityAt ?? info.createdAt);
1198
+ const nameLabel = isEditing && onRename ? /* @__PURE__ */ jsx(NameEditor, {
1199
+ initial: editable,
1200
+ placeholder: agent ? "Agent name" : "Session name",
1201
+ onCommit: (title) => {
1202
+ setEditing(false);
1203
+ if (title !== editable && (title || !agent)) onRename(title);
1204
+ },
1205
+ onCancel: () => setEditing(false)
1206
+ }) : /* @__PURE__ */ jsx("span", {
1207
+ onDoubleClick: onRename && renameOn === "doubleClick" ? (e) => {
1208
+ e.stopPropagation();
1209
+ setEditing(true);
1210
+ } : void 0,
1211
+ className: "min-w-0 shrink truncate text-body-sm font-medium tracking-[-0.005em] text-fg-1",
1212
+ children: label
1213
+ });
1214
+ const unread = row.unseen > 0 ? /* @__PURE__ */ jsx("span", {
1215
+ title: `${row.unseen} new message${row.unseen === 1 ? "" : "s"}`,
1216
+ className: cn("flex h-4 min-w-6 shrink-0 items-center justify-center rounded-full px-2", "text-[0.75rem] leading-none tracking-[-0.005em] tabular-nums", row.state === "working" ? "bg-badge text-badge-fg" : "bg-accent text-accent-fg"),
1217
+ children: row.unseen
1218
+ }) : null;
1097
1219
  return /* @__PURE__ */ jsxs("div", {
1098
1220
  "data-slot": "session-item",
1099
1221
  "data-active": active || void 0,
@@ -1120,33 +1242,91 @@ function SessionItem({ row, active = false, activeStepKey, showGateway, showProj
1120
1242
  });
1121
1243
  }
1122
1244
  },
1123
- className: cn("group flex w-full cursor-pointer flex-col p-1 text-left outline-none", "rounded-[4px] transition-colors focus-visible:ring-2 focus-visible:ring-ring", holdsOpenStep ? "bg-row-selected-weak" : active ? "bg-row-selected" : "hover:bg-row-hover", className),
1124
- children: [/* @__PURE__ */ jsxs("div", {
1245
+ className: cn("group flex w-full cursor-pointer flex-col p-1 text-left outline-none", "rounded-[4px] transition-colors focus-visible:ring-2 focus-visible:ring-ring", needsYou ? cn("bg-row-attention", active && "ring-1 ring-accent ring-inset") : holdsOpenStep ? "bg-row-selected-weak" : active ? "bg-row-selected" : "hover:bg-row-hover", className),
1246
+ children: [agent && variant === "member" ? /* @__PURE__ */ jsxs("div", {
1247
+ className: cn("flex h-6 items-center gap-1.5 overflow-hidden py-0.5 pr-0.5 pl-1.5", info.engineAsleep && "opacity-60"),
1248
+ children: [
1249
+ /* @__PURE__ */ jsx(AgentAvatar, {
1250
+ row,
1251
+ image: avatarOf(avatars, agent),
1252
+ size: 22
1253
+ }),
1254
+ nameLabel,
1255
+ status ? /* @__PURE__ */ jsx("span", {
1256
+ title: status,
1257
+ className: "min-w-0 flex-1 truncate text-body-sm text-fg-3",
1258
+ children: status
1259
+ }) : /* @__PURE__ */ jsx("span", { className: "flex-1" }),
1260
+ unread,
1261
+ /* @__PURE__ */ jsx("span", {
1262
+ className: "shrink-0 text-body-sm text-fg-4",
1263
+ children: time
1264
+ }),
1265
+ actions
1266
+ ]
1267
+ }) : agent || tile ? /* @__PURE__ */ jsxs("div", {
1268
+ className: cn("flex items-center gap-2 py-0.5 pr-0.5 pl-1.5", info.engineAsleep && "opacity-60"),
1269
+ children: [/* @__PURE__ */ jsx(AgentAvatar, {
1270
+ row,
1271
+ image: avatarOf(avatars, agent),
1272
+ state: badgeState
1273
+ }), /* @__PURE__ */ jsxs("div", {
1274
+ className: "flex min-w-0 flex-1 flex-col gap-1",
1275
+ children: [/* @__PURE__ */ jsxs("div", {
1276
+ className: "flex h-5 items-center gap-1.5 overflow-hidden",
1277
+ children: [
1278
+ nameLabel,
1279
+ agent?.leads ? /* @__PURE__ */ jsx(LeadChip, {}) : null,
1280
+ agent ? /* @__PURE__ */ jsx("span", {
1281
+ className: "w-max max-w-max min-w-0 grow basis-0 truncate text-label text-fg-4/70",
1282
+ children: time
1283
+ }) : null,
1284
+ /* @__PURE__ */ jsx("span", { className: "flex-1" }),
1285
+ unread,
1286
+ teamUnseen > 0 ? /* @__PURE__ */ jsxs("span", {
1287
+ title: `${teamUnseen} new message${teamUnseen === 1 ? "" : "s"} in the team`,
1288
+ className: "flex h-4 shrink-0 items-center gap-0.5 rounded-full bg-accent px-1.5 text-[0.75rem] leading-none text-accent-fg tabular-nums",
1289
+ children: [/* @__PURE__ */ jsx(Users, { className: "size-3" }), teamUnseen]
1290
+ }) : null,
1291
+ teamTray,
1292
+ /* @__PURE__ */ jsx(ContextRing, {
1293
+ usage: info.contextUsage,
1294
+ engine,
1295
+ size: 16,
1296
+ className: "p-0.5"
1297
+ })
1298
+ ]
1299
+ }), /* @__PURE__ */ jsxs("div", {
1300
+ className: "flex h-5 items-center gap-1.5 overflow-hidden text-body-sm tracking-[-0.005em]",
1301
+ children: [
1302
+ agent ? /* @__PURE__ */ jsxs(Fragment$1, { children: [model ? /* @__PURE__ */ jsx("span", {
1303
+ className: cn("shrink-0", vendorTextClass(engine, info.model)),
1304
+ children: model
1305
+ }) : null, status ? /* @__PURE__ */ jsxs("span", {
1306
+ title: status,
1307
+ className: "min-w-0 truncate text-fg-3",
1308
+ children: [model ? "· " : "", status]
1309
+ }) : null] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
1310
+ className: "min-w-0 truncate text-fg-4",
1311
+ children: parts.map((part, i) => /* @__PURE__ */ jsxs(Fragment, { children: [i > 0 ? " · " : "", part] }, i))
1312
+ }), /* @__PURE__ */ jsxs("span", {
1313
+ className: "shrink-0 text-fg-4",
1314
+ children: [parts.length > 0 ? "· " : "", time]
1315
+ })] }),
1316
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1" }),
1317
+ actions
1318
+ ]
1319
+ })]
1320
+ })]
1321
+ }) : /* @__PURE__ */ jsxs("div", {
1125
1322
  className: cn("flex flex-col gap-1 py-0.5 pr-0.5 pl-1.5", info.engineAsleep && "opacity-60"),
1126
1323
  children: [/* @__PURE__ */ jsxs("div", {
1127
1324
  className: "flex h-5 items-center gap-1.5 overflow-hidden",
1128
1325
  children: [
1129
1326
  /* @__PURE__ */ jsx(Gutter, { children: /* @__PURE__ */ jsx(SessionStatusIcon, { row }) }),
1130
- isEditing && onRename ? /* @__PURE__ */ jsx(NameEditor, {
1131
- initial: info.title ?? "",
1132
- onCommit: (title) => {
1133
- setEditing(false);
1134
- if (title !== (info.title ?? "")) onRename(title);
1135
- },
1136
- onCancel: () => setEditing(false)
1137
- }) : /* @__PURE__ */ jsx("span", {
1138
- onDoubleClick: onRename && renameOn === "doubleClick" ? (e) => {
1139
- e.stopPropagation();
1140
- setEditing(true);
1141
- } : void 0,
1142
- className: "min-w-0 flex-1 truncate text-body-sm font-medium tracking-[-0.005em] text-fg-1",
1143
- children: sessionLabel(info)
1144
- }),
1145
- row.unseen > 0 ? /* @__PURE__ */ jsx("span", {
1146
- title: `${row.unseen} new message${row.unseen === 1 ? "" : "s"}`,
1147
- className: cn("flex h-4 min-w-6 shrink-0 items-center justify-center rounded-full px-2", "text-[0.75rem] leading-none tracking-[-0.005em] tabular-nums", row.state === "working" ? "bg-badge text-badge-fg" : "bg-accent text-accent-fg"),
1148
- children: row.unseen
1149
- }) : null,
1327
+ nameLabel,
1328
+ /* @__PURE__ */ jsx("span", { className: "flex-1" }),
1329
+ unread,
1150
1330
  /* @__PURE__ */ jsx(ContextRing, {
1151
1331
  usage: info.contextUsage,
1152
1332
  engine,
@@ -1168,7 +1348,7 @@ function SessionItem({ row, active = false, activeStepKey, showGateway, showProj
1168
1348
  }),
1169
1349
  /* @__PURE__ */ jsxs("span", {
1170
1350
  className: "shrink-0 text-fg-4",
1171
- children: [parts.length > 0 ? "· " : "", formatRelativeTime(info.lastActivityAt ?? info.createdAt)]
1351
+ children: [parts.length > 0 ? "· " : "", time]
1172
1352
  }),
1173
1353
  /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1" }),
1174
1354
  actions
@@ -1190,7 +1370,7 @@ function Gutter({ children }) {
1190
1370
  children
1191
1371
  });
1192
1372
  }
1193
- function NameEditor({ initial, onCommit, onCancel }) {
1373
+ function NameEditor({ initial, placeholder, onCommit, onCancel }) {
1194
1374
  const [value, setValue] = useState(initial);
1195
1375
  const ref = useRef(null);
1196
1376
  useEffect(() => {
@@ -1209,8 +1389,8 @@ function NameEditor({ initial, onCommit, onCancel }) {
1209
1389
  ref,
1210
1390
  value,
1211
1391
  spellCheck: false,
1212
- placeholder: "Session name",
1213
- "aria-label": "Session name",
1392
+ placeholder,
1393
+ "aria-label": placeholder,
1214
1394
  onClick: (e) => e.stopPropagation(),
1215
1395
  onDoubleClick: (e) => e.stopPropagation(),
1216
1396
  onChange: (e) => setValue(e.target.value),
@@ -1225,11 +1405,60 @@ function NameEditor({ initial, onCommit, onCancel }) {
1225
1405
  className: cn("-my-0.5 min-w-0 flex-1 rounded-sm border border-ring bg-bg px-1 py-px", "text-body-sm leading-5 text-fg-1 outline-none")
1226
1406
  });
1227
1407
  }
1408
+ function statusLine(label) {
1409
+ return label ? label.emoji ? `${label.emoji} ${label.text}` : label.text : void 0;
1410
+ }
1411
+ //#endregion
1412
+ //#region src/lib/team-drop.ts
1413
+ function dropZone(offsetY, height) {
1414
+ if (height <= 0) return "join";
1415
+ const at = offsetY / height;
1416
+ return at < .25 ? "before" : at > .75 ? "after" : "join";
1417
+ }
1418
+ function teamDropRefusal(dragged, lead) {
1419
+ const mover = dragged.info.agent;
1420
+ const target = lead.info.agent;
1421
+ if (dragged.hostId !== lead.hostId) return "a team stays on one gateway";
1422
+ if (!target) return "only an agent can lead a team";
1423
+ if (mover?.id === target.id || dragged.info.id === lead.info.id) return "an agent cannot lead its own team";
1424
+ if (target.lead !== void 0) return `${target.name} is a member of a team; teams are one level deep`;
1425
+ if (mover?.leads) return `${mover.name} leads a team; teams are one level deep`;
1426
+ }
1427
+ function memberDrop(dragged, lead, member, zone) {
1428
+ const refusal = teamDropRefusal(dragged, lead);
1429
+ if (refusal) return refusal;
1430
+ const others = (lead.members ?? []).filter((row) => row.info.id !== dragged.info.id || row.hostId !== dragged.hostId);
1431
+ const at = others.findIndex((row) => row.info.id === member.info.id && row.hostId === member.hostId);
1432
+ return placeMember(dragged, lead, others, at < 0 ? others.length : zone === "before" ? at : at + 1);
1433
+ }
1434
+ function joinDrop(dragged, lead) {
1435
+ const refusal = teamDropRefusal(dragged, lead);
1436
+ if (refusal) return refusal;
1437
+ const others = (lead.members ?? []).filter((row) => row.info.id !== dragged.info.id || row.hostId !== dragged.hostId);
1438
+ return placeMember(dragged, lead, others, others.length);
1439
+ }
1440
+ function placeMember(dragged, lead, others, index) {
1441
+ const siblings = others.map((row, i) => ({
1442
+ row,
1443
+ order: i < index ? i : i + 1
1444
+ })).filter(({ row, order }) => row.info.agent?.order !== order);
1445
+ return {
1446
+ row: dragged,
1447
+ lead,
1448
+ order: index,
1449
+ ...siblings.length ? { siblings } : {}
1450
+ };
1451
+ }
1228
1452
  //#endregion
1229
1453
  //#region src/components/agent/SessionGroups.tsx
1230
- function useGroupDrag(groups, onChange) {
1454
+ const ERROR_MS = 5e3;
1455
+ function useGroupDrag(groups, onChange, options) {
1456
+ const { custom, team } = options;
1231
1457
  const [item, setItem] = useState();
1232
1458
  const [over, setOver] = useState();
1459
+ const [failure, setFailure] = useState();
1460
+ const failureTimer = useRef(void 0);
1461
+ useEffect(() => () => clearTimeout(failureTimer.current), []);
1233
1462
  const end = () => {
1234
1463
  setItem(void 0);
1235
1464
  setOver(void 0);
@@ -1240,13 +1469,74 @@ function useGroupDrag(groups, onChange) {
1240
1469
  e.dataTransfer.setData("text/plain", next.kind === "session" ? next.key : next.id);
1241
1470
  setItem(next);
1242
1471
  };
1243
- const accept = (e, spot) => {
1472
+ const accept = (e, next) => {
1244
1473
  e.preventDefault();
1245
1474
  e.stopPropagation();
1246
- e.dataTransfer.dropEffect = "move";
1247
- setOver(spot);
1475
+ e.dataTransfer.dropEffect = next.refusal ? "none" : "move";
1476
+ if (over?.spot !== next.spot || over.refusal !== next.refusal) setOver(next);
1477
+ };
1478
+ const fail = (key, err) => {
1479
+ clearTimeout(failureTimer.current);
1480
+ setFailure({
1481
+ key,
1482
+ message: err instanceof Error ? err.message : String(err)
1483
+ });
1484
+ failureTimer.current = setTimeout(() => setFailure(void 0), ERROR_MS);
1485
+ };
1486
+ const move = (key, next) => () => {
1487
+ setFailure(void 0);
1488
+ Promise.resolve().then(() => team.onMove(next)).catch((err) => fail(key, err));
1248
1489
  };
1249
- function session(key, group) {
1490
+ function land(e, key, group, place) {
1491
+ if (item?.kind !== "session" || item.key === key) return;
1492
+ const reorder = custom ? {
1493
+ spot: `row:${key}`,
1494
+ run: () => onChange(moveToCustomGroup(groups, item.key, group.custom, group.custom ? key : void 0))
1495
+ } : void 0;
1496
+ const dragged = team?.rowOf(item.key);
1497
+ if (!team || !dragged || !place) return reorder;
1498
+ const rect = e.currentTarget.getBoundingClientRect();
1499
+ const zone = dropZone(e.clientY - rect.top, rect.height);
1500
+ if (place.lead) {
1501
+ const result = memberDrop(dragged, place.lead, place.row, zone);
1502
+ return typeof result === "string" ? {
1503
+ spot: `refused:${key}`,
1504
+ refusal: result
1505
+ } : {
1506
+ spot: `${zone === "before" ? "before" : "after"}:${key}`,
1507
+ run: move(key, result)
1508
+ };
1509
+ }
1510
+ if (zone === "join") {
1511
+ const result = joinDrop(dragged, place.row);
1512
+ if (typeof result !== "string") return {
1513
+ spot: `join:${key}`,
1514
+ run: move(key, result)
1515
+ };
1516
+ return reorder ?? {
1517
+ spot: `refused:${key}`,
1518
+ refusal: result
1519
+ };
1520
+ }
1521
+ if (dragged.info.agent?.lead !== void 0) {
1522
+ const leave = move(key, {
1523
+ row: dragged,
1524
+ lead: null
1525
+ });
1526
+ return {
1527
+ spot: `${zone}:${key}`,
1528
+ run: () => {
1529
+ leave();
1530
+ reorder?.run();
1531
+ }
1532
+ };
1533
+ }
1534
+ return reorder ? {
1535
+ ...reorder,
1536
+ spot: `${zone}:${key}`
1537
+ } : void 0;
1538
+ }
1539
+ function session(key, group, place) {
1250
1540
  return {
1251
1541
  draggable: true,
1252
1542
  onDragStart: (e) => start(e, {
@@ -1255,26 +1545,37 @@ function useGroupDrag(groups, onChange) {
1255
1545
  }),
1256
1546
  onDragEnd: end,
1257
1547
  onDragOver: (e) => {
1258
- if (item?.kind === "session") accept(e, `row:${key}`);
1548
+ const landing = land(e, key, group, place);
1549
+ if (landing) accept(e, landing);
1259
1550
  },
1260
1551
  onDrop: (e) => {
1261
- if (item?.kind !== "session") return;
1552
+ const landing = land(e, key, group, place);
1553
+ if (!landing) return;
1262
1554
  e.preventDefault();
1263
1555
  e.stopPropagation();
1264
- if (item.key !== key) onChange(moveToCustomGroup(groups, item.key, group.custom, group.custom ? key : void 0));
1556
+ landing.run?.();
1265
1557
  end();
1266
1558
  }
1267
1559
  };
1268
1560
  }
1269
1561
  function container(group) {
1562
+ const leaving = () => {
1563
+ const dragged = item?.kind === "session" ? team?.rowOf(item.key) : void 0;
1564
+ return dragged?.info.agent?.lead !== void 0 ? dragged : void 0;
1565
+ };
1270
1566
  return {
1271
1567
  onDragOver: (e) => {
1272
- if (item) accept(e, `group:${group.key}`);
1568
+ if (item && (custom || leaving())) accept(e, { spot: `group:${group.key}` });
1273
1569
  },
1274
1570
  onDrop: (e) => {
1275
1571
  e.preventDefault();
1276
- if (item?.kind === "session") onChange(moveToCustomGroup(groups, item.key, group.custom));
1277
- else if (item?.kind === "group") onChange(moveCustomGroup(groups, item.id, group.custom));
1572
+ const member = leaving();
1573
+ if (member) move(sessionKey(member), {
1574
+ row: member,
1575
+ lead: null
1576
+ })();
1577
+ if (custom && item?.kind === "session") onChange(moveToCustomGroup(groups, item.key, group.custom));
1578
+ else if (custom && item?.kind === "group") onChange(moveCustomGroup(groups, item.id, group.custom));
1278
1579
  end();
1279
1580
  }
1280
1581
  };
@@ -1291,9 +1592,24 @@ function useGroupDrag(groups, onChange) {
1291
1592
  onDragEnd: end
1292
1593
  };
1293
1594
  }
1595
+ function cue(key) {
1596
+ if (failure?.key === key) return {
1597
+ zone: "refused",
1598
+ message: failure.message
1599
+ };
1600
+ const spot = over?.spot;
1601
+ if (!spot || spot.slice(spot.indexOf(":") + 1) !== key) return {};
1602
+ const kind = spot.slice(0, spot.indexOf(":"));
1603
+ if (kind === "refused") return {
1604
+ zone: "refused",
1605
+ message: over?.refusal
1606
+ };
1607
+ return kind === "row" || kind === "before" ? { zone: "before" } : kind === "after" ? { zone: "after" } : kind === "join" ? { zone: "join" } : {};
1608
+ }
1294
1609
  return {
1295
1610
  dragging: item !== void 0,
1296
- isOver: (spot) => over === spot,
1611
+ isOver: (spot) => over?.spot === spot,
1612
+ cue,
1297
1613
  session,
1298
1614
  container,
1299
1615
  header,
@@ -1303,10 +1619,11 @@ function useGroupDrag(groups, onChange) {
1303
1619
  return id;
1304
1620
  },
1305
1621
  rename: (id, name) => onChange(renameCustomGroup(groups, id, name)),
1622
+ style: (id, look) => onChange(styleCustomGroup(groups, id, look)),
1306
1623
  remove: (id) => onChange(removeCustomGroup(groups, id))
1307
1624
  };
1308
1625
  }
1309
- function CustomGroupHeader({ group, editing, onEditingChange, onRename, onRemove, dragProps }) {
1626
+ function CustomGroupHeader({ group, look, editing, onEditingChange, onRename, onRemove, onStyle, dragProps }) {
1310
1627
  if (editing) return /* @__PURE__ */ jsx(GroupNameInput, {
1311
1628
  initial: group.label ?? "",
1312
1629
  onRename,
@@ -1317,9 +1634,13 @@ function CustomGroupHeader({ group, editing, onEditingChange, onRename, onRemove
1317
1634
  ...dragProps,
1318
1635
  label: group.label ?? "",
1319
1636
  count: group.rows.length,
1637
+ caps: !custom,
1320
1638
  className: cn("group/heading", custom && "cursor-grab"),
1321
1639
  onDoubleClick: custom ? () => onEditingChange(true) : void 0,
1322
- leading: custom ? /* @__PURE__ */ jsx(GripVertical, { className: "-ml-1.5 size-3 opacity-0 group-hover/heading:opacity-60" }) : void 0,
1640
+ leading: custom ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(GripVertical, { className: "-mr-1.5 -ml-1.5 size-3 opacity-0 group-hover/heading:opacity-60" }), look ? /* @__PURE__ */ jsx(GroupBadge, {
1641
+ group: look,
1642
+ onStyle
1643
+ }) : null] }) : void 0,
1323
1644
  actions: custom ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(HeadingAction, {
1324
1645
  label: "Rename group",
1325
1646
  onClick: () => onEditingChange(true),
@@ -1359,14 +1680,14 @@ function GroupNameInput({ initial, onRename, onDone }) {
1359
1680
  })
1360
1681
  });
1361
1682
  }
1362
- function GroupHeading({ label, count, leading, actions, className, ...rest }) {
1683
+ function GroupHeading({ label, count, leading, actions, caps = true, className, ...rest }) {
1363
1684
  return /* @__PURE__ */ jsxs("div", {
1364
1685
  ...rest,
1365
1686
  className: cn("group/heading flex min-h-5 items-center gap-2 px-2 text-label font-medium text-fg-4", className),
1366
1687
  children: [
1367
1688
  leading,
1368
1689
  /* @__PURE__ */ jsx("span", {
1369
- className: "min-w-0 truncate uppercase tracking-wide",
1690
+ className: cn("min-w-0 truncate", caps ? "uppercase tracking-wide" : "text-fg-3"),
1370
1691
  children: label
1371
1692
  }),
1372
1693
  /* @__PURE__ */ jsx("span", {
@@ -1403,12 +1724,100 @@ function NewGroupButton({ onClick }) {
1403
1724
  children: [/* @__PURE__ */ jsx(Plus, {}), "New group"]
1404
1725
  });
1405
1726
  }
1727
+ const ICON_PX = 64;
1728
+ function GroupBadge({ group, onStyle }) {
1729
+ const [error, setError] = useState();
1730
+ const file = useRef(null);
1731
+ const mark = group.icon ? /* @__PURE__ */ jsx("img", {
1732
+ src: group.icon,
1733
+ alt: "",
1734
+ className: "size-3.5 rounded-[3px] object-cover",
1735
+ draggable: false
1736
+ }) : /* @__PURE__ */ jsx("span", {
1737
+ className: "size-2 rounded-[2px]",
1738
+ style: { background: customGroupColor(group) }
1739
+ });
1740
+ if (!onStyle) return /* @__PURE__ */ jsx("span", {
1741
+ className: "flex size-3.5 shrink-0 items-center justify-center",
1742
+ children: mark
1743
+ });
1744
+ return /* @__PURE__ */ jsxs(Popover, { children: [/* @__PURE__ */ jsx(PopoverTrigger, { render: /* @__PURE__ */ jsx("button", {
1745
+ type: "button",
1746
+ "aria-label": `Colour or image for ${group.name}`,
1747
+ title: "Colour or image",
1748
+ onClick: (e) => e.stopPropagation(),
1749
+ onDoubleClick: (e) => e.stopPropagation(),
1750
+ className: "flex size-3.5 shrink-0 items-center justify-center rounded-[3px] hover:ring-1 hover:ring-border",
1751
+ children: mark
1752
+ }) }), /* @__PURE__ */ jsxs(PopoverContent, {
1753
+ align: "start",
1754
+ className: "flex w-44 flex-col gap-2",
1755
+ children: [
1756
+ /* @__PURE__ */ jsx("div", {
1757
+ className: "grid grid-cols-4 gap-1.5",
1758
+ children: PROJECT_ACCENTS.map((color) => /* @__PURE__ */ jsx("button", {
1759
+ type: "button",
1760
+ "aria-label": `Colour ${color}`,
1761
+ onClick: () => onStyle({
1762
+ color,
1763
+ icon: null
1764
+ }),
1765
+ className: cn("h-6 rounded-[4px] ring-offset-1 ring-offset-surface", !group.icon && customGroupColor(group) === color && "ring-2 ring-fg-3"),
1766
+ style: { background: color }
1767
+ }, color))
1768
+ }),
1769
+ /* @__PURE__ */ jsx("input", {
1770
+ ref: file,
1771
+ type: "file",
1772
+ accept: "image/*",
1773
+ className: "hidden",
1774
+ onChange: (e) => {
1775
+ const picked = e.target.files?.[0];
1776
+ e.target.value = "";
1777
+ if (!picked) return;
1778
+ setError(void 0);
1779
+ iconFromFile(picked).then((icon) => onStyle({ icon })).catch(() => setError("That image could not be read"));
1780
+ }
1781
+ }),
1782
+ /* @__PURE__ */ jsxs(Button, {
1783
+ variant: "outline",
1784
+ size: "xs",
1785
+ onClick: () => file.current?.click(),
1786
+ children: [/* @__PURE__ */ jsx(Image, {}), "Choose image…"]
1787
+ }),
1788
+ group.icon ? /* @__PURE__ */ jsx(Button, {
1789
+ variant: "ghost",
1790
+ size: "xs",
1791
+ onClick: () => onStyle({ icon: null }),
1792
+ children: "Remove image"
1793
+ }) : null,
1794
+ error ? /* @__PURE__ */ jsx("span", {
1795
+ className: "text-label text-danger",
1796
+ children: error
1797
+ }) : null
1798
+ ]
1799
+ })] });
1800
+ }
1801
+ async function iconFromFile(file) {
1802
+ const bitmap = await createImageBitmap(file);
1803
+ const canvas = document.createElement("canvas");
1804
+ canvas.width = ICON_PX;
1805
+ canvas.height = ICON_PX;
1806
+ const context = canvas.getContext("2d");
1807
+ if (!context) throw new Error("no canvas");
1808
+ const scale = Math.max(ICON_PX / bitmap.width, ICON_PX / bitmap.height);
1809
+ const width = bitmap.width * scale;
1810
+ const height = bitmap.height * scale;
1811
+ context.drawImage(bitmap, (ICON_PX - width) / 2, (ICON_PX - height) / 2, width, height);
1812
+ bitmap.close();
1813
+ return canvas.toDataURL("image/png");
1814
+ }
1406
1815
  //#endregion
1407
1816
  //#region src/components/agent/SessionBrowser.tsx
1408
1817
  function rowShapeClass(active) {
1409
1818
  return cn("px-2 py-1.5 hover:bg-row-hover", active ? "mr-1 ml-0 rounded-r-md border-l-4 border-l-accent" : "mx-1 rounded-md");
1410
1819
  }
1411
- function SessionBrowser({ rows, config, onConfigChange, scope, activeId, activeSubagentId, activeShellId, now, isActive = (row) => row.info.id === activeId, rowActions, gatewayCount, showSubset = true, onSelect, onDelete, onRename, onClearContext, onSleep, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite, onCreateInGroup, emptyState, showControls = true, showSearch = showControls, autoFocusSearch, projectIcons, className }) {
1820
+ function SessionBrowser({ rows, config, onConfigChange, scope, activeId, activeSubagentId, activeShellId, now, isActive = (row) => row.info.id === activeId, rowActions, gatewayCount, showSubset = true, onSelect, onDelete, onRename, onRenameAgent, onClearContext, onSleep, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite, avatars, onTeamMove, onCreateInGroup, emptyState, showControls = true, showSearch = showControls, autoFocusSearch, projectIcons, className }) {
1412
1821
  const rowGateways = useMemo(() => new Set(rows.map((row) => row.hostId)).size, [rows]);
1413
1822
  const gateways = gatewayCount ?? rowGateways;
1414
1823
  const visible = useMemo(() => filterRows(rows, config, scope), [
@@ -1416,28 +1825,56 @@ function SessionBrowser({ rows, config, onConfigChange, scope, activeId, activeS
1416
1825
  config,
1417
1826
  scope
1418
1827
  ]);
1419
- const groups = useMemo(() => groupRows(visible, config, { gatewayCount: gateways }), [
1828
+ const groups = useMemo(() => groupRows(visible, config, {
1829
+ gatewayCount: gateways,
1830
+ all: rows
1831
+ }), [
1420
1832
  visible,
1421
1833
  config,
1422
- gateways
1834
+ gateways,
1835
+ rows
1423
1836
  ]);
1424
1837
  const subset = subsetSummary(config, scope, visible.length, rows.length);
1838
+ const tiles = useMemo(() => rows.some((row) => row.info.agent !== void 0), [rows]);
1425
1839
  const custom = config.groupBy === "custom";
1426
1840
  const [editingGroup, setEditingGroup] = useState();
1427
1841
  const set = (patch) => onConfigChange({
1428
1842
  ...config,
1429
1843
  ...patch
1430
1844
  });
1431
- const drag = useGroupDrag(config.customGroups ?? [], (customGroups) => set({ customGroups }));
1845
+ const byKey = useMemo(() => new Map(rows.map((row) => [sessionKey(row), row])), [rows]);
1846
+ const drag = useGroupDrag(config.customGroups ?? [], (customGroups) => set({ customGroups }), {
1847
+ custom,
1848
+ team: onTeamMove ? {
1849
+ rowOf: (key) => byKey.get(key),
1850
+ onMove: onTeamMove
1851
+ } : void 0
1852
+ });
1853
+ const draggable = custom || onTeamMove !== void 0;
1432
1854
  const heading = (group) => {
1433
1855
  if (custom) return /* @__PURE__ */ jsx(CustomGroupHeader, {
1434
1856
  group,
1857
+ look: config.customGroups?.find((custom) => custom.id === group.custom),
1858
+ onStyle: (look) => group.custom && drag.style(group.custom, look),
1435
1859
  editing: group.custom !== void 0 && editingGroup === group.custom,
1436
1860
  onEditingChange: (editing) => setEditingGroup(editing ? group.custom : void 0),
1437
1861
  onRename: (name) => group.custom && drag.rename(group.custom, name),
1438
1862
  onRemove: () => group.custom && drag.remove(group.custom),
1439
1863
  dragProps: drag.header(group)
1440
1864
  });
1865
+ if (group.earlier) return /* @__PURE__ */ jsxs("button", {
1866
+ type: "button",
1867
+ "aria-expanded": config.earlierOpen === true,
1868
+ onClick: () => set({ earlierOpen: !config.earlierOpen }),
1869
+ className: "flex items-center gap-1 px-2 text-left text-label text-fg-4 hover:text-fg-2",
1870
+ children: [
1871
+ config.earlierOpen ? /* @__PURE__ */ jsx(ChevronDown, { className: "size-3.5" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "size-3.5" }),
1872
+ "Earlier · ",
1873
+ group.rows.length,
1874
+ " one-off session",
1875
+ group.rows.length === 1 ? "" : "s"
1876
+ ]
1877
+ });
1441
1878
  if (config.groupBy === "none" || !group.label) return null;
1442
1879
  const project = config.groupBy === "project";
1443
1880
  const target = project && group.hostId ? {
@@ -1521,43 +1958,67 @@ function SessionBrowser({ rows, config, onConfigChange, scope, activeId, activeS
1521
1958
  title: "Nothing here",
1522
1959
  description: "No session to show."
1523
1960
  }) : /* @__PURE__ */ jsxs("div", {
1524
- className: "flex flex-col gap-4 px-1",
1961
+ className: "flex flex-col gap-2 px-1",
1525
1962
  children: [groups.map((group) => /* @__PURE__ */ jsxs("div", {
1526
- ...custom ? drag.container(group) : {},
1527
- className: cn("flex flex-col gap-1 rounded-md", custom && drag.isOver(`group:${group.key}`) && "bg-row-hover/50"),
1963
+ ...draggable ? drag.container(group) : {},
1964
+ className: cn("flex flex-col gap-1 rounded-md", draggable && drag.isOver(`group:${group.key}`) && "bg-row-hover/50"),
1528
1965
  children: [
1529
1966
  heading(group),
1530
1967
  custom && group.custom !== void 0 && group.rows.length === 0 ? /* @__PURE__ */ jsx("div", {
1531
1968
  className: "mx-1 rounded-md border border-dashed border-border px-2 py-2 text-center text-label text-fg-4",
1532
1969
  children: "Drag sessions here"
1533
1970
  }) : null,
1534
- group.rows.map((row) => /* @__PURE__ */ jsx(SessionRowItem, {
1535
- dragProps: custom ? drag.session(sessionKey(row), group) : void 0,
1536
- dropTarget: custom && drag.isOver(`row:${sessionKey(row)}`),
1537
- row,
1538
- active: isActive(row),
1539
- activeSubagentId,
1540
- activeShellId,
1541
- actions: rowActions?.(row),
1542
- now,
1543
- showGateway: gateways > 1 && config.groupBy !== "project",
1544
- showProject: config.groupBy !== "project",
1545
- subagents: config.subagents,
1546
- shells: config.shells,
1547
- tasks: config.tasks,
1548
- projectIcons,
1549
- onSelect,
1550
- onDelete,
1551
- onRename,
1552
- onClearContext,
1553
- onSleep,
1554
- onSelectSubagent,
1555
- onSelectTask,
1556
- onStopTask,
1557
- onSelectShell,
1558
- onKillShell,
1559
- onShellAgentWrite
1560
- }, sessionKey(row)))
1971
+ group.earlier && !config.earlierOpen ? null : group.rows.map((row) => {
1972
+ const item = (member, variant, extra = {}) => /* @__PURE__ */ jsx(SessionRowItem, {
1973
+ dragProps: onTeamMove || custom && variant === "card" ? drag.session(sessionKey(member), group, variant === "member" ? {
1974
+ row: member,
1975
+ lead: row
1976
+ } : { row }) : void 0,
1977
+ dropCue: draggable ? drag.cue(sessionKey(member)) : void 0,
1978
+ row: member,
1979
+ variant,
1980
+ active: isActive(member),
1981
+ activeSubagentId,
1982
+ activeShellId,
1983
+ actions: rowActions?.(member),
1984
+ now,
1985
+ showGateway: gateways > 1 && config.groupBy !== "project",
1986
+ showProject: config.groupBy !== "project",
1987
+ subagents: config.subagents,
1988
+ shells: config.shells,
1989
+ tasks: config.tasks,
1990
+ projectIcons,
1991
+ avatars,
1992
+ tile: tiles,
1993
+ onSelect,
1994
+ onDelete,
1995
+ onRename: member.info.agent ? onRenameAgent : onRename,
1996
+ onClearContext,
1997
+ onSleep,
1998
+ onSelectSubagent,
1999
+ onSelectTask,
2000
+ onStopTask,
2001
+ onSelectShell,
2002
+ onKillShell,
2003
+ onShellAgentWrite,
2004
+ ...extra
2005
+ }, sessionKey(member));
2006
+ if (!row.members?.length) return item(row, "card", { className: row.context ? "opacity-50" : void 0 });
2007
+ const collapsed = isTeamCollapsed(config, row);
2008
+ return /* @__PURE__ */ jsx(TeamBlock, {
2009
+ lead: row,
2010
+ collapsed,
2011
+ avatars,
2012
+ onToggle: () => onConfigChange(toggleTeamCollapsed(config, row)),
2013
+ renderLead: (summary, tray) => item(row, "card", {
2014
+ className: row.context ? "opacity-50" : void 0,
2015
+ badgeState: collapsed ? row.teamState : void 0,
2016
+ teamUnseen: collapsed ? summary.unseen : 0,
2017
+ teamTray: tray
2018
+ }),
2019
+ renderMember: (member) => item(member, "member")
2020
+ }, sessionKey(row));
2021
+ })
1561
2022
  ]
1562
2023
  }, group.key)), custom ? /* @__PURE__ */ jsx(NewGroupButton, { onClick: () => setEditingGroup(drag.create()) }) : null]
1563
2024
  })
@@ -1568,11 +2029,18 @@ function iconSrcOf(row, icons) {
1568
2029
  const icon = row?.info.project?.icon;
1569
2030
  return icon?.type === "image" ? icons?.[icon.hash] : void 0;
1570
2031
  }
1571
- function SessionRowItem({ row, dragProps, dropTarget, active, actions, activeSubagentId, activeShellId, now, showGateway, showProject = true, subagents, shells, tasks, projectIcons, onSelect, onDelete, onRename, onClearContext, onSleep, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite }) {
2032
+ function SessionRowItem({ row, variant, avatars, badgeState, teamUnseen, teamTray, tile, className, dragProps, dropCue, active, actions, activeSubagentId, activeShellId, now, showGateway, showProject = true, subagents, shells, tasks, projectIcons, onSelect, onDelete, onRename, onClearContext, onSleep, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite }) {
1572
2033
  const { info } = row;
1573
2034
  const [editing, setEditing] = useState(false);
1574
2035
  const item = /* @__PURE__ */ jsx(SessionItem, {
1575
2036
  row,
2037
+ variant,
2038
+ avatars,
2039
+ badgeState,
2040
+ teamUnseen,
2041
+ teamTray,
2042
+ tile,
2043
+ className,
1576
2044
  active: active === true,
1577
2045
  activeStepKey: active ? activeShellId ?? activeSubagentId : void 0,
1578
2046
  now,
@@ -1595,7 +2063,7 @@ function SessionRowItem({ row, dragProps, dropTarget, active, actions, activeSub
1595
2063
  onEditingChange: actions === void 0 ? setEditing : void 0,
1596
2064
  actions: actions ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [
1597
2065
  onRename && !editing ? /* @__PURE__ */ jsx(RowAction, {
1598
- label: "Rename session",
2066
+ label: info.agent ? "Rename agent" : "Rename session",
1599
2067
  onClick: () => setEditing(true),
1600
2068
  children: /* @__PURE__ */ jsx(Pencil, { className: "size-3 text-fg-3" })
1601
2069
  }) : null,
@@ -1619,10 +2087,81 @@ function SessionRowItem({ row, dragProps, dropTarget, active, actions, activeSub
1619
2087
  ] })
1620
2088
  });
1621
2089
  if (!dragProps) return item;
1622
- return /* @__PURE__ */ jsx("div", {
2090
+ const zone = dropCue?.zone;
2091
+ return /* @__PURE__ */ jsxs("div", {
1623
2092
  ...dragProps,
1624
- className: cn("rounded-md", dropTarget && "shadow-[inset_0_2px_0_0_var(--color-accent)]"),
1625
- children: item
2093
+ title: zone === "refused" ? dropCue?.message : void 0,
2094
+ className: cn("rounded-md", zone === "before" && "shadow-[inset_0_2px_0_0_var(--color-accent)]", zone === "after" && "shadow-[inset_0_-2px_0_0_var(--color-accent)]", zone === "join" && "bg-accent/10 ring-1 ring-accent", zone === "refused" && "ring-1 ring-danger/60"),
2095
+ children: [item, zone === "refused" && dropCue?.message ? /* @__PURE__ */ jsx("div", {
2096
+ role: "status",
2097
+ className: "px-3 pb-1 text-label text-danger",
2098
+ children: dropCue.message
2099
+ }) : null]
2100
+ });
2101
+ }
2102
+ const TRAY_MAX = 4;
2103
+ function TeamBlock({ lead, collapsed, avatars, onToggle, renderLead, renderMember }) {
2104
+ const members = lead.members ?? [];
2105
+ const summary = teamSummary(lead);
2106
+ if (collapsed) {
2107
+ const surfaced = members.filter((member) => member.state === "attention");
2108
+ const counts = [
2109
+ `${summary.members} member${summary.members === 1 ? "" : "s"}`,
2110
+ summary.working ? `${summary.working} working` : void 0,
2111
+ summary.attention ? `${summary.attention} need${summary.attention === 1 ? "s" : ""} you` : void 0
2112
+ ].filter(Boolean);
2113
+ const hidden = members.length - TRAY_MAX;
2114
+ const tray = /* @__PURE__ */ jsxs("button", {
2115
+ type: "button",
2116
+ "aria-expanded": false,
2117
+ "aria-label": `Expand ${lead.info.agent?.name ?? "team"}: ${counts.join(", ")}`,
2118
+ title: counts.join(" · "),
2119
+ onClick: (e) => {
2120
+ e.stopPropagation();
2121
+ onToggle();
2122
+ },
2123
+ className: "flex shrink-0 items-center gap-1 rounded-[4px] px-0.5 hover:bg-row-hover",
2124
+ children: [members.slice(0, hidden > 0 ? 3 : TRAY_MAX).map((member) => /* @__PURE__ */ jsx(AgentAvatar, {
2125
+ row: member,
2126
+ image: avatarOf(avatars, member.info.agent),
2127
+ size: 16,
2128
+ className: "rounded-[3px]"
2129
+ }, sessionKey(member))), hidden > 0 ? /* @__PURE__ */ jsxs("span", {
2130
+ className: "text-label text-fg-4 tabular-nums",
2131
+ children: ["+", hidden + 1]
2132
+ }) : null]
2133
+ });
2134
+ return /* @__PURE__ */ jsxs("div", {
2135
+ "data-slot": "team",
2136
+ "data-collapsed": true,
2137
+ className: "flex flex-col",
2138
+ children: [renderLead(summary, tray), surfaced.length ? /* @__PURE__ */ jsx("div", {
2139
+ className: "ml-3 flex flex-col",
2140
+ children: surfaced.map(renderMember)
2141
+ }) : null]
2142
+ });
2143
+ }
2144
+ return /* @__PURE__ */ jsxs("div", {
2145
+ "data-slot": "team",
2146
+ className: "flex flex-col",
2147
+ children: [renderLead(summary), /* @__PURE__ */ jsxs("div", {
2148
+ className: "relative ml-3.5 flex flex-col pl-1",
2149
+ children: [
2150
+ /* @__PURE__ */ jsx("span", {
2151
+ "aria-hidden": true,
2152
+ className: "absolute top-0 bottom-3 left-0 w-px bg-border"
2153
+ }),
2154
+ /* @__PURE__ */ jsx("button", {
2155
+ type: "button",
2156
+ "aria-expanded": true,
2157
+ "aria-label": `Collapse ${lead.info.agent?.name ?? "team"}`,
2158
+ onClick: onToggle,
2159
+ className: "absolute -top-1 -left-[7px] flex size-3.5 items-center justify-center rounded-full border border-border bg-bg text-fg-4 hover:text-fg-1",
2160
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-2.5" })
2161
+ }),
2162
+ members.map(renderMember)
2163
+ ]
2164
+ })]
1626
2165
  });
1627
2166
  }
1628
2167
  function RowAction({ label, title, onClick, children }) {
@@ -1744,6 +2283,6 @@ function SubagentToggle({ value, onChange, className }) {
1744
2283
  })] });
1745
2284
  }
1746
2285
  //#endregion
1747
- export { AgentWriteIcon, AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, Badge, Band, Blank, Button, Card, CardContent, CardHeader, CardTitle, CodeBlock, Composer, ContextDialog, ContextPanel, ContextRing, Conversation, ConversationContent, ConversationScrollButton, CopyAction, CopyButton, Dialog, DialogBody, DialogClose, DialogContent, DialogHeader, DialogRow, DialogTrigger, EffortSelect, Empty, EmptyKey, EngineIcon, FileCard, FileLinkProvider, HostFilesDialog, ImageViewer, ImageViewerProvider, Ink, Input, Loader, McpDialog, McpPanel, McpPanelActions, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, ModelSelect, OptionSelect, PERMISSION_MODES, PermissionModeSelect, PermissionPrompt, Popover, PopoverContent, PopoverTrigger, ProgressRing, ProjectIcon, PromptArea, PromptTokenText, QUESTION_BEHAVIORS, QuestionPrompt, Reasoning, Response, Row, SHELL_AGENT_WRITE_NOTE, SHELL_GLYPH, SHELL_KILL_GLYPH, STATUS_META, STEP_DISPLAY_OPTIONS, SUBAGENT_DISPLAY_META, SUBAGENT_DISPLAY_ORDER, Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue, SessionBrowser, SessionEmptyState, SessionFilters, SessionFiltersButton, SessionInfoDialog, SessionInfoPanel, SessionItem, SessionList, SessionListItem, SessionNamesProvider, SessionPanel, SessionSearch, SessionStatusIcon, ShellActionsProvider, ShellStrip, SkillNamesProvider, SkillsDialog, Spinner, Splitter, StatusBar, StepDisplayControl, StepRow, SubagentDisplayIcon, SubagentStrip, SubagentToggle, TaskList, TasksDialog, TerminalDiff, TerminalItemView, TerminalMarkdown, TerminalPermissionPrompt, TerminalQuestionPrompt, TerminalStatusLine, TerminalSurface, TerminalTranscript, Textarea, Tip, Toaster, ToolCallCard, ToolTitleProvider, TooltipContent, TooltipProvider, Transcript, TranscriptVariantProvider, UsageDialog, UsageMeters, ViewableImage, WithActions, badgeVariants, buttonVariants, cn, commandTrigger, copyText, effortChoices, engineMark, formatAgoPrecise, formatBytes, formatCost, formatCountdown, formatDuration, formatRateLimitWindow, formatRateLimitWindowLong, formatRelativeTime, formatTokens, friendlyModel, getChipsByTrigger, hashtagTrigger, isMutatingTool, isSegmentsEmpty, launchTrigger, matchClientCommand, matchPath, mentionTrigger, mergeComposerRows, parseFileLink, parseUserQuestions, permissionModeChoices, permissionModeMeta, plainTextToSegments, previewPatch, rankComposerRows, rankPeerSessions, rateLimitWindowSeconds, resolveAgainstCwd, rowShapeClass, segmentsToPlainText, sessionSteps, shellAgentWriteLabel, shellGrantable, shellInfoFailed, shellInfoLabel, shellInfoStatusText, shellTitle, skillPrompt, toast, toolIcon, toolInputPreview, useAffordances, useFileLinks, useMcpPanel, useMinuteClock, useOpenImage, usePathLinks, usePromptAreaState, useShellActions, useShellFrame, useToolTitle, useTranscriptVariant, vendorMarkClass, vendorTextClass };
2286
+ export { AgentAvatar, AgentHeading, AgentWriteIcon, AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, Badge, Band, Blank, Button, Card, CardContent, CardHeader, CardTitle, CodeBlock, Composer, ContextDialog, ContextPanel, ContextRing, Conversation, ConversationContent, ConversationScrollButton, CopyAction, CopyButton, Dialog, DialogBody, DialogClose, DialogContent, DialogHeader, DialogRow, DialogTrigger, EffortSelect, Empty, EmptyKey, EngineIcon, FileCard, FileLinkProvider, HostFilesDialog, ImageViewer, ImageViewerProvider, Ink, Input, LeadChip, Loader, McpDialog, McpPanel, McpPanelActions, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, ModelSelect, OptionSelect, PERMISSION_MODES, PermissionModeSelect, PermissionPrompt, Popover, PopoverContent, PopoverTrigger, ProgressRing, ProjectIcon, PromptArea, PromptTokenText, QUESTION_BEHAVIORS, QuestionPrompt, Reasoning, Response, Row, SHELL_AGENT_WRITE_NOTE, SHELL_GLYPH, SHELL_KILL_GLYPH, STATUS_META, STEP_DISPLAY_OPTIONS, SUBAGENT_DISPLAY_META, SUBAGENT_DISPLAY_ORDER, Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue, SessionBrowser, SessionEmptyState, SessionFilters, SessionFiltersButton, SessionInfoDialog, SessionInfoPanel, SessionItem, SessionList, SessionListItem, SessionNamesProvider, SessionPanel, SessionSearch, SessionStatusIcon, ShellActionsProvider, ShellStrip, SkillNamesProvider, SkillsDialog, Spinner, Splitter, StatusBar, StepDisplayControl, StepRow, SubagentDisplayIcon, SubagentStrip, SubagentToggle, TaskList, TasksDialog, TerminalDiff, TerminalItemView, TerminalMarkdown, TerminalPermissionPrompt, TerminalQuestionPrompt, TerminalStatusLine, TerminalSurface, TerminalTranscript, Textarea, Tip, Toaster, ToolCallCard, ToolTitleProvider, TooltipContent, TooltipProvider, Transcript, TranscriptVariantProvider, UsageDialog, UsageMeters, ViewableImage, WithActions, avatarOf, badgeVariants, buttonVariants, cn, commandTrigger, copyText, effortChoices, engineMark, formatAgoPrecise, formatBytes, formatCost, formatCountdown, formatDuration, formatRateLimitWindow, formatRateLimitWindowLong, formatRelativeTime, formatTokens, friendlyModel, getChipsByTrigger, hashtagTrigger, isMutatingTool, isSegmentsEmpty, launchTrigger, matchClientCommand, matchPath, mentionTrigger, mergeComposerRows, parseFileLink, parseUserQuestions, permissionModeChoices, permissionModeMeta, plainTextToSegments, previewPatch, rankComposerRows, rankPeerSessions, rateLimitWindowSeconds, resolveAgainstCwd, rowShapeClass, segmentsToPlainText, sessionSteps, shellAgentWriteLabel, shellGrantable, shellInfoFailed, shellInfoLabel, shellInfoStatusText, shellTitle, skillPrompt, teamDropRefusal, toast, toolIcon, toolInputPreview, useAffordances, useFileLinks, useMcpPanel, useMinuteClock, useOpenImage, usePathLinks, usePromptAreaState, useShellActions, useShellFrame, useToolTitle, useTranscriptVariant, vendorMarkClass, vendorTextClass };
1748
2287
 
1749
2288
  //# sourceMappingURL=index.mjs.map