@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.d.mts +55 -4
- package/build/index.mjs +702 -163
- package/build/index.mjs.map +1 -1
- package/build/scoped.css +131 -0
- package/package.json +4 -4
- package/src/components/agent/AgentAvatar.tsx +117 -0
- package/src/components/agent/SessionBrowser.tsx +246 -43
- package/src/components/agent/SessionGroups.tsx +256 -23
- package/src/components/agent/SessionItem.tsx +200 -68
- package/src/index.ts +11 -0
- package/src/lib/team-drop.ts +65 -0
- package/src/styles/theme.css +22 -0
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
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
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 ? "· " : "",
|
|
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
|
|
1213
|
-
"aria-label":
|
|
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
|
-
|
|
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,
|
|
1472
|
+
const accept = (e, next) => {
|
|
1244
1473
|
e.preventDefault();
|
|
1245
1474
|
e.stopPropagation();
|
|
1246
|
-
e.dataTransfer.dropEffect = "move";
|
|
1247
|
-
|
|
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
|
|
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
|
-
|
|
1548
|
+
const landing = land(e, key, group, place);
|
|
1549
|
+
if (landing) accept(e, landing);
|
|
1259
1550
|
},
|
|
1260
1551
|
onDrop: (e) => {
|
|
1261
|
-
|
|
1552
|
+
const landing = land(e, key, group, place);
|
|
1553
|
+
if (!landing) return;
|
|
1262
1554
|
e.preventDefault();
|
|
1263
1555
|
e.stopPropagation();
|
|
1264
|
-
|
|
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
|
-
|
|
1277
|
-
|
|
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" })
|
|
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, {
|
|
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
|
|
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-
|
|
1961
|
+
className: "flex flex-col gap-2 px-1",
|
|
1525
1962
|
children: [groups.map((group) => /* @__PURE__ */ jsxs("div", {
|
|
1526
|
-
...
|
|
1527
|
-
className: cn("flex flex-col gap-1 rounded-md",
|
|
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) =>
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
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,
|
|
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
|
-
|
|
2090
|
+
const zone = dropCue?.zone;
|
|
2091
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1623
2092
|
...dragProps,
|
|
1624
|
-
|
|
1625
|
-
|
|
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
|