@workerdeck/ui 2.1.0 → 2.2.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/{SessionPanel-DrMj8Yv0.mjs → SessionPanel-ErvQUyHe.mjs} +101 -21
- package/build/SessionPanel-ErvQUyHe.mjs.map +1 -0
- package/build/index.d.mts +15 -2
- package/build/index.mjs +2 -2
- package/build/scoped.css +23 -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 +11 -0
- package/src/styles/theme.css +5 -0
- package/build/SessionPanel-DrMj8Yv0.mjs.map +0 -1
|
@@ -4385,6 +4385,22 @@ function hashtagTrigger(opts = {}) {
|
|
|
4385
4385
|
...rest
|
|
4386
4386
|
};
|
|
4387
4387
|
}
|
|
4388
|
+
/**
|
|
4389
|
+
* Creates a **launch** trigger: `onActivate` fires on keydown and the character
|
|
4390
|
+
* never enters the editor. For flipping the composer into another mode, or
|
|
4391
|
+
* opening a surface outside it.
|
|
4392
|
+
*
|
|
4393
|
+
* Defaults: `position: 'start'`, `mode: 'launch'`.
|
|
4394
|
+
*/
|
|
4395
|
+
function launchTrigger(opts) {
|
|
4396
|
+
const { char, ...rest } = opts;
|
|
4397
|
+
return {
|
|
4398
|
+
char,
|
|
4399
|
+
position: "start",
|
|
4400
|
+
mode: "launch",
|
|
4401
|
+
...rest
|
|
4402
|
+
};
|
|
4403
|
+
}
|
|
4388
4404
|
//#endregion
|
|
4389
4405
|
//#region src/components/agent/transcript-variant.tsx
|
|
4390
4406
|
const VariantContext = createContext("cards");
|
|
@@ -5529,6 +5545,8 @@ function TerminalSurface({ fontSize, lineHeight, bleed, affordances, className,
|
|
|
5529
5545
|
}
|
|
5530
5546
|
//#endregion
|
|
5531
5547
|
//#region src/components/agent/Composer.tsx
|
|
5548
|
+
const SHELL_PLACEHOLDER = "Run a command on the host…";
|
|
5549
|
+
const SHELL_HINT = "! shell mode · esc to exit";
|
|
5532
5550
|
function cleanName(name) {
|
|
5533
5551
|
return name.replace(/\s*\(MCP\)$/i, "");
|
|
5534
5552
|
}
|
|
@@ -5542,13 +5560,14 @@ function matchScore(query, haystacks) {
|
|
|
5542
5560
|
if (lowered.some((h) => h.startsWith(needle))) return 2;
|
|
5543
5561
|
return lowered.some((h) => h.includes(needle)) ? 1 : 0;
|
|
5544
5562
|
}
|
|
5545
|
-
function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message the agent…", commands, skills, onSearchFiles, attachments, toolbar, layout = "stacked", fontSize, lineHeight, affordances, draft, className, ref }) {
|
|
5563
|
+
function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message the agent…", commands, skills, onSearchFiles, onShellCommand, attachments, toolbar, layout = "stacked", fontSize, lineHeight, affordances, draft, className, ref }) {
|
|
5546
5564
|
const inline = layout === "inline";
|
|
5547
5565
|
const terminal = useTranscriptVariant() === "terminal";
|
|
5548
5566
|
const [initialDraft] = useState(() => draft?.initialText ?? "");
|
|
5549
5567
|
const { bind, plainText, isEmpty, clear, focus } = usePromptAreaState(initialDraft === "" ? void 0 : { initialValue: plainTextToSegments(initialDraft) });
|
|
5550
5568
|
const fileInput = useRef(null);
|
|
5551
5569
|
const [dragging, setDragging] = useState(false);
|
|
5570
|
+
const [shellMode, setShellMode] = useState(false);
|
|
5552
5571
|
useImperativeHandle(ref, () => ({
|
|
5553
5572
|
insertText: (text) => {
|
|
5554
5573
|
const prefix = plainText.length > 0 && !/\s$/.test(plainText) ? " " : "";
|
|
@@ -5642,11 +5661,17 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
5642
5661
|
chipClassName: "font-mono",
|
|
5643
5662
|
emptyMessage: "No matching files"
|
|
5644
5663
|
}));
|
|
5664
|
+
if (onShellCommand) configured.push(launchTrigger({
|
|
5665
|
+
char: "!",
|
|
5666
|
+
accessibilityLabel: "shell mode",
|
|
5667
|
+
onActivate: () => setShellMode(true)
|
|
5668
|
+
}));
|
|
5645
5669
|
return configured.length > 0 ? configured : void 0;
|
|
5646
5670
|
}, [
|
|
5647
5671
|
commands,
|
|
5648
5672
|
skills,
|
|
5649
|
-
onSearchFiles
|
|
5673
|
+
onSearchFiles,
|
|
5674
|
+
onShellCommand
|
|
5650
5675
|
]);
|
|
5651
5676
|
const saveDraft = draft?.save;
|
|
5652
5677
|
useEffect(() => {
|
|
@@ -5656,12 +5681,35 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
5656
5681
|
const canSend = !disabled && (!isEmpty || staged.length > 0) && !attachments?.uploading && !attachments?.hasFailure;
|
|
5657
5682
|
const submit = () => {
|
|
5658
5683
|
if (!canSend) return;
|
|
5684
|
+
if (shellMode) {
|
|
5685
|
+
const command = plainText.trim();
|
|
5686
|
+
if (command === "") return;
|
|
5687
|
+
onShellCommand?.(command);
|
|
5688
|
+
setShellMode(false);
|
|
5689
|
+
draft?.clear();
|
|
5690
|
+
clear();
|
|
5691
|
+
focus();
|
|
5692
|
+
return;
|
|
5693
|
+
}
|
|
5659
5694
|
onSend(plainText.trim(), attachments?.readyIds ?? []);
|
|
5660
5695
|
attachments?.clear();
|
|
5661
5696
|
draft?.clear();
|
|
5662
5697
|
clear();
|
|
5663
5698
|
focus();
|
|
5664
5699
|
};
|
|
5700
|
+
const leaveShellMode = () => {
|
|
5701
|
+
setShellMode(false);
|
|
5702
|
+
focus();
|
|
5703
|
+
};
|
|
5704
|
+
const shellKeys = shellMode ? {
|
|
5705
|
+
onEscape: leaveShellMode,
|
|
5706
|
+
onKeyDown: (e) => {
|
|
5707
|
+
if (e.key === "Backspace" && isEmpty) {
|
|
5708
|
+
e.preventDefault();
|
|
5709
|
+
leaveShellMode();
|
|
5710
|
+
}
|
|
5711
|
+
}
|
|
5712
|
+
} : {};
|
|
5665
5713
|
const pick = (files) => {
|
|
5666
5714
|
if (files && files.length > 0) attachments?.add(files);
|
|
5667
5715
|
};
|
|
@@ -5685,7 +5733,13 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
5685
5733
|
onClick: () => fileInput.current?.click(),
|
|
5686
5734
|
children: /* @__PURE__ */ jsx(Paperclip, { className: "size-4" })
|
|
5687
5735
|
})] }) : null;
|
|
5688
|
-
const gutter =
|
|
5736
|
+
const gutter = shellMode ? /* @__PURE__ */ jsx(GlyphButton, {
|
|
5737
|
+
gutter: true,
|
|
5738
|
+
label: "Leave shell mode",
|
|
5739
|
+
tone: "magenta",
|
|
5740
|
+
onClick: leaveShellMode,
|
|
5741
|
+
children: "!"
|
|
5742
|
+
}) : busy ? /* @__PURE__ */ jsx(GlyphButton, {
|
|
5689
5743
|
gutter: true,
|
|
5690
5744
|
label: "Interrupt",
|
|
5691
5745
|
tone: "yellow",
|
|
@@ -5768,7 +5822,7 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
5768
5822
|
affordances,
|
|
5769
5823
|
bleed: "1ch",
|
|
5770
5824
|
"data-dragging": dragging || void 0,
|
|
5771
|
-
className: cn("term-composer", disabled && "opacity-60"),
|
|
5825
|
+
className: cn("term-composer", shellMode && "term-composer-shell", disabled && "opacity-60"),
|
|
5772
5826
|
children: /* @__PURE__ */ jsxs("div", {
|
|
5773
5827
|
className: "term-composer-body",
|
|
5774
5828
|
children: [
|
|
@@ -5776,7 +5830,7 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
5776
5830
|
/* @__PURE__ */ jsxs("div", {
|
|
5777
5831
|
className: "term-row",
|
|
5778
5832
|
children: [
|
|
5779
|
-
canAttach ? fileField : null,
|
|
5833
|
+
canAttach && !shellMode ? fileField : null,
|
|
5780
5834
|
gutter,
|
|
5781
5835
|
/* @__PURE__ */ jsxs("div", {
|
|
5782
5836
|
className: "flex min-w-0 items-start",
|
|
@@ -5787,17 +5841,27 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
5787
5841
|
normalizeBullets: false,
|
|
5788
5842
|
onSubmit: submit,
|
|
5789
5843
|
disabled,
|
|
5790
|
-
placeholder: disabled ? "Session ended" : placeholder,
|
|
5844
|
+
placeholder: disabled ? "Session ended" : shellMode ? SHELL_PLACEHOLDER : placeholder,
|
|
5791
5845
|
minHeight: line,
|
|
5792
5846
|
maxHeight: line * 10,
|
|
5793
|
-
"aria-label": "Message the agent",
|
|
5847
|
+
"aria-label": shellMode ? "Run a shell command" : "Message the agent",
|
|
5794
5848
|
className: "term-composer-field min-w-0 flex-1",
|
|
5795
|
-
onImagePaste: (file) => attachments?.add([file])
|
|
5849
|
+
onImagePaste: (file) => attachments?.add([file]),
|
|
5850
|
+
...shellKeys
|
|
5796
5851
|
}), submitButton]
|
|
5797
5852
|
})
|
|
5798
5853
|
]
|
|
5799
5854
|
}),
|
|
5800
|
-
|
|
5855
|
+
shellMode ? /* @__PURE__ */ jsxs("div", {
|
|
5856
|
+
className: "term-row",
|
|
5857
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
5858
|
+
"aria-hidden": true,
|
|
5859
|
+
className: "term-gutter"
|
|
5860
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
5861
|
+
className: "term-composer-shell-hint",
|
|
5862
|
+
children: SHELL_HINT
|
|
5863
|
+
})]
|
|
5864
|
+
}) : toolbar ? /* @__PURE__ */ jsxs("div", {
|
|
5801
5865
|
className: "term-row",
|
|
5802
5866
|
children: [/* @__PURE__ */ jsx("span", {
|
|
5803
5867
|
"aria-hidden": true,
|
|
@@ -5817,11 +5881,11 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
5817
5881
|
className: cn("px-[var(--wd-composer-padding)] pb-[var(--wd-composer-padding)]", className),
|
|
5818
5882
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
5819
5883
|
...dropHandlers,
|
|
5820
|
-
className: cn("mx-auto w-full max-w-[var(--wd-transcript-max-width)] overflow-hidden border border-border bg-bg", "transition-colors rounded-lg shadow-(--shadow-xs)", "focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/30", dragging && "border-ring ring-2 ring-ring/30", disabled && "opacity-60"),
|
|
5884
|
+
className: cn("mx-auto w-full max-w-[var(--wd-transcript-max-width)] overflow-hidden border border-border bg-bg", "transition-colors rounded-lg shadow-(--shadow-xs)", "focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/30", dragging && "border-ring ring-2 ring-ring/30", shellMode && "border-[var(--wd-shell-accent)] focus-within:border-[var(--wd-shell-accent)] focus-within:ring-[var(--wd-shell-accent)]/30", disabled && "opacity-60"),
|
|
5821
5885
|
children: [staged.length > 0 && attachments ? /* @__PURE__ */ jsx(AttachmentStrip, { attachments }) : null, inline ? /* @__PURE__ */ jsxs("div", {
|
|
5822
5886
|
className: "flex items-end gap-1 p-1",
|
|
5823
5887
|
children: [
|
|
5824
|
-
attach,
|
|
5888
|
+
shellMode ? /* @__PURE__ */ jsx(ShellBadge, { onLeave: leaveShellMode }) : attach,
|
|
5825
5889
|
/* @__PURE__ */ jsx(PromptArea, {
|
|
5826
5890
|
...bind,
|
|
5827
5891
|
triggers,
|
|
@@ -5829,12 +5893,13 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
5829
5893
|
normalizeBullets: false,
|
|
5830
5894
|
onSubmit: submit,
|
|
5831
5895
|
disabled,
|
|
5832
|
-
placeholder: disabled ? "Session ended" : placeholder,
|
|
5896
|
+
placeholder: disabled ? "Session ended" : shellMode ? SHELL_PLACEHOLDER : placeholder,
|
|
5833
5897
|
minHeight: 20,
|
|
5834
5898
|
maxHeight: 192,
|
|
5835
|
-
"aria-label": "Message the agent",
|
|
5899
|
+
"aria-label": shellMode ? "Run a shell command" : "Message the agent",
|
|
5836
5900
|
className: "min-w-0 flex-1 py-1 text-body-sm text-text",
|
|
5837
|
-
onImagePaste: (file) => attachments?.add([file])
|
|
5901
|
+
onImagePaste: (file) => attachments?.add([file]),
|
|
5902
|
+
...shellKeys
|
|
5838
5903
|
}),
|
|
5839
5904
|
submitButton
|
|
5840
5905
|
]
|
|
@@ -5845,17 +5910,21 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
5845
5910
|
normalizeBullets: false,
|
|
5846
5911
|
onSubmit: submit,
|
|
5847
5912
|
disabled,
|
|
5848
|
-
placeholder: disabled ? "Session ended" : placeholder,
|
|
5913
|
+
placeholder: disabled ? "Session ended" : shellMode ? SHELL_PLACEHOLDER : placeholder,
|
|
5849
5914
|
minHeight: 28,
|
|
5850
5915
|
maxHeight: 192,
|
|
5851
|
-
"aria-label": "Message the agent",
|
|
5916
|
+
"aria-label": shellMode ? "Run a shell command" : "Message the agent",
|
|
5852
5917
|
className: "px-3 pt-2.5 pb-0 text-body-sm text-text",
|
|
5853
|
-
onImagePaste: (file) => attachments?.add([file])
|
|
5918
|
+
onImagePaste: (file) => attachments?.add([file]),
|
|
5919
|
+
...shellKeys
|
|
5854
5920
|
}), /* @__PURE__ */ jsxs("div", {
|
|
5855
5921
|
className: "flex items-center justify-between gap-2 px-2 pb-2",
|
|
5856
5922
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
5857
5923
|
className: "flex min-w-0 items-center gap-1",
|
|
5858
|
-
children: [attach,
|
|
5924
|
+
children: [shellMode ? /* @__PURE__ */ jsx(ShellBadge, { onLeave: leaveShellMode }) : attach, shellMode ? /* @__PURE__ */ jsx("span", {
|
|
5925
|
+
className: "text-label text-text-muted",
|
|
5926
|
+
children: SHELL_HINT
|
|
5927
|
+
}) : toolbar]
|
|
5859
5928
|
}), submitButton]
|
|
5860
5929
|
})] })]
|
|
5861
5930
|
}), errorRow]
|
|
@@ -5933,6 +6002,16 @@ function extensionOf(name) {
|
|
|
5933
6002
|
const dot = name.lastIndexOf(".");
|
|
5934
6003
|
return dot > 0 ? name.slice(dot + 1).toUpperCase() : "FILE";
|
|
5935
6004
|
}
|
|
6005
|
+
function ShellBadge({ onLeave }) {
|
|
6006
|
+
return /* @__PURE__ */ jsx("button", {
|
|
6007
|
+
type: "button",
|
|
6008
|
+
"aria-label": "Leave shell mode",
|
|
6009
|
+
title: "Leave shell mode",
|
|
6010
|
+
onClick: onLeave,
|
|
6011
|
+
className: "shrink-0 rounded px-1.5 py-0.5 font-mono text-label font-semibold text-[var(--wd-shell-accent)]",
|
|
6012
|
+
children: "!"
|
|
6013
|
+
});
|
|
6014
|
+
}
|
|
5936
6015
|
//#endregion
|
|
5937
6016
|
//#region src/lib/css.ts
|
|
5938
6017
|
function cssColor(color) {
|
|
@@ -11069,7 +11148,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
|
|
|
11069
11148
|
const [panel, setPanel] = useState();
|
|
11070
11149
|
const [showCompletedTasks, setShowCompletedTasks] = useState(false);
|
|
11071
11150
|
const [taskReveal, setTaskReveal] = useState();
|
|
11072
|
-
const { state, connection, replaying, protocolMismatch, models, effectiveModel, handle, send, approve, deny, interrupt, setModel, setPermissionMode, reconnectNow, loadFullResult } = useClaudeSession(client, sessionId, {
|
|
11151
|
+
const { state, connection, replaying, protocolMismatch, shell, models, effectiveModel, handle, send, runShell, approve, deny, interrupt, setModel, setPermissionMode, reconnectNow, loadFullResult } = useClaudeSession(client, sessionId, {
|
|
11073
11152
|
onProtocolError: setProtocolError,
|
|
11074
11153
|
cacheTranscript
|
|
11075
11154
|
});
|
|
@@ -11479,6 +11558,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
|
|
|
11479
11558
|
attachments,
|
|
11480
11559
|
draft,
|
|
11481
11560
|
onSearchFiles: hostFiles.available ? searchComposerFiles : void 0,
|
|
11561
|
+
onShellCommand: shell ? runShell : void 0,
|
|
11482
11562
|
layout: controlsExternal ? "inline" : "stacked",
|
|
11483
11563
|
toolbar: controlsExternal ? void 0 : sessionControls,
|
|
11484
11564
|
fontSize: effectiveTermFontSize,
|
|
@@ -11612,6 +11692,6 @@ function Notice({ level, onDismiss, children }) {
|
|
|
11612
11692
|
});
|
|
11613
11693
|
}
|
|
11614
11694
|
//#endregion
|
|
11615
|
-
export { Ink as $, PERMISSION_MODES as A,
|
|
11695
|
+
export { Ink as $, PERMISSION_MODES as A, DialogContent as At, TaskList as B, SelectContent as Bt, TerminalPermissionPrompt as C, copyText as Ct, SubagentStrip as D, Dialog$1 as Dt, parseUserQuestions as E, TooltipProvider as Et, SkillsDialog as F, MenuContent as Ft, TerminalSurface as G, PortalScope as Gt, contextNote as H, SelectItemText as Ht, McpDialog as I, MenuItem as It, TerminalMarkdown as J, badgeVariants as Jt, ToolTitleProvider as K, Input as Kt, HostFilesDialog as L, MenuSeparator as Lt, permissionModeChoices as M, DialogRow as Mt, permissionModeMeta as N, DialogTrigger as Nt, PermissionPrompt as O, DialogBody as Ot, ModelSelect as P, Menu$1 as Pt, Blank as Q, EntryIcon as R, MenuTrigger as Rt, TerminalQuestionPrompt as S, CopyButton as St, QuestionPrompt as T, TooltipContent as Tt, Composer as U, SelectTrigger as Ut, ContextDialog as V, SelectItem as Vt, skillPrompt as W, SelectValue as Wt, previewPatch as X, buttonVariants as Xt, TerminalDiff as Y, Button as Yt, Band as Z, cn as Zt, ConversationContent as _, segmentsToPlainText as _t, Transcript as a, toolIcon as at, STATUS_META as b, CodeBlock as bt, PromptTokenText as c, useTranscriptDensity as ct, FileCard as d, hashtagTrigger as dt, Row as et, TerminalItemView as f, launchTrigger as ft, Conversation as g, plainTextToSegments as gt, Loader as h, PromptArea as ht, useMinuteClock as i, isMutatingTool as it, PermissionModeSelect as j, DialogHeader as jt, Response as k, DialogClose as kt, Message as l, useTranscriptVariant as lt, SessionEmptyState as m, usePromptAreaState as mt, UsageDialog as n, WithActions as nt, ToolCallCard as o, TranscriptDensityProvider as ot, TerminalTranscript as p, mentionTrigger as pt, useToolTitle as q, Badge as qt, UsageMeters as r, useAffordances as rt, Reasoning as s, TranscriptVariantProvider as st, SessionPanel as t, CopyAction as tt, MessageContent as u, commandTrigger as ut, ConversationScrollButton as v, ProgressRing as vt, QUESTION_BEHAVIORS as w, Tip as wt, SessionInfoDialog as x, Spinner as xt, StatusBar as y, Splitter as yt, TasksDialog as z, Select$1 as zt };
|
|
11616
11696
|
|
|
11617
|
-
//# sourceMappingURL=SessionPanel-
|
|
11697
|
+
//# sourceMappingURL=SessionPanel-ErvQUyHe.mjs.map
|