@workerdeck/ui 2.1.0 → 2.2.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/{SessionPanel-DrMj8Yv0.mjs → SessionPanel-ErvQUyHe.mjs} +101 -21
- package/build/SessionPanel-ErvQUyHe.mjs.map +1 -0
- package/build/index.d.mts +16 -3
- package/build/index.mjs +2 -2
- package/build/scoped.css +25 -0
- package/build/workspace.mjs +1 -1
- package/package.json +4 -4
- package/src/components/agent/Composer.tsx +102 -17
- package/src/components/agent/SessionPanel.tsx +3 -0
- package/src/components/prompt-area/index.ts +1 -1
- package/src/components/prompt-area/trigger-presets.ts +24 -0
- package/src/index.ts +1 -0
- package/src/styles/terminal.css +19 -0
- package/src/styles/theme.css +5 -0
- package/build/SessionPanel-DrMj8Yv0.mjs.map +0 -1
package/build/index.d.mts
CHANGED
|
@@ -15,7 +15,7 @@ import { ConnectionState, TranscriptItem, TranscriptState, UseAttachmentsResult
|
|
|
15
15
|
import { WorkerDeckClient } from "@workerdeck/client";
|
|
16
16
|
//#region src/components/ui/Button.d.ts
|
|
17
17
|
declare const buttonVariants: (props?: ({
|
|
18
|
-
variant?: "default" | "
|
|
18
|
+
variant?: "default" | "link" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
|
|
19
19
|
size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-sm" | null | undefined;
|
|
20
20
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
21
21
|
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {}
|
|
@@ -623,6 +623,18 @@ type HashtagTriggerOptions = TriggerPresetOptions & {
|
|
|
623
623
|
* `resolveOnSpace: true`, accessible label `"tag"`.
|
|
624
624
|
*/
|
|
625
625
|
declare function hashtagTrigger(opts?: HashtagTriggerOptions): TriggerConfig;
|
|
626
|
+
type LaunchTriggerOptions = Omit<Partial<TriggerConfig>, 'mode'> & {
|
|
627
|
+
/** The trigger character. Required. */
|
|
628
|
+
char: string;
|
|
629
|
+
};
|
|
630
|
+
/**
|
|
631
|
+
* Creates a **launch** trigger: `onActivate` fires on keydown and the character
|
|
632
|
+
* never enters the editor. For flipping the composer into another mode, or
|
|
633
|
+
* opening a surface outside it.
|
|
634
|
+
*
|
|
635
|
+
* Defaults: `position: 'start'`, `mode: 'launch'`.
|
|
636
|
+
*/
|
|
637
|
+
declare function launchTrigger(opts: LaunchTriggerOptions): TriggerConfig;
|
|
626
638
|
//#endregion
|
|
627
639
|
//#region src/components/prompt-area/prompt-area-engine.d.ts
|
|
628
640
|
/**
|
|
@@ -888,6 +900,7 @@ interface ComposerProps {
|
|
|
888
900
|
onSearchFiles?: (query: string, options: {
|
|
889
901
|
signal: AbortSignal;
|
|
890
902
|
}) => Promise<ComposerFileMatch[]>;
|
|
903
|
+
onShellCommand?: (command: string) => void;
|
|
891
904
|
attachments?: UseAttachmentsResult;
|
|
892
905
|
toolbar?: ReactNode;
|
|
893
906
|
layout?: 'stacked' | 'inline';
|
|
@@ -903,7 +916,7 @@ interface ComposerProps {
|
|
|
903
916
|
ref?: Ref<ComposerHandle>;
|
|
904
917
|
}
|
|
905
918
|
declare function skillPrompt(skill: SkillInfo): string;
|
|
906
|
-
declare function Composer({ onSend, onInterrupt, busy, disabled, placeholder, commands, skills, onSearchFiles, attachments, toolbar, layout, fontSize, lineHeight, affordances, draft, className, ref }: ComposerProps): import("react").JSX.Element;
|
|
919
|
+
declare function Composer({ onSend, onInterrupt, busy, disabled, placeholder, commands, skills, onSearchFiles, onShellCommand, attachments, toolbar, layout, fontSize, lineHeight, affordances, draft, className, ref }: ComposerProps): import("react").JSX.Element;
|
|
907
920
|
//#endregion
|
|
908
921
|
//#region src/components/agent/ModelSelect.d.ts
|
|
909
922
|
interface ModelSelectProps {
|
|
@@ -1190,5 +1203,5 @@ declare function copyText(value: string): Promise<boolean>;
|
|
|
1190
1203
|
declare function toolIcon(toolName: string): LucideIcon;
|
|
1191
1204
|
declare function isMutatingTool(toolName: string): boolean;
|
|
1192
1205
|
//#endregion
|
|
1193
|
-
export { AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, Badge, type BadgeProps, Band, Blank, Button, type ButtonProps, Card, CardContent, CardHeader, CardTitle, type ChipSegment, CodeBlock, type CodeBlockProps, Composer, type ComposerFileMatch, type ComposerHandle, type ComposerProps, ContextDialog, type ContextDialogProps, 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, HostFilesDialog, type HostFilesDialogProps, Ink, Input, Loader, McpDialog, type McpDialogProps, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, type MessageProps, ModelSelect, type ModelSelectProps, PERMISSION_MODES, type PermissionModeChoice, type PermissionModeMeta, PermissionModeSelect, type PermissionModeSelectProps, PermissionPrompt, type PermissionPromptProps, 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, STATUS_META, type Segment, Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue, SessionBrowser, type SessionBrowserProps, type SessionControls, SessionEmptyState, type SessionEmptyStateProps, SessionInfoDialog, type SessionInfoDialogProps, SessionItem, type SessionItemProps, SessionList, SessionListItem, type SessionListItemProps, type SessionListProps, SessionPanel, type SessionPanelProps, SessionStatusIcon, type SessionSurfacePanel, type SessionVitals, SkillsDialog, type SkillsDialogProps, Spinner, Splitter, type SplitterProps, StatusBar, type StatusBarProps, type Step, StepRow, StepToggle, SubagentStrip, TaskList, type TaskListProps, 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 TranscriptDensity, TranscriptDensityProvider, type TranscriptFont, type TranscriptProps, type TranscriptVariant, TranscriptVariantProvider, type TriggerConfig, type TriggerSuggestion, UsageDialog, type UsageDialogProps, UsageMeters, WithActions, badgeVariants, buttonVariants, cn, commandTrigger, copyText, engineMark, formatAgoPrecise, formatBytes, formatCost, formatCountdown, formatDuration, formatRateLimitWindow, formatRateLimitWindowLong, formatRelativeTime, formatTokens, friendlyModel, getChipsByTrigger, hashtagTrigger, isMutatingTool, isSegmentsEmpty, mentionTrigger, parseUserQuestions, permissionModeChoices, permissionModeMeta, plainTextToSegments, previewPatch, rateLimitWindowSeconds, rowShapeClass, runningSteps, segmentsToPlainText, sessionSteps, skillPrompt, toast, toolIcon, toolInputPreview, useAffordances, useMinuteClock, usePromptAreaState, useToolTitle, useTranscriptDensity, useTranscriptVariant, vendorMarkClass, vendorTextClass };
|
|
1206
|
+
export { AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, Badge, type BadgeProps, Band, Blank, Button, type ButtonProps, Card, CardContent, CardHeader, CardTitle, type ChipSegment, CodeBlock, type CodeBlockProps, Composer, type ComposerFileMatch, type ComposerHandle, type ComposerProps, ContextDialog, type ContextDialogProps, 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, HostFilesDialog, type HostFilesDialogProps, Ink, Input, Loader, McpDialog, type McpDialogProps, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, type MessageProps, ModelSelect, type ModelSelectProps, PERMISSION_MODES, type PermissionModeChoice, type PermissionModeMeta, PermissionModeSelect, type PermissionModeSelectProps, PermissionPrompt, type PermissionPromptProps, 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, STATUS_META, type Segment, Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue, SessionBrowser, type SessionBrowserProps, type SessionControls, SessionEmptyState, type SessionEmptyStateProps, SessionInfoDialog, type SessionInfoDialogProps, SessionItem, type SessionItemProps, SessionList, SessionListItem, type SessionListItemProps, type SessionListProps, SessionPanel, type SessionPanelProps, SessionStatusIcon, type SessionSurfacePanel, type SessionVitals, SkillsDialog, type SkillsDialogProps, Spinner, Splitter, type SplitterProps, StatusBar, type StatusBarProps, type Step, StepRow, StepToggle, SubagentStrip, TaskList, type TaskListProps, 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 TranscriptDensity, TranscriptDensityProvider, type TranscriptFont, type TranscriptProps, type TranscriptVariant, TranscriptVariantProvider, type TriggerConfig, type TriggerSuggestion, UsageDialog, type UsageDialogProps, UsageMeters, WithActions, badgeVariants, buttonVariants, cn, commandTrigger, copyText, engineMark, formatAgoPrecise, formatBytes, formatCost, formatCountdown, formatDuration, formatRateLimitWindow, formatRateLimitWindowLong, formatRelativeTime, formatTokens, friendlyModel, getChipsByTrigger, hashtagTrigger, isMutatingTool, isSegmentsEmpty, launchTrigger, mentionTrigger, parseUserQuestions, permissionModeChoices, permissionModeMeta, plainTextToSegments, previewPatch, rateLimitWindowSeconds, rowShapeClass, runningSteps, segmentsToPlainText, sessionSteps, skillPrompt, toast, toolIcon, toolInputPreview, useAffordances, useMinuteClock, usePromptAreaState, useToolTitle, useTranscriptDensity, useTranscriptVariant, vendorMarkClass, vendorTextClass };
|
|
1194
1207
|
//# sourceMappingURL=index.d.mts.map
|
package/build/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as Ink, A as PERMISSION_MODES, At as
|
|
1
|
+
import { $ as Ink, A as PERMISSION_MODES, At as DialogContent, B as TaskList, Bt as SelectContent, C as TerminalPermissionPrompt, Ct as copyText, D as SubagentStrip, Dt as Dialog, E as parseUserQuestions, Et as TooltipProvider, F as SkillsDialog, Ft as MenuContent, G as TerminalSurface, Gt as PortalScope, H as contextNote, Ht as SelectItemText, I as McpDialog, It as MenuItem, J as TerminalMarkdown, Jt as badgeVariants, K as ToolTitleProvider, Kt as Input, L as HostFilesDialog, Lt as MenuSeparator, M as permissionModeChoices, Mt as DialogRow, N as permissionModeMeta, Nt as DialogTrigger, O as PermissionPrompt, Ot as DialogBody, P as ModelSelect, Pt as Menu, Q as Blank, Rt as MenuTrigger, S as TerminalQuestionPrompt, St as CopyButton, T as QuestionPrompt, Tt as TooltipContent, U as Composer, Ut as SelectTrigger, V as ContextDialog, Vt as SelectItem, W as skillPrompt, Wt as SelectValue, X as previewPatch, Xt as buttonVariants, Y as TerminalDiff, Yt as Button, Z as Band, Zt as cn, _ as ConversationContent, _t as segmentsToPlainText, a as Transcript, at as toolIcon, b as STATUS_META, bt as CodeBlock, c as PromptTokenText, ct as useTranscriptDensity, d as FileCard, dt as hashtagTrigger, et as Row, f as TerminalItemView, ft as launchTrigger, g as Conversation, gt as plainTextToSegments, h as Loader, ht as PromptArea, i as useMinuteClock, it as isMutatingTool, j as PermissionModeSelect, jt as DialogHeader, k as Response, kt as DialogClose, l as Message, lt as useTranscriptVariant, m as SessionEmptyState, mt as usePromptAreaState, n as UsageDialog, nt as WithActions, o as ToolCallCard, ot as TranscriptDensityProvider, p as TerminalTranscript, pt as mentionTrigger, q as useToolTitle, qt as Badge, r as UsageMeters, rt as useAffordances, s as Reasoning, st as TranscriptVariantProvider, t as SessionPanel, tt as CopyAction, u as MessageContent, ut as commandTrigger, v as ConversationScrollButton, vt as ProgressRing, w as QUESTION_BEHAVIORS, wt as Tip, x as SessionInfoDialog, xt as Spinner, y as StatusBar, yt as Splitter, z as TasksDialog, zt as Select } from "./SessionPanel-ErvQUyHe.mjs";
|
|
2
2
|
import { C as toolInputPreview, S as rateLimitWindowSeconds, _ as formatRateLimitWindow, b as formatTokens, c as tightestWindow, f as formatAgoPrecise, g as formatDuration, h as formatCountdown, i as meterSeverity, m as formatCost, o as modelLabel, p as formatBytes, r as meterColorClass, s as statusPresentation, t as contextSeverity, u as windowLabel, v as formatRateLimitWindowLong, x as friendlyModel, y as formatRelativeTime } from "./status-C4TAgVSc.mjs";
|
|
3
3
|
import { Fragment, forwardRef, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1089,6 +1089,6 @@ function OneOfSelect({ label, value, options, onChange }) {
|
|
|
1089
1089
|
});
|
|
1090
1090
|
}
|
|
1091
1091
|
//#endregion
|
|
1092
|
-
export { AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, Badge, Band, Blank, Button, Card, CardContent, CardHeader, CardTitle, CodeBlock, Composer, ContextDialog, ContextRing, Conversation, ConversationContent, ConversationScrollButton, CopyAction, CopyButton, Dialog, DialogBody, DialogClose, DialogContent, DialogHeader, DialogRow, DialogTrigger, Empty, EmptyKey, EngineIcon, FileCard, HostFilesDialog, Ink, Input, Loader, McpDialog, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, ModelSelect, PERMISSION_MODES, PermissionModeSelect, PermissionPrompt, ProgressRing, ProjectIcon, PromptArea, PromptTokenText, QUESTION_BEHAVIORS, QuestionPrompt, Reasoning, Response, Row, STATUS_META, Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue, SessionBrowser, SessionEmptyState, SessionInfoDialog, SessionItem, SessionList, SessionListItem, SessionPanel, SessionStatusIcon, SkillsDialog, Spinner, Splitter, StatusBar, StepRow, StepToggle, SubagentStrip, TaskList, TasksDialog, TerminalDiff, TerminalItemView, TerminalMarkdown, TerminalPermissionPrompt, TerminalQuestionPrompt, TerminalStatusLine, TerminalSurface, TerminalTranscript, Textarea, Tip, Toaster, ToolCallCard, ToolTitleProvider, TooltipContent, TooltipProvider, Transcript, TranscriptDensityProvider, TranscriptVariantProvider, UsageDialog, UsageMeters, WithActions, badgeVariants, buttonVariants, cn, commandTrigger, copyText, engineMark, formatAgoPrecise, formatBytes, formatCost, formatCountdown, formatDuration, formatRateLimitWindow, formatRateLimitWindowLong, formatRelativeTime, formatTokens, friendlyModel, getChipsByTrigger, hashtagTrigger, isMutatingTool, isSegmentsEmpty, mentionTrigger, parseUserQuestions, permissionModeChoices, permissionModeMeta, plainTextToSegments, previewPatch, rateLimitWindowSeconds, rowShapeClass, runningSteps, segmentsToPlainText, sessionSteps, skillPrompt, toast, toolIcon, toolInputPreview, useAffordances, useMinuteClock, usePromptAreaState, useToolTitle, useTranscriptDensity, useTranscriptVariant, vendorMarkClass, vendorTextClass };
|
|
1092
|
+
export { AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, Badge, Band, Blank, Button, Card, CardContent, CardHeader, CardTitle, CodeBlock, Composer, ContextDialog, ContextRing, Conversation, ConversationContent, ConversationScrollButton, CopyAction, CopyButton, Dialog, DialogBody, DialogClose, DialogContent, DialogHeader, DialogRow, DialogTrigger, Empty, EmptyKey, EngineIcon, FileCard, HostFilesDialog, Ink, Input, Loader, McpDialog, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, ModelSelect, PERMISSION_MODES, PermissionModeSelect, PermissionPrompt, ProgressRing, ProjectIcon, PromptArea, PromptTokenText, QUESTION_BEHAVIORS, QuestionPrompt, Reasoning, Response, Row, STATUS_META, Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue, SessionBrowser, SessionEmptyState, SessionInfoDialog, SessionItem, SessionList, SessionListItem, SessionPanel, SessionStatusIcon, SkillsDialog, Spinner, Splitter, StatusBar, StepRow, StepToggle, SubagentStrip, TaskList, TasksDialog, TerminalDiff, TerminalItemView, TerminalMarkdown, TerminalPermissionPrompt, TerminalQuestionPrompt, TerminalStatusLine, TerminalSurface, TerminalTranscript, Textarea, Tip, Toaster, ToolCallCard, ToolTitleProvider, TooltipContent, TooltipProvider, Transcript, TranscriptDensityProvider, TranscriptVariantProvider, UsageDialog, UsageMeters, WithActions, badgeVariants, buttonVariants, cn, commandTrigger, copyText, engineMark, formatAgoPrecise, formatBytes, formatCost, formatCountdown, formatDuration, formatRateLimitWindow, formatRateLimitWindowLong, formatRelativeTime, formatTokens, friendlyModel, getChipsByTrigger, hashtagTrigger, isMutatingTool, isSegmentsEmpty, launchTrigger, mentionTrigger, parseUserQuestions, permissionModeChoices, permissionModeMeta, plainTextToSegments, previewPatch, rateLimitWindowSeconds, rowShapeClass, runningSteps, segmentsToPlainText, sessionSteps, skillPrompt, toast, toolIcon, toolInputPreview, useAffordances, useMinuteClock, usePromptAreaState, useToolTitle, useTranscriptDensity, useTranscriptVariant, vendorMarkClass, vendorTextClass };
|
|
1093
1093
|
|
|
1094
1094
|
//# sourceMappingURL=index.mjs.map
|
package/build/scoped.css
CHANGED
|
@@ -980,6 +980,9 @@
|
|
|
980
980
|
border-left-style: var(--tw-border-style);
|
|
981
981
|
border-left-width: 4px;
|
|
982
982
|
}
|
|
983
|
+
.wd-root .border-\[var\(--wd-shell-accent\)\] {
|
|
984
|
+
border-color: var(--wd-shell-accent);
|
|
985
|
+
}
|
|
983
986
|
.wd-root .border-border {
|
|
984
987
|
border-color: var(--border);
|
|
985
988
|
}
|
|
@@ -1536,6 +1539,9 @@
|
|
|
1536
1539
|
.wd-root .text-\[var\(--sdm-c\,inherit\)\] {
|
|
1537
1540
|
color: var(--sdm-c,inherit);
|
|
1538
1541
|
}
|
|
1542
|
+
.wd-root .text-\[var\(--wd-shell-accent\)\] {
|
|
1543
|
+
color: var(--wd-shell-accent);
|
|
1544
|
+
}
|
|
1539
1545
|
.wd-root .text-accent {
|
|
1540
1546
|
color: var(--accent);
|
|
1541
1547
|
}
|
|
@@ -1855,6 +1861,9 @@
|
|
|
1855
1861
|
content: var(--tw-content);
|
|
1856
1862
|
counter-increment: line;
|
|
1857
1863
|
}
|
|
1864
|
+
.wd-root .focus-within\:border-\[var\(--wd-shell-accent\)\]:focus-within {
|
|
1865
|
+
border-color: var(--wd-shell-accent);
|
|
1866
|
+
}
|
|
1858
1867
|
.wd-root .focus-within\:border-ring:focus-within {
|
|
1859
1868
|
border-color: var(--ring);
|
|
1860
1869
|
}
|
|
@@ -1862,6 +1871,12 @@
|
|
|
1862
1871
|
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
1863
1872
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
1864
1873
|
}
|
|
1874
|
+
.wd-root .focus-within\:ring-\[var\(--wd-shell-accent\)\]\/30:focus-within {
|
|
1875
|
+
--tw-ring-color: var(--wd-shell-accent);
|
|
1876
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1877
|
+
--tw-ring-color: color-mix(in oklab, var(--wd-shell-accent) 30%, transparent);
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1865
1880
|
.wd-root .focus-within\:ring-ring\/30:focus-within {
|
|
1866
1881
|
--tw-ring-color: var(--ring);
|
|
1867
1882
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -2381,6 +2396,8 @@
|
|
|
2381
2396
|
background: var(--term-user-bg);
|
|
2382
2397
|
margin-inline: calc(-1 * var(--term-bleed, 0px));
|
|
2383
2398
|
padding-inline: var(--term-bleed, 0px);
|
|
2399
|
+
user-select: text;
|
|
2400
|
+
cursor: text;
|
|
2384
2401
|
}
|
|
2385
2402
|
.wd-root [data-terminal] .term-link {
|
|
2386
2403
|
text-decoration: underline;
|
|
@@ -2497,6 +2514,12 @@
|
|
|
2497
2514
|
.wd-root [data-terminal].term-composer:focus-within, .wd-root [data-terminal].term-composer[data-dragging] {
|
|
2498
2515
|
border-color: var(--term-blue);
|
|
2499
2516
|
}
|
|
2517
|
+
.wd-root [data-terminal].term-composer-shell, .wd-root [data-terminal].term-composer-shell:focus-within {
|
|
2518
|
+
border-color: var(--term-magenta);
|
|
2519
|
+
}
|
|
2520
|
+
.wd-root [data-terminal] .term-composer-shell-hint {
|
|
2521
|
+
color: var(--term-dim);
|
|
2522
|
+
}
|
|
2500
2523
|
.wd-root [data-terminal] .term-composer-field {
|
|
2501
2524
|
font: inherit;
|
|
2502
2525
|
color: var(--term-fg);
|
|
@@ -2834,6 +2857,7 @@
|
|
|
2834
2857
|
--shine: #dcdcdc;
|
|
2835
2858
|
--frame-shadow: var(--shadow-xs);
|
|
2836
2859
|
--wd-scrub-bookmark: #8b3a8b;
|
|
2860
|
+
--wd-shell-accent: #8b3a8b;
|
|
2837
2861
|
--surface: var(--bg-surface);
|
|
2838
2862
|
--sidebar: #f4f4f4;
|
|
2839
2863
|
--text: var(--fg-1);
|
|
@@ -2886,6 +2910,7 @@
|
|
|
2886
2910
|
--shine: #303030;
|
|
2887
2911
|
--frame-shadow: 0 4px 24px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.45);
|
|
2888
2912
|
--wd-scrub-bookmark: #c586c0;
|
|
2913
|
+
--wd-shell-accent: #c586c0;
|
|
2889
2914
|
--surface: var(--bg-surface);
|
|
2890
2915
|
--sidebar: #131313;
|
|
2891
2916
|
--text: var(--fg-1);
|
package/build/workspace.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Et as TooltipProvider, Kt as Input, R as EntryIcon, Yt as Button, Zt as cn, t as SessionPanel, wt as Tip, xt as Spinner, yt as Splitter } from "./SessionPanel-ErvQUyHe.mjs";
|
|
2
2
|
import { p as formatBytes } from "./status-C4TAgVSc.mjs";
|
|
3
3
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
4
4
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workerdeck/ui",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Styled agent-control component library for WorkerDeck: session panel, transcript with streaming, tool-call cards, permission prompts, session list, composer. Tailwind v4 + Base UI + cva. Pairs with the headless @workerdeck/react layer.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"streamdown": "^2.6.0",
|
|
40
40
|
"tailwind-merge": "^3.6.0",
|
|
41
41
|
"use-stick-to-bottom": "^1.1.6",
|
|
42
|
-
"@workerdeck/
|
|
43
|
-
"@workerdeck/
|
|
44
|
-
"@workerdeck/
|
|
42
|
+
"@workerdeck/client": "2.2.1",
|
|
43
|
+
"@workerdeck/protocol": "2.2.1",
|
|
44
|
+
"@workerdeck/react": "2.2.1"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"monaco-editor": "^0.56.0",
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
useEffect,
|
|
3
|
+
useImperativeHandle,
|
|
4
|
+
useMemo,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
type DragEvent,
|
|
8
|
+
type KeyboardEvent,
|
|
9
|
+
type ReactNode,
|
|
10
|
+
type Ref,
|
|
11
|
+
} from 'react'
|
|
2
12
|
import type { SkillInfo, SlashCommandInfo } from '@workerdeck/protocol'
|
|
3
13
|
import type { StagedAttachment, UseAttachmentsResult } from '@workerdeck/react'
|
|
4
14
|
import { ArrowUp, FileText, Paperclip, RotateCw, Sparkles, Square, TriangleAlert, X } from 'lucide-react'
|
|
@@ -7,7 +17,7 @@ import { Spinner } from '../ui/Spinner.tsx'
|
|
|
7
17
|
import { PromptArea } from '../prompt-area/prompt-area.tsx'
|
|
8
18
|
import { usePromptAreaState } from '../prompt-area/use-prompt-area-state.ts'
|
|
9
19
|
import { plainTextToSegments } from '../prompt-area/prompt-area-engine.ts'
|
|
10
|
-
import { commandTrigger, mentionTrigger } from '../prompt-area/trigger-presets.ts'
|
|
20
|
+
import { commandTrigger, launchTrigger, mentionTrigger } from '../prompt-area/trigger-presets.ts'
|
|
11
21
|
import { useTranscriptVariant } from './transcript-variant.tsx'
|
|
12
22
|
import type { TerminalAffordances } from '../terminal/affordances.tsx'
|
|
13
23
|
import { PROMPT_GLYPH } from '../terminal/items.tsx'
|
|
@@ -18,6 +28,9 @@ import { formatBytes } from '../../lib/format.ts'
|
|
|
18
28
|
|
|
19
29
|
export type ComposerFileMatch = { path: string; relative: string }
|
|
20
30
|
|
|
31
|
+
const SHELL_PLACEHOLDER = 'Run a command on the host…'
|
|
32
|
+
const SHELL_HINT = '! shell mode · esc to exit'
|
|
33
|
+
|
|
21
34
|
export type ComposerHandle = {
|
|
22
35
|
insertText: (text: string) => void
|
|
23
36
|
focus: () => void
|
|
@@ -32,6 +45,9 @@ export interface ComposerProps {
|
|
|
32
45
|
commands?: SlashCommandInfo[]
|
|
33
46
|
skills?: SkillInfo[]
|
|
34
47
|
onSearchFiles?: (query: string, options: { signal: AbortSignal }) => Promise<ComposerFileMatch[]>
|
|
48
|
+
// Shell mode: `!` as the first character turns the composer into a host shell prompt. Omit to leave the
|
|
49
|
+
// mode off entirely — the gateway only offers it to an operator on a session whose engine reaches a host cwd.
|
|
50
|
+
onShellCommand?: (command: string) => void
|
|
35
51
|
attachments?: UseAttachmentsResult
|
|
36
52
|
toolbar?: ReactNode
|
|
37
53
|
layout?: 'stacked' | 'inline'
|
|
@@ -72,6 +88,7 @@ export function Composer({
|
|
|
72
88
|
commands,
|
|
73
89
|
skills,
|
|
74
90
|
onSearchFiles,
|
|
91
|
+
onShellCommand,
|
|
75
92
|
attachments,
|
|
76
93
|
toolbar,
|
|
77
94
|
layout = 'stacked',
|
|
@@ -91,6 +108,7 @@ export function Composer({
|
|
|
91
108
|
)
|
|
92
109
|
const fileInput = useRef<HTMLInputElement>(null)
|
|
93
110
|
const [dragging, setDragging] = useState(false)
|
|
111
|
+
const [shellMode, setShellMode] = useState(false)
|
|
94
112
|
|
|
95
113
|
useImperativeHandle(
|
|
96
114
|
ref,
|
|
@@ -196,8 +214,17 @@ export function Composer({
|
|
|
196
214
|
}),
|
|
197
215
|
)
|
|
198
216
|
}
|
|
217
|
+
if (onShellCommand) {
|
|
218
|
+
configured.push(
|
|
219
|
+
launchTrigger({
|
|
220
|
+
char: '!',
|
|
221
|
+
accessibilityLabel: 'shell mode',
|
|
222
|
+
onActivate: () => setShellMode(true),
|
|
223
|
+
}),
|
|
224
|
+
)
|
|
225
|
+
}
|
|
199
226
|
return configured.length > 0 ? configured : undefined
|
|
200
|
-
}, [commands, skills, onSearchFiles])
|
|
227
|
+
}, [commands, skills, onSearchFiles, onShellCommand])
|
|
201
228
|
|
|
202
229
|
const saveDraft = draft?.save
|
|
203
230
|
useEffect(() => {
|
|
@@ -211,6 +238,18 @@ export function Composer({
|
|
|
211
238
|
if (!canSend) {
|
|
212
239
|
return
|
|
213
240
|
}
|
|
241
|
+
if (shellMode) {
|
|
242
|
+
const command = plainText.trim()
|
|
243
|
+
if (command === '') {
|
|
244
|
+
return
|
|
245
|
+
}
|
|
246
|
+
onShellCommand?.(command)
|
|
247
|
+
setShellMode(false)
|
|
248
|
+
draft?.clear()
|
|
249
|
+
clear()
|
|
250
|
+
focus()
|
|
251
|
+
return
|
|
252
|
+
}
|
|
214
253
|
onSend(plainText.trim(), attachments?.readyIds ?? [])
|
|
215
254
|
attachments?.clear()
|
|
216
255
|
draft?.clear()
|
|
@@ -218,6 +257,24 @@ export function Composer({
|
|
|
218
257
|
focus()
|
|
219
258
|
}
|
|
220
259
|
|
|
260
|
+
const leaveShellMode = () => {
|
|
261
|
+
setShellMode(false)
|
|
262
|
+
focus()
|
|
263
|
+
}
|
|
264
|
+
// Escape and backspace-on-empty both leave, because both are what a person reaches for when the
|
|
265
|
+
// pink frame was not what they meant. Backspace only when there is nothing left to delete.
|
|
266
|
+
const shellKeys = shellMode
|
|
267
|
+
? {
|
|
268
|
+
onEscape: leaveShellMode,
|
|
269
|
+
onKeyDown: (e: KeyboardEvent<HTMLDivElement>) => {
|
|
270
|
+
if (e.key === 'Backspace' && isEmpty) {
|
|
271
|
+
e.preventDefault()
|
|
272
|
+
leaveShellMode()
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
}
|
|
276
|
+
: {}
|
|
277
|
+
|
|
221
278
|
const pick = (files: FileList | null) => {
|
|
222
279
|
if (files && files.length > 0) {
|
|
223
280
|
attachments?.add(files)
|
|
@@ -250,7 +307,11 @@ export function Composer({
|
|
|
250
307
|
</>
|
|
251
308
|
) : null
|
|
252
309
|
|
|
253
|
-
const gutter =
|
|
310
|
+
const gutter = shellMode ? (
|
|
311
|
+
<GlyphButton gutter label="Leave shell mode" tone="magenta" onClick={leaveShellMode}>
|
|
312
|
+
!
|
|
313
|
+
</GlyphButton>
|
|
314
|
+
) : busy ? (
|
|
254
315
|
<GlyphButton gutter label="Interrupt" tone="yellow" onClick={onInterrupt}>
|
|
255
316
|
✕
|
|
256
317
|
</GlyphButton>
|
|
@@ -318,12 +379,12 @@ export function Composer({
|
|
|
318
379
|
affordances={affordances}
|
|
319
380
|
bleed="1ch"
|
|
320
381
|
data-dragging={dragging || undefined}
|
|
321
|
-
className={cn('term-composer', disabled && 'opacity-60')}
|
|
382
|
+
className={cn('term-composer', shellMode && 'term-composer-shell', disabled && 'opacity-60')}
|
|
322
383
|
>
|
|
323
384
|
<div className="term-composer-body">
|
|
324
385
|
{staged.length > 0 && attachments ? <AttachmentStrip attachments={attachments} /> : null}
|
|
325
386
|
<div className="term-row">
|
|
326
|
-
{canAttach ? fileField : null}
|
|
387
|
+
{canAttach && !shellMode ? fileField : null}
|
|
327
388
|
{gutter}
|
|
328
389
|
<div className="flex min-w-0 items-start">
|
|
329
390
|
<PromptArea
|
|
@@ -333,17 +394,23 @@ export function Composer({
|
|
|
333
394
|
normalizeBullets={false}
|
|
334
395
|
onSubmit={submit}
|
|
335
396
|
disabled={disabled}
|
|
336
|
-
placeholder={disabled ? 'Session ended' : placeholder}
|
|
397
|
+
placeholder={disabled ? 'Session ended' : shellMode ? SHELL_PLACEHOLDER : placeholder}
|
|
337
398
|
minHeight={line}
|
|
338
399
|
maxHeight={line * 10}
|
|
339
|
-
aria-label=
|
|
400
|
+
aria-label={shellMode ? 'Run a shell command' : 'Message the agent'}
|
|
340
401
|
className="term-composer-field min-w-0 flex-1"
|
|
341
402
|
onImagePaste={(file) => attachments?.add([file])}
|
|
403
|
+
{...shellKeys}
|
|
342
404
|
/>
|
|
343
405
|
{submitButton}
|
|
344
406
|
</div>
|
|
345
407
|
</div>
|
|
346
|
-
{
|
|
408
|
+
{shellMode ? (
|
|
409
|
+
<div className="term-row">
|
|
410
|
+
<span aria-hidden className="term-gutter" />
|
|
411
|
+
<span className="term-composer-shell-hint">{SHELL_HINT}</span>
|
|
412
|
+
</div>
|
|
413
|
+
) : toolbar ? (
|
|
347
414
|
<div className="term-row">
|
|
348
415
|
<span aria-hidden className="term-gutter" />
|
|
349
416
|
<div className="flex min-w-0 items-center gap-[1ch]">{toolbar}</div>
|
|
@@ -365,13 +432,15 @@ export function Composer({
|
|
|
365
432
|
'transition-colors rounded-lg shadow-(--shadow-xs)',
|
|
366
433
|
'focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/30',
|
|
367
434
|
dragging && 'border-ring ring-2 ring-ring/30',
|
|
435
|
+
shellMode &&
|
|
436
|
+
'border-[var(--wd-shell-accent)] focus-within:border-[var(--wd-shell-accent)] focus-within:ring-[var(--wd-shell-accent)]/30',
|
|
368
437
|
disabled && 'opacity-60',
|
|
369
438
|
)}
|
|
370
439
|
>
|
|
371
440
|
{staged.length > 0 && attachments ? <AttachmentStrip attachments={attachments} /> : null}
|
|
372
441
|
{inline ? (
|
|
373
442
|
<div className="flex items-end gap-1 p-1">
|
|
374
|
-
{attach}
|
|
443
|
+
{shellMode ? <ShellBadge onLeave={leaveShellMode} /> : attach}
|
|
375
444
|
<PromptArea
|
|
376
445
|
{...bind}
|
|
377
446
|
triggers={triggers}
|
|
@@ -379,12 +448,13 @@ export function Composer({
|
|
|
379
448
|
normalizeBullets={false}
|
|
380
449
|
onSubmit={submit}
|
|
381
450
|
disabled={disabled}
|
|
382
|
-
placeholder={disabled ? 'Session ended' : placeholder}
|
|
451
|
+
placeholder={disabled ? 'Session ended' : shellMode ? SHELL_PLACEHOLDER : placeholder}
|
|
383
452
|
minHeight={20}
|
|
384
453
|
maxHeight={192}
|
|
385
|
-
aria-label=
|
|
454
|
+
aria-label={shellMode ? 'Run a shell command' : 'Message the agent'}
|
|
386
455
|
className="min-w-0 flex-1 py-1 text-body-sm text-text"
|
|
387
456
|
onImagePaste={(file) => attachments?.add([file])}
|
|
457
|
+
{...shellKeys}
|
|
388
458
|
/>
|
|
389
459
|
{submitButton}
|
|
390
460
|
</div>
|
|
@@ -397,17 +467,18 @@ export function Composer({
|
|
|
397
467
|
normalizeBullets={false}
|
|
398
468
|
onSubmit={submit}
|
|
399
469
|
disabled={disabled}
|
|
400
|
-
placeholder={disabled ? 'Session ended' : placeholder}
|
|
470
|
+
placeholder={disabled ? 'Session ended' : shellMode ? SHELL_PLACEHOLDER : placeholder}
|
|
401
471
|
minHeight={28}
|
|
402
472
|
maxHeight={192}
|
|
403
|
-
aria-label=
|
|
473
|
+
aria-label={shellMode ? 'Run a shell command' : 'Message the agent'}
|
|
404
474
|
className="px-3 pt-2.5 pb-0 text-body-sm text-text"
|
|
405
475
|
onImagePaste={(file) => attachments?.add([file])}
|
|
476
|
+
{...shellKeys}
|
|
406
477
|
/>
|
|
407
478
|
<div className="flex items-center justify-between gap-2 px-2 pb-2">
|
|
408
479
|
<div className="flex min-w-0 items-center gap-1">
|
|
409
|
-
{attach}
|
|
410
|
-
{toolbar}
|
|
480
|
+
{shellMode ? <ShellBadge onLeave={leaveShellMode} /> : attach}
|
|
481
|
+
{shellMode ? <span className="text-label text-text-muted">{SHELL_HINT}</span> : toolbar}
|
|
411
482
|
</div>
|
|
412
483
|
{submitButton}
|
|
413
484
|
</div>
|
|
@@ -428,7 +499,7 @@ function GlyphButton({
|
|
|
428
499
|
className,
|
|
429
500
|
children,
|
|
430
501
|
}: {
|
|
431
|
-
tone?: 'blue' | 'yellow'
|
|
502
|
+
tone?: 'blue' | 'yellow' | 'magenta'
|
|
432
503
|
label: string
|
|
433
504
|
disabled?: boolean
|
|
434
505
|
onClick: () => void
|
|
@@ -526,3 +597,17 @@ function extensionOf(name: string) {
|
|
|
526
597
|
const dot = name.lastIndexOf('.')
|
|
527
598
|
return dot > 0 ? name.slice(dot + 1).toUpperCase() : 'FILE'
|
|
528
599
|
}
|
|
600
|
+
|
|
601
|
+
function ShellBadge({ onLeave }: { onLeave: () => void }) {
|
|
602
|
+
return (
|
|
603
|
+
<button
|
|
604
|
+
type="button"
|
|
605
|
+
aria-label="Leave shell mode"
|
|
606
|
+
title="Leave shell mode"
|
|
607
|
+
onClick={onLeave}
|
|
608
|
+
className="shrink-0 rounded px-1.5 py-0.5 font-mono text-label font-semibold text-[var(--wd-shell-accent)]"
|
|
609
|
+
>
|
|
610
|
+
!
|
|
611
|
+
</button>
|
|
612
|
+
)
|
|
613
|
+
}
|
|
@@ -229,10 +229,12 @@ export function SessionPanel({
|
|
|
229
229
|
connection,
|
|
230
230
|
replaying,
|
|
231
231
|
protocolMismatch,
|
|
232
|
+
shell,
|
|
232
233
|
models,
|
|
233
234
|
effectiveModel,
|
|
234
235
|
handle,
|
|
235
236
|
send,
|
|
237
|
+
runShell,
|
|
236
238
|
approve,
|
|
237
239
|
deny,
|
|
238
240
|
interrupt,
|
|
@@ -695,6 +697,7 @@ export function SessionPanel({
|
|
|
695
697
|
attachments={attachments}
|
|
696
698
|
draft={draft}
|
|
697
699
|
onSearchFiles={hostFiles.available ? searchComposerFiles : undefined}
|
|
700
|
+
onShellCommand={shell ? runShell : undefined}
|
|
698
701
|
layout={controlsExternal ? 'inline' : 'stacked'}
|
|
699
702
|
toolbar={controlsExternal ? undefined : sessionControls}
|
|
700
703
|
fontSize={effectiveTermFontSize}
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { PromptArea } from './prompt-area.tsx'
|
|
7
7
|
export { usePromptAreaState } from './use-prompt-area-state.ts'
|
|
8
|
-
export { commandTrigger, mentionTrigger, hashtagTrigger } from './trigger-presets.ts'
|
|
8
|
+
export { commandTrigger, mentionTrigger, hashtagTrigger, launchTrigger } from './trigger-presets.ts'
|
|
9
9
|
export { segmentsToPlainText, plainTextToSegments, isSegmentsEmpty, getChipsByTrigger } from './segment-helpers.ts'
|
|
10
10
|
export type { PromptAreaHandle, PromptAreaProps, Segment, ChipSegment, TextSegment, TriggerConfig, TriggerSuggestion } from './types.ts'
|
|
@@ -131,3 +131,27 @@ export function callbackTrigger(opts: CallbackTriggerOptions): TriggerConfig {
|
|
|
131
131
|
...rest,
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
+
|
|
135
|
+
// Launch trigger — fires onActivate and swallows the character
|
|
136
|
+
|
|
137
|
+
export type LaunchTriggerOptions = Omit<Partial<TriggerConfig>, 'mode'> & {
|
|
138
|
+
/** The trigger character. Required. */
|
|
139
|
+
char: string
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Creates a **launch** trigger: `onActivate` fires on keydown and the character
|
|
144
|
+
* never enters the editor. For flipping the composer into another mode, or
|
|
145
|
+
* opening a surface outside it.
|
|
146
|
+
*
|
|
147
|
+
* Defaults: `position: 'start'`, `mode: 'launch'`.
|
|
148
|
+
*/
|
|
149
|
+
export function launchTrigger(opts: LaunchTriggerOptions): TriggerConfig {
|
|
150
|
+
const { char, ...rest } = opts
|
|
151
|
+
return {
|
|
152
|
+
char,
|
|
153
|
+
position: 'start',
|
|
154
|
+
mode: 'launch',
|
|
155
|
+
...rest,
|
|
156
|
+
}
|
|
157
|
+
}
|
package/src/index.ts
CHANGED
package/src/styles/terminal.css
CHANGED
|
@@ -401,6 +401,14 @@
|
|
|
401
401
|
background: var(--term-user-bg);
|
|
402
402
|
margin-inline: calc(-1 * var(--term-bleed, 0px));
|
|
403
403
|
padding-inline: var(--term-bleed, 0px);
|
|
404
|
+
/* Declared, never inherited. This band is the one transcript block that is
|
|
405
|
+
neither a `.term-press` nor plain flow text, so without saying so it takes
|
|
406
|
+
whatever the host gives it — which differs between the browser and the VS
|
|
407
|
+
Code webview, and a block that cannot host a selection endpoint does not
|
|
408
|
+
merely refuse the drag: the selection jumps to the next valid position
|
|
409
|
+
above it, swallowing everything in between. */
|
|
410
|
+
user-select: text;
|
|
411
|
+
cursor: text;
|
|
404
412
|
}
|
|
405
413
|
|
|
406
414
|
[data-terminal] .term-link {
|
|
@@ -643,6 +651,17 @@
|
|
|
643
651
|
border-color: var(--term-blue);
|
|
644
652
|
}
|
|
645
653
|
|
|
654
|
+
/* Shell mode. The frame and the gutter glyph move together and both go magenta, because the thing
|
|
655
|
+
the mode changes is where the text goes — a subtle cue would be the wrong kind of quiet. Listed
|
|
656
|
+
after the focus rule so it wins while the field is focused, which is the whole time it is on. */
|
|
657
|
+
[data-terminal].term-composer-shell,
|
|
658
|
+
[data-terminal].term-composer-shell:focus-within {
|
|
659
|
+
border-color: var(--term-magenta);
|
|
660
|
+
}
|
|
661
|
+
[data-terminal] .term-composer-shell-hint {
|
|
662
|
+
color: var(--term-dim);
|
|
663
|
+
}
|
|
664
|
+
|
|
646
665
|
/* The contentEditable field. `font: inherit` is what makes it the cell — the
|
|
647
666
|
surface above already carries the size and the line height, and anything that
|
|
648
667
|
restates them here can disagree with the rows. */
|
package/src/styles/theme.css
CHANGED
|
@@ -155,6 +155,10 @@
|
|
|
155
155
|
and every other colour on the rail is already spoken for. */
|
|
156
156
|
--wd-scrub-bookmark: #8b3a8b;
|
|
157
157
|
|
|
158
|
+
/* Shell mode's frame and glyph. The same magenta as the bookmark rail, for the same reason: the app
|
|
159
|
+
palette has no magenta, and shell mode must not read as focus (blue) or as an error (red). */
|
|
160
|
+
--wd-shell-accent: #8b3a8b;
|
|
161
|
+
|
|
158
162
|
/* ---------- aliases (bridge for the @theme utilities) ---------- */
|
|
159
163
|
--surface: var(--bg-surface);
|
|
160
164
|
--sidebar: #f4f4f4;
|
|
@@ -238,6 +242,7 @@
|
|
|
238
242
|
|
|
239
243
|
/* See the light block — lifted for the dark ground. */
|
|
240
244
|
--wd-scrub-bookmark: #c586c0;
|
|
245
|
+
--wd-shell-accent: #c586c0;
|
|
241
246
|
|
|
242
247
|
/* ---------- aliases ---------- */
|
|
243
248
|
--surface: var(--bg-surface);
|