@workerdeck/ui 3.1.0 → 3.3.0

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 CHANGED
@@ -1248,6 +1248,7 @@ interface SessionBrowserProps {
1248
1248
  onSelectShell?: (row: SessionRow, shellId: string) => void;
1249
1249
  onKillShell?: (row: SessionRow, shellId: string) => void;
1250
1250
  onShellAgentWrite?: (row: SessionRow, shellId: string, enabled: boolean) => void;
1251
+ onCreateInGroup?: (target: GroupTarget) => void;
1251
1252
  emptyState?: ReactNode;
1252
1253
  showControls?: boolean;
1253
1254
  showSearch?: boolean;
@@ -1255,8 +1256,12 @@ interface SessionBrowserProps {
1255
1256
  projectIcons?: Record<string, string>;
1256
1257
  className?: string;
1257
1258
  }
1259
+ type GroupTarget = {
1260
+ hostId: string;
1261
+ cwd?: string;
1262
+ };
1258
1263
  declare function rowShapeClass(active: boolean): string;
1259
- declare function SessionBrowser({ rows, config, onConfigChange, scope, activeId, activeSubagentId, activeShellId, now, isActive, rowActions, gatewayCount, showSubset, onSelect, onDelete, onRename, onClearContext, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite, emptyState, showControls, showSearch, autoFocusSearch, projectIcons, className }: SessionBrowserProps): import("react").JSX.Element;
1264
+ declare function SessionBrowser({ rows, config, onConfigChange, scope, activeId, activeSubagentId, activeShellId, now, isActive, rowActions, gatewayCount, showSubset, onSelect, onDelete, onRename, onClearContext, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite, onCreateInGroup, emptyState, showControls, showSearch, autoFocusSearch, projectIcons, className }: SessionBrowserProps): import("react").JSX.Element;
1260
1265
  declare function SessionSearch({ value, onChange, autoFocus, className, inputClassName }: {
1261
1266
  value: string;
1262
1267
  onChange: (value: string) => void;
@@ -1495,5 +1500,5 @@ declare function copyText(value: string): Promise<boolean>;
1495
1500
  declare function toolIcon(toolName: string): LucideIcon;
1496
1501
  declare function isMutatingTool(toolName: string): boolean;
1497
1502
  //#endregion
1498
- export { type ActionPlacement, AgentWriteIcon, AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, type ApprovalPromptProps, Badge, type BadgeProps, Band, Blank, Button, type ButtonProps, Card, CardContent, CardHeader, CardTitle, type ChipSegment, type ClientCommand, CodeBlock, type CodeBlockProps, Composer, type ComposerFileMatch, type ComposerHandle, type ComposerProps, type ComposerRow, ContextDialog, type ContextDialogProps, ContextPanel, type ContextPanelProps, ContextRing, Conversation, ConversationContent, type ConversationProps, ConversationScrollButton, CopyAction, CopyButton, type CopyButtonProps, Dialog, DialogBody, DialogClose, DialogContent, DialogHeader, DialogRow, DialogTrigger, Empty, EmptyKey, EngineIcon, FileCard, type FileCardProps, type FileDeliveredItem, type FileLink, type FileLinkHandle, type FileLinkOpener, FileLinkProvider, HostFilesDialog, type HostFilesDialogProps, ImageViewer, ImageViewerProvider, Ink, Input, Loader, McpDialog, type McpDialogProps, McpPanel, McpPanelActions, type McpPanelModel, type McpPanelProps, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, type MessageProps, ModelSelect, type ModelSelectProps, type OpenImage, OptionSelect, type OptionSelectProps, PERMISSION_MODES, type PathHit, type PathMatch, type PermissionModeChoice, type PermissionModeMeta, PermissionModeSelect, type PermissionModeSelectProps, PermissionPrompt, type PermissionPromptProps, Popover, PopoverContent, PopoverTrigger, ProgressRing, type ProgressRingProps, ProjectIcon, PromptArea, type PromptAreaHandle, type PromptAreaProps, PromptTokenText, QUESTION_BEHAVIORS, type QuestionBehaviorMeta, QuestionPrompt, type QuestionPromptProps, Reasoning, type ReasoningProps, Response, type ResponseProps, Row, type RowProps, SHELL_AGENT_WRITE_NOTE, SHELL_GLYPH, SHELL_KILL_GLYPH, STATUS_META, STEP_DISPLAY_OPTIONS, SUBAGENT_DISPLAY_META, SUBAGENT_DISPLAY_ORDER, type Segment, Select, SelectContent, SelectItem, SelectItemText, type SelectModifiers, SelectTrigger, SelectValue, SessionBrowser, type SessionBrowserProps, type SessionControls, SessionEmptyState, type SessionEmptyStateProps, SessionFilters, SessionFiltersButton, type SessionFiltersButtonProps, type SessionFiltersProps, SessionInfoDialog, type SessionInfoDialogProps, SessionInfoPanel, type SessionInfoPanelProps, SessionItem, type SessionItemProps, SessionList, SessionListItem, type SessionListItemProps, type SessionListProps, SessionNamesProvider, SessionPanel, type SessionPanelProps, SessionSearch, SessionStatusIcon, type SessionSurfacePanel, type SessionVitals, type ShellActions, ShellActionsProvider, type ShellFrame, type ShellFrameOptions, type ShellStepOptions, ShellStrip, type ShellStripProps, SkillNamesProvider, SkillsDialog, type SkillsDialogProps, Spinner, Splitter, type SplitterProps, StatusBar, type StatusBarProps, type Step, StepDisplayControl, type StepKind, StepRow, SubagentDisplayIcon, SubagentStrip, SubagentToggle, type SubagentToggleProps, TaskList, type TaskListProps, type TaskStepOptions, TasksDialog, type TasksDialogProps, type TerminalAffordances, TerminalDiff, TerminalItemView, TerminalMarkdown, type TerminalMarkdownProps, type TerminalMetrics, TerminalPermissionPrompt, type TerminalPermissionPromptProps, TerminalQuestionPrompt, type TerminalQuestionPromptProps, TerminalStatusLine, type TerminalStatusLineProps, TerminalSurface, type TerminalSurfaceProps, TerminalTranscript, type TerminalTranscriptProps, type TextSegment, Textarea, Tip, Toaster, type Tone, ToolCallCard, type ToolCallCardProps, type ToolCallItem, ToolTitleProvider, TooltipContent, TooltipProvider, Transcript, type TranscriptFont, type TranscriptProps, type TranscriptVariant, TranscriptVariantProvider, type TriggerConfig, type TriggerSuggestion, UsageDialog, type UsageDialogProps, UsageMeters, ViewableImage, type ViewedImage, WithActions, badgeVariants, buttonVariants, cn, commandTrigger, copyText, 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 };
1503
+ export { type ActionPlacement, AgentWriteIcon, AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, type ApprovalPromptProps, Badge, type BadgeProps, Band, Blank, Button, type ButtonProps, Card, CardContent, CardHeader, CardTitle, type ChipSegment, type ClientCommand, CodeBlock, type CodeBlockProps, Composer, type ComposerFileMatch, type ComposerHandle, type ComposerProps, type ComposerRow, ContextDialog, type ContextDialogProps, ContextPanel, type ContextPanelProps, ContextRing, Conversation, ConversationContent, type ConversationProps, ConversationScrollButton, CopyAction, CopyButton, type CopyButtonProps, Dialog, DialogBody, DialogClose, DialogContent, DialogHeader, DialogRow, DialogTrigger, Empty, EmptyKey, EngineIcon, FileCard, type FileCardProps, type FileDeliveredItem, type FileLink, type FileLinkHandle, type FileLinkOpener, FileLinkProvider, type GroupTarget, HostFilesDialog, type HostFilesDialogProps, ImageViewer, ImageViewerProvider, Ink, Input, Loader, McpDialog, type McpDialogProps, McpPanel, McpPanelActions, type McpPanelModel, type McpPanelProps, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, type MessageProps, ModelSelect, type ModelSelectProps, type OpenImage, OptionSelect, type OptionSelectProps, PERMISSION_MODES, type PathHit, type PathMatch, type PermissionModeChoice, type PermissionModeMeta, PermissionModeSelect, type PermissionModeSelectProps, PermissionPrompt, type PermissionPromptProps, Popover, PopoverContent, PopoverTrigger, ProgressRing, type ProgressRingProps, ProjectIcon, PromptArea, type PromptAreaHandle, type PromptAreaProps, PromptTokenText, QUESTION_BEHAVIORS, type QuestionBehaviorMeta, QuestionPrompt, type QuestionPromptProps, Reasoning, type ReasoningProps, Response, type ResponseProps, Row, type RowProps, SHELL_AGENT_WRITE_NOTE, SHELL_GLYPH, SHELL_KILL_GLYPH, STATUS_META, STEP_DISPLAY_OPTIONS, SUBAGENT_DISPLAY_META, SUBAGENT_DISPLAY_ORDER, type Segment, Select, SelectContent, SelectItem, SelectItemText, type SelectModifiers, SelectTrigger, SelectValue, SessionBrowser, type SessionBrowserProps, type SessionControls, SessionEmptyState, type SessionEmptyStateProps, SessionFilters, SessionFiltersButton, type SessionFiltersButtonProps, type SessionFiltersProps, SessionInfoDialog, type SessionInfoDialogProps, SessionInfoPanel, type SessionInfoPanelProps, SessionItem, type SessionItemProps, SessionList, SessionListItem, type SessionListItemProps, type SessionListProps, SessionNamesProvider, SessionPanel, type SessionPanelProps, SessionSearch, SessionStatusIcon, type SessionSurfacePanel, type SessionVitals, type ShellActions, ShellActionsProvider, type ShellFrame, type ShellFrameOptions, type ShellStepOptions, ShellStrip, type ShellStripProps, SkillNamesProvider, SkillsDialog, type SkillsDialogProps, Spinner, Splitter, type SplitterProps, StatusBar, type StatusBarProps, type Step, StepDisplayControl, type StepKind, StepRow, SubagentDisplayIcon, SubagentStrip, SubagentToggle, type SubagentToggleProps, TaskList, type TaskListProps, type TaskStepOptions, TasksDialog, type TasksDialogProps, type TerminalAffordances, TerminalDiff, TerminalItemView, TerminalMarkdown, type TerminalMarkdownProps, type TerminalMetrics, TerminalPermissionPrompt, type TerminalPermissionPromptProps, TerminalQuestionPrompt, type TerminalQuestionPromptProps, TerminalStatusLine, type TerminalStatusLineProps, TerminalSurface, type TerminalSurfaceProps, TerminalTranscript, type TerminalTranscriptProps, type TextSegment, Textarea, Tip, Toaster, type Tone, ToolCallCard, type ToolCallCardProps, type ToolCallItem, ToolTitleProvider, TooltipContent, TooltipProvider, Transcript, type TranscriptFont, type TranscriptProps, type TranscriptVariant, TranscriptVariantProvider, type TriggerConfig, type TriggerSuggestion, UsageDialog, type UsageDialogProps, UsageMeters, ViewableImage, type ViewedImage, WithActions, badgeVariants, buttonVariants, cn, commandTrigger, copyText, 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 };
1499
1504
  //# sourceMappingURL=index.d.mts.map
package/build/index.mjs CHANGED
@@ -1,12 +1,12 @@
1
- import { $ as ShellActionsProvider, $t as Spinner, A as PermissionPrompt, An as buttonVariants, At as PromptTokenText, B as ModelSelect, Bt as rankPeerSessions, C as SessionInfoDialog, Cn as SelectValue, Ct as Blank, D as QUESTION_BEHAVIORS, Dn as Badge, Dt as CopyAction, E as TerminalPermissionPrompt, En as Input, Et as AgentWriteIcon, F as SubagentStrip, Ft as TranscriptVariantProvider, G as useMcpPanel, Gt as mentionTrigger, H as McpDialog, Ht as commandTrigger, I as PERMISSION_MODES, It as useTranscriptVariant, J as ContextDialog, Jt as plainTextToSegments, K as HostFilesDialog, Kt as usePromptAreaState, L as PermissionModeSelect, Lt as matchClientCommand, M as useShellFrame, Mt as SkillNamesProvider, Nt as isMutatingTool, O as QuestionPrompt, On as badgeVariants, Ot as WithActions, P as ShellStrip, Pt as toolIcon, Q as TerminalSurface, Qt as CodeBlock, R as permissionModeChoices, Rt as mergeComposerRows, S as STATUS_META, Sn as SelectTrigger, St as Band, T as TerminalQuestionPrompt, Tn as Textarea, Tt as Row, U as McpPanel, Ut as hashtagTrigger, V as SkillsDialog, Vt as skillPrompt, W as McpPanelActions, Wt as launchTrigger, X as contextNote, Xt as ProgressRing, Y as ContextPanel, Yt as segmentsToPlainText, Z as Composer, Zt as Splitter, _ as Loader, _n as OptionSelect, _t as FileLinkProvider, a as UsageDialog, an as Dialog, at as shellGrantable, b as ConversationScrollButton, bn as SelectItem, bt as TerminalDiff, c as TerminalTranscript, cn as DialogContent, ct as shellInfoStatusText, d as Reasoning, dn as DialogTrigger, dt as useToolTitle, en as CopyButton, et as useShellActions, f as Message, fn as Menu, ft as TerminalMarkdown, g as SessionEmptyState, gn as MenuTrigger, gt as useOpenImage, h as TerminalItemView, hn as MenuSeparator, ht as ViewableImage, i as SessionPanel, in as TooltipProvider, it as shellAgentWriteLabel, j as Response, jn as cn, jt as SessionNamesProvider, k as parseUserQuestions, kn as Button, kt as useAffordances, l as Transcript, ln as DialogHeader, lt as shellTitle, m as FileCard, mn as MenuItem, mt as ImageViewerProvider, n as usePathLinks, nn as Tip, nt as SHELL_GLYPH, o as UsageMeters, on as DialogBody, ot as shellInfoFailed, p as MessageContent, pn as MenuContent, pt as ImageViewer, qt as PromptArea, r as matchPath, rn as TooltipContent, rt as SHELL_KILL_GLYPH, s as useMinuteClock, sn as DialogClose, st as shellInfoLabel, t as resolveAgainstCwd, tn as copyText, tt as SHELL_AGENT_WRITE_NOTE, u as ToolCallCard, un as DialogRow, ut as ToolTitleProvider, v as Conversation, vn as Select, vt as useFileLinks, w as SessionInfoPanel, wn as PortalScope, wt as Ink, x as StatusBar, xn as SelectItemText, xt as previewPatch, y as ConversationContent, yn as SelectContent, yt as parseFileLink, z as permissionModeMeta, zt as rankComposerRows } from "./use-path-links-C6Fh5zdx.mjs";
1
+ import { $ as ShellActionsProvider, $t as Spinner, A as PermissionPrompt, An as buttonVariants, At as PromptTokenText, B as ModelSelect, Bt as rankPeerSessions, C as SessionInfoDialog, Cn as SelectValue, Ct as Blank, D as QUESTION_BEHAVIORS, Dn as Badge, Dt as CopyAction, E as TerminalPermissionPrompt, En as Input, Et as AgentWriteIcon, F as SubagentStrip, Ft as TranscriptVariantProvider, G as useMcpPanel, Gt as mentionTrigger, H as McpDialog, Ht as commandTrigger, I as PERMISSION_MODES, It as useTranscriptVariant, J as ContextDialog, Jt as plainTextToSegments, K as HostFilesDialog, Kt as usePromptAreaState, L as PermissionModeSelect, Lt as matchClientCommand, M as useShellFrame, Mt as SkillNamesProvider, Nt as isMutatingTool, O as QuestionPrompt, On as badgeVariants, Ot as WithActions, P as ShellStrip, Pt as toolIcon, Q as TerminalSurface, Qt as CodeBlock, R as permissionModeChoices, Rt as mergeComposerRows, S as STATUS_META, Sn as SelectTrigger, St as Band, T as TerminalQuestionPrompt, Tn as Textarea, Tt as Row, U as McpPanel, Ut as hashtagTrigger, V as SkillsDialog, Vt as skillPrompt, W as McpPanelActions, Wt as launchTrigger, X as contextNote, Xt as ProgressRing, Y as ContextPanel, Yt as segmentsToPlainText, Z as Composer, Zt as Splitter, _ as Loader, _n as OptionSelect, _t as FileLinkProvider, a as UsageDialog, an as Dialog, at as shellGrantable, b as ConversationScrollButton, bn as SelectItem, bt as TerminalDiff, c as TerminalTranscript, cn as DialogContent, ct as shellInfoStatusText, d as Reasoning, dn as DialogTrigger, dt as useToolTitle, en as CopyButton, et as useShellActions, f as Message, fn as Menu, ft as TerminalMarkdown, g as SessionEmptyState, gn as MenuTrigger, gt as useOpenImage, h as TerminalItemView, hn as MenuSeparator, ht as ViewableImage, i as SessionPanel, in as TooltipProvider, it as shellAgentWriteLabel, j as Response, jn as cn, jt as SessionNamesProvider, k as parseUserQuestions, kn as Button, kt as useAffordances, l as Transcript, ln as DialogHeader, lt as shellTitle, m as FileCard, mn as MenuItem, mt as ImageViewerProvider, n as usePathLinks, nn as Tip, nt as SHELL_GLYPH, o as UsageMeters, on as DialogBody, ot as shellInfoFailed, p as MessageContent, pn as MenuContent, pt as ImageViewer, qt as PromptArea, r as matchPath, rn as TooltipContent, rt as SHELL_KILL_GLYPH, s as useMinuteClock, sn as DialogClose, st as shellInfoLabel, t as resolveAgainstCwd, tn as copyText, tt as SHELL_AGENT_WRITE_NOTE, u as ToolCallCard, un as DialogRow, ut as ToolTitleProvider, v as Conversation, vn as Select, vt as useFileLinks, w as SessionInfoPanel, wn as PortalScope, wt as Ink, x as StatusBar, xn as SelectItemText, xt as previewPatch, y as ConversationContent, yn as SelectContent, yt as parseFileLink, z as permissionModeMeta, zt as rankComposerRows } from "./use-path-links-Cby4i_VL.mjs";
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, 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, 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, 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, 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";
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, clearFilters, displayCustomized, displayedTasks, facetFilterCount, filterRows, groupRows, hasFacetFilter, isAgentRecord, projectLabel, projectName, projectSubpath, projectsOf, scopeActive, sessionLabel, subagentLabel, subsetSummary, taskSummary, visibleShells, visibleSubagents, visibleTasks } from "@workerdeck/protocol";
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";
10
10
  //#region src/components/ui/Card.tsx
11
11
  function Card({ className, ...props }) {
12
12
  return /* @__PURE__ */ jsx("div", {
@@ -632,14 +632,14 @@ function SessionFilters({ config, onConfigChange, rows, scope, gateways: gateway
632
632
  value: "adapter",
633
633
  label: "By engine"
634
634
  },
635
- ...projects.length > 1 ? [{
635
+ {
636
636
  value: "project",
637
- label: "By project"
638
- }] : [],
639
- ...gateways.length > 1 ? [{
640
- value: "gateway",
641
- label: "By gateway"
642
- }] : []
637
+ label: gateways.length > 1 ? "By gateway & project" : "By project"
638
+ },
639
+ {
640
+ value: "custom",
641
+ label: "Custom"
642
+ }
643
643
  ],
644
644
  onChange: (groupBy) => set({ groupBy })
645
645
  })
@@ -1224,23 +1224,240 @@ function NameEditor({ initial, onCommit, onCancel }) {
1224
1224
  });
1225
1225
  }
1226
1226
  //#endregion
1227
+ //#region src/components/agent/SessionGroups.tsx
1228
+ function useGroupDrag(groups, onChange) {
1229
+ const [item, setItem] = useState();
1230
+ const [over, setOver] = useState();
1231
+ const end = () => {
1232
+ setItem(void 0);
1233
+ setOver(void 0);
1234
+ };
1235
+ const start = (e, next) => {
1236
+ e.stopPropagation();
1237
+ e.dataTransfer.effectAllowed = "move";
1238
+ e.dataTransfer.setData("text/plain", next.kind === "session" ? next.key : next.id);
1239
+ setItem(next);
1240
+ };
1241
+ const accept = (e, spot) => {
1242
+ e.preventDefault();
1243
+ e.stopPropagation();
1244
+ e.dataTransfer.dropEffect = "move";
1245
+ setOver(spot);
1246
+ };
1247
+ function session(key, group) {
1248
+ return {
1249
+ draggable: true,
1250
+ onDragStart: (e) => start(e, {
1251
+ kind: "session",
1252
+ key
1253
+ }),
1254
+ onDragEnd: end,
1255
+ onDragOver: (e) => {
1256
+ if (item?.kind === "session") accept(e, `row:${key}`);
1257
+ },
1258
+ onDrop: (e) => {
1259
+ if (item?.kind !== "session") return;
1260
+ e.preventDefault();
1261
+ e.stopPropagation();
1262
+ if (item.key !== key) onChange(moveToCustomGroup(groups, item.key, group.custom, group.custom ? key : void 0));
1263
+ end();
1264
+ }
1265
+ };
1266
+ }
1267
+ function container(group) {
1268
+ return {
1269
+ onDragOver: (e) => {
1270
+ if (item) accept(e, `group:${group.key}`);
1271
+ },
1272
+ onDrop: (e) => {
1273
+ e.preventDefault();
1274
+ if (item?.kind === "session") onChange(moveToCustomGroup(groups, item.key, group.custom));
1275
+ else if (item?.kind === "group") onChange(moveCustomGroup(groups, item.id, group.custom));
1276
+ end();
1277
+ }
1278
+ };
1279
+ }
1280
+ function header(group) {
1281
+ const id = group.custom;
1282
+ if (id === void 0) return {};
1283
+ return {
1284
+ draggable: true,
1285
+ onDragStart: (e) => start(e, {
1286
+ kind: "group",
1287
+ id
1288
+ }),
1289
+ onDragEnd: end
1290
+ };
1291
+ }
1292
+ return {
1293
+ dragging: item !== void 0,
1294
+ isOver: (spot) => over === spot,
1295
+ session,
1296
+ container,
1297
+ header,
1298
+ create: (name = "New group") => {
1299
+ const id = newCustomGroupId();
1300
+ onChange(addCustomGroup(groups, name, id));
1301
+ return id;
1302
+ },
1303
+ rename: (id, name) => onChange(renameCustomGroup(groups, id, name)),
1304
+ remove: (id) => onChange(removeCustomGroup(groups, id))
1305
+ };
1306
+ }
1307
+ function CustomGroupHeader({ group, editing, onEditingChange, onRename, onRemove, dragProps }) {
1308
+ if (editing) return /* @__PURE__ */ jsx(GroupNameInput, {
1309
+ initial: group.label ?? "",
1310
+ onRename,
1311
+ onDone: () => onEditingChange(false)
1312
+ });
1313
+ const custom = group.custom !== void 0;
1314
+ return /* @__PURE__ */ jsx(GroupHeading, {
1315
+ ...dragProps,
1316
+ label: group.label ?? "",
1317
+ count: group.rows.length,
1318
+ className: cn("group/heading", custom && "cursor-grab"),
1319
+ onDoubleClick: custom ? () => onEditingChange(true) : void 0,
1320
+ leading: custom ? /* @__PURE__ */ jsx(GripVertical, { className: "-ml-1.5 size-3 opacity-0 group-hover/heading:opacity-60" }) : void 0,
1321
+ actions: custom ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(HeadingAction, {
1322
+ label: "Rename group",
1323
+ onClick: () => onEditingChange(true),
1324
+ children: /* @__PURE__ */ jsx(Pencil, { className: "size-3" })
1325
+ }), /* @__PURE__ */ jsx(HeadingAction, {
1326
+ label: "Delete group",
1327
+ title: "Delete the group - its sessions move to Ungrouped",
1328
+ onClick: onRemove,
1329
+ children: /* @__PURE__ */ jsx(Trash2, { className: "size-3" })
1330
+ })] }) : void 0
1331
+ });
1332
+ }
1333
+ function GroupNameInput({ initial, onRename, onDone }) {
1334
+ const [draft, setDraft] = useState(initial);
1335
+ const commit = () => {
1336
+ const name = draft.trim();
1337
+ if (name && name !== initial) onRename(name);
1338
+ onDone();
1339
+ };
1340
+ return /* @__PURE__ */ jsx("div", {
1341
+ className: "px-2",
1342
+ children: /* @__PURE__ */ jsx(Input, {
1343
+ autoFocus: true,
1344
+ "aria-label": "Group name",
1345
+ value: draft,
1346
+ onFocus: (e) => e.currentTarget.select(),
1347
+ onChange: (e) => setDraft(e.target.value),
1348
+ onBlur: commit,
1349
+ onKeyDown: (e) => {
1350
+ if (e.key === "Enter") commit();
1351
+ else if (e.key === "Escape") {
1352
+ e.stopPropagation();
1353
+ onDone();
1354
+ }
1355
+ },
1356
+ className: "h-6 text-label"
1357
+ })
1358
+ });
1359
+ }
1360
+ function GroupHeading({ label, count, leading, actions, className, ...rest }) {
1361
+ return /* @__PURE__ */ jsxs("div", {
1362
+ ...rest,
1363
+ className: cn("group/heading flex min-h-5 items-center gap-2 px-2 text-label font-medium text-fg-4", className),
1364
+ children: [
1365
+ leading,
1366
+ /* @__PURE__ */ jsx("span", {
1367
+ className: "min-w-0 truncate uppercase tracking-wide",
1368
+ children: label
1369
+ }),
1370
+ /* @__PURE__ */ jsx("span", {
1371
+ className: "text-fg-4/70",
1372
+ children: count
1373
+ }),
1374
+ actions ? /* @__PURE__ */ jsx("span", {
1375
+ className: "ml-auto flex items-center gap-0.5 opacity-0 transition-opacity group-hover/heading:opacity-100 focus-within:opacity-100",
1376
+ children: actions
1377
+ }) : null
1378
+ ]
1379
+ });
1380
+ }
1381
+ function HeadingAction({ label, title, onClick, children }) {
1382
+ return /* @__PURE__ */ jsx(Button, {
1383
+ variant: "ghost",
1384
+ size: "icon-sm",
1385
+ "aria-label": label,
1386
+ title: title ?? label,
1387
+ className: "size-5 text-fg-3",
1388
+ onClick: (e) => {
1389
+ e.stopPropagation();
1390
+ onClick();
1391
+ },
1392
+ children
1393
+ });
1394
+ }
1395
+ function NewGroupButton({ onClick }) {
1396
+ return /* @__PURE__ */ jsxs(Button, {
1397
+ variant: "ghost",
1398
+ size: "xs",
1399
+ className: "mx-1 self-start text-fg-3",
1400
+ onClick,
1401
+ children: [/* @__PURE__ */ jsx(Plus, {}), "New group"]
1402
+ });
1403
+ }
1404
+ //#endregion
1227
1405
  //#region src/components/agent/SessionBrowser.tsx
1228
1406
  function rowShapeClass(active) {
1229
1407
  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");
1230
1408
  }
1231
- function SessionBrowser({ rows, config, onConfigChange, scope, activeId, activeSubagentId, activeShellId, now, isActive = (row) => row.info.id === activeId, rowActions, gatewayCount, showSubset = true, onSelect, onDelete, onRename, onClearContext, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite, emptyState, showControls = true, showSearch = showControls, autoFocusSearch, projectIcons, className }) {
1409
+ function SessionBrowser({ rows, config, onConfigChange, scope, activeId, activeSubagentId, activeShellId, now, isActive = (row) => row.info.id === activeId, rowActions, gatewayCount, showSubset = true, onSelect, onDelete, onRename, onClearContext, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite, onCreateInGroup, emptyState, showControls = true, showSearch = showControls, autoFocusSearch, projectIcons, className }) {
1410
+ const rowGateways = useMemo(() => new Set(rows.map((row) => row.hostId)).size, [rows]);
1411
+ const gateways = gatewayCount ?? rowGateways;
1232
1412
  const visible = useMemo(() => filterRows(rows, config, scope), [
1233
1413
  rows,
1234
1414
  config,
1235
1415
  scope
1236
1416
  ]);
1237
- const groups = useMemo(() => groupRows(visible, config), [visible, config]);
1417
+ const groups = useMemo(() => groupRows(visible, config, { gatewayCount: gateways }), [
1418
+ visible,
1419
+ config,
1420
+ gateways
1421
+ ]);
1238
1422
  const subset = subsetSummary(config, scope, visible.length, rows.length);
1239
- const rowGateways = useMemo(() => new Set(rows.map((row) => row.hostId)).size, [rows]);
1423
+ const custom = config.groupBy === "custom";
1424
+ const [editingGroup, setEditingGroup] = useState();
1240
1425
  const set = (patch) => onConfigChange({
1241
1426
  ...config,
1242
1427
  ...patch
1243
1428
  });
1429
+ const drag = useGroupDrag(config.customGroups ?? [], (customGroups) => set({ customGroups }));
1430
+ const heading = (group) => {
1431
+ if (custom) return /* @__PURE__ */ jsx(CustomGroupHeader, {
1432
+ group,
1433
+ editing: group.custom !== void 0 && editingGroup === group.custom,
1434
+ onEditingChange: (editing) => setEditingGroup(editing ? group.custom : void 0),
1435
+ onRename: (name) => group.custom && drag.rename(group.custom, name),
1436
+ onRemove: () => group.custom && drag.remove(group.custom),
1437
+ dragProps: drag.header(group)
1438
+ });
1439
+ if (config.groupBy === "none" || !group.label) return null;
1440
+ const project = config.groupBy === "project";
1441
+ const target = project && group.hostId ? {
1442
+ hostId: group.hostId,
1443
+ cwd: group.cwd
1444
+ } : void 0;
1445
+ return /* @__PURE__ */ jsx(GroupHeading, {
1446
+ label: group.label,
1447
+ count: group.rows.length,
1448
+ title: project && group.cwd ? group.cwd : void 0,
1449
+ leading: project ? /* @__PURE__ */ jsx(ProjectIcon, {
1450
+ icon: group.rows[0]?.info.project?.icon,
1451
+ src: iconSrcOf(group.rows[0], projectIcons),
1452
+ name: group.label
1453
+ }) : void 0,
1454
+ actions: target && onCreateInGroup ? /* @__PURE__ */ jsx(HeadingAction, {
1455
+ label: `New session in ${group.label}`,
1456
+ onClick: () => onCreateInGroup(target),
1457
+ children: /* @__PURE__ */ jsx(Plus, { className: "size-3" })
1458
+ }) : void 0
1459
+ });
1460
+ };
1244
1461
  return /* @__PURE__ */ jsxs("div", {
1245
1462
  "data-slot": "session-browser",
1246
1463
  className: cn("flex flex-col gap-3", className),
@@ -1291,52 +1508,45 @@ function SessionBrowser({ rows, config, onConfigChange, scope, activeId, activeS
1291
1508
  icon: /* @__PURE__ */ jsx(Layers, {}),
1292
1509
  title: "Nothing here",
1293
1510
  description: "No session to show."
1294
- }) : /* @__PURE__ */ jsx("div", {
1511
+ }) : /* @__PURE__ */ jsxs("div", {
1295
1512
  className: "flex flex-col gap-4 px-1",
1296
- children: groups.map((group) => /* @__PURE__ */ jsxs("div", {
1297
- className: "flex flex-col gap-1",
1298
- children: [config.groupBy !== "none" && group.label ? /* @__PURE__ */ jsxs("div", {
1299
- className: "flex items-center gap-2 px-2 text-label font-medium text-fg-4",
1300
- children: [
1301
- config.groupBy === "project" ? /* @__PURE__ */ jsx(ProjectIcon, {
1302
- icon: group.rows[0]?.info.project?.icon,
1303
- src: iconSrcOf(group.rows[0], projectIcons),
1304
- name: group.label
1305
- }) : null,
1306
- /* @__PURE__ */ jsx("span", {
1307
- className: "uppercase tracking-wide",
1308
- children: group.label
1309
- }),
1310
- /* @__PURE__ */ jsx("span", {
1311
- className: "text-fg-4/70",
1312
- children: group.rows.length
1313
- })
1314
- ]
1315
- }) : null, group.rows.map((row) => /* @__PURE__ */ jsx(SessionRowItem, {
1316
- row,
1317
- active: isActive(row),
1318
- activeSubagentId,
1319
- activeShellId,
1320
- actions: rowActions?.(row),
1321
- now,
1322
- showGateway: (gatewayCount ?? rowGateways) > 1 && config.groupBy !== "gateway",
1323
- showProject: config.groupBy !== "project",
1324
- subagents: config.subagents,
1325
- shells: config.shells,
1326
- tasks: config.tasks,
1327
- projectIcons,
1328
- onSelect,
1329
- onDelete,
1330
- onRename,
1331
- onClearContext,
1332
- onSelectSubagent,
1333
- onSelectTask,
1334
- onStopTask,
1335
- onSelectShell,
1336
- onKillShell,
1337
- onShellAgentWrite
1338
- }, `${row.hostId}:${row.info.id}`))]
1339
- }, group.key))
1513
+ children: [groups.map((group) => /* @__PURE__ */ jsxs("div", {
1514
+ ...custom ? drag.container(group) : {},
1515
+ className: cn("flex flex-col gap-1 rounded-md", custom && drag.isOver(`group:${group.key}`) && "bg-row-hover/50"),
1516
+ children: [
1517
+ heading(group),
1518
+ custom && group.custom !== void 0 && group.rows.length === 0 ? /* @__PURE__ */ jsx("div", {
1519
+ className: "mx-1 rounded-md border border-dashed border-border px-2 py-2 text-center text-label text-fg-4",
1520
+ children: "Drag sessions here"
1521
+ }) : null,
1522
+ group.rows.map((row) => /* @__PURE__ */ jsx(SessionRowItem, {
1523
+ dragProps: custom ? drag.session(sessionKey(row), group) : void 0,
1524
+ dropTarget: custom && drag.isOver(`row:${sessionKey(row)}`),
1525
+ row,
1526
+ active: isActive(row),
1527
+ activeSubagentId,
1528
+ activeShellId,
1529
+ actions: rowActions?.(row),
1530
+ now,
1531
+ showGateway: gateways > 1 && config.groupBy !== "project",
1532
+ showProject: config.groupBy !== "project",
1533
+ subagents: config.subagents,
1534
+ shells: config.shells,
1535
+ tasks: config.tasks,
1536
+ projectIcons,
1537
+ onSelect,
1538
+ onDelete,
1539
+ onRename,
1540
+ onClearContext,
1541
+ onSelectSubagent,
1542
+ onSelectTask,
1543
+ onStopTask,
1544
+ onSelectShell,
1545
+ onKillShell,
1546
+ onShellAgentWrite
1547
+ }, sessionKey(row)))
1548
+ ]
1549
+ }, group.key)), custom ? /* @__PURE__ */ jsx(NewGroupButton, { onClick: () => setEditingGroup(drag.create()) }) : null]
1340
1550
  })
1341
1551
  ]
1342
1552
  });
@@ -1345,10 +1555,10 @@ function iconSrcOf(row, icons) {
1345
1555
  const icon = row?.info.project?.icon;
1346
1556
  return icon?.type === "image" ? icons?.[icon.hash] : void 0;
1347
1557
  }
1348
- function SessionRowItem({ row, active, actions, activeSubagentId, activeShellId, now, showGateway, showProject = true, subagents, shells, tasks, projectIcons, onSelect, onDelete, onRename, onClearContext, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite }) {
1558
+ function SessionRowItem({ row, dragProps, dropTarget, active, actions, activeSubagentId, activeShellId, now, showGateway, showProject = true, subagents, shells, tasks, projectIcons, onSelect, onDelete, onRename, onClearContext, onSelectSubagent, onSelectTask, onStopTask, onSelectShell, onKillShell, onShellAgentWrite }) {
1349
1559
  const { info } = row;
1350
1560
  const [editing, setEditing] = useState(false);
1351
- return /* @__PURE__ */ jsx(SessionItem, {
1561
+ const item = /* @__PURE__ */ jsx(SessionItem, {
1352
1562
  row,
1353
1563
  active: active === true,
1354
1564
  activeStepKey: active ? activeShellId ?? activeSubagentId : void 0,
@@ -1389,6 +1599,12 @@ function SessionRowItem({ row, active, actions, activeSubagentId, activeShellId,
1389
1599
  }) : null
1390
1600
  ] })
1391
1601
  });
1602
+ if (!dragProps) return item;
1603
+ return /* @__PURE__ */ jsx("div", {
1604
+ ...dragProps,
1605
+ className: cn("rounded-md", dropTarget && "shadow-[inset_0_2px_0_0_var(--color-accent)]"),
1606
+ children: item
1607
+ });
1392
1608
  }
1393
1609
  function RowAction({ label, title, onClick, children }) {
1394
1610
  return /* @__PURE__ */ jsx(Button, {