@tangle-network/sandbox-ui 0.62.0 → 0.63.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/dist/chat.d.ts +14 -1
- package/dist/chat.js +1 -1
- package/dist/{chunk-R72QYE2U.js → chunk-2E3FJM56.js} +160 -44
- package/dist/{chunk-J36F6LD2.js → chunk-6OJUOEF4.js} +1 -1
- package/dist/{chunk-OQZQFSWM.js → chunk-DZA4UBXU.js} +11 -9
- package/dist/dashboard.d.ts +8 -1
- package/dist/dashboard.js +1 -1
- package/dist/index.js +3 -3
- package/dist/workbench.js +2 -2
- package/package.json +1 -1
package/dist/chat.d.ts
CHANGED
|
@@ -124,8 +124,21 @@ interface AgentSessionHarnessControl {
|
|
|
124
124
|
* switch harness.
|
|
125
125
|
*/
|
|
126
126
|
locked?: boolean;
|
|
127
|
-
/** Tooltip shown on the locked trigger. */
|
|
127
|
+
/** Tooltip shown on the locked trigger when no `onNewChat` is provided. */
|
|
128
128
|
lockReason?: string;
|
|
129
|
+
/**
|
|
130
|
+
* Fork action for a locked harness. When provided, the locked trigger turns
|
|
131
|
+
* into an informative chip: hover or tap opens a small popover explaining the
|
|
132
|
+
* lock and offering a button that calls this to start a fresh session. When
|
|
133
|
+
* omitted, the locked trigger stays a plain inert button with `lockReason`.
|
|
134
|
+
*/
|
|
135
|
+
onNewChat?: () => void;
|
|
136
|
+
/** Popover heading. Defaults to `Agent fixed to {harness} for this conversation.` */
|
|
137
|
+
lockTitle?: React.ReactNode;
|
|
138
|
+
/** Popover sub-line. Defaults to "Conversations stay on one agent." */
|
|
139
|
+
lockBody?: React.ReactNode;
|
|
140
|
+
/** Fork button label. Defaults to "New chat to switch agent". */
|
|
141
|
+
newChatLabel?: string;
|
|
129
142
|
}
|
|
130
143
|
interface AgentSessionModelControl {
|
|
131
144
|
/** Canonical model id (provider-prefixed, e.g. "anthropic/claude-opus-4-8"). */
|
package/dist/chat.js
CHANGED
|
@@ -156,7 +156,24 @@ import {
|
|
|
156
156
|
reasoningEffortsFor
|
|
157
157
|
} from "@tangle-network/agent-interface";
|
|
158
158
|
import * as DropdownMenu2 from "@radix-ui/react-dropdown-menu";
|
|
159
|
-
import { ChevronDown as ChevronDown3, Lock, SlidersHorizontal } from "lucide-react";
|
|
159
|
+
import { ChevronDown as ChevronDown3, Lock, Plus as Plus2, SlidersHorizontal } from "lucide-react";
|
|
160
|
+
import * as React3 from "react";
|
|
161
|
+
|
|
162
|
+
// src/lib/use-click-outside.ts
|
|
163
|
+
import * as React from "react";
|
|
164
|
+
function useClickOutside(onOutside) {
|
|
165
|
+
const ref = React.useRef(null);
|
|
166
|
+
React.useEffect(() => {
|
|
167
|
+
function handler(event) {
|
|
168
|
+
if (ref.current && !ref.current.contains(event.target)) {
|
|
169
|
+
onOutside();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
document.addEventListener("mousedown", handler);
|
|
173
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
174
|
+
}, [onOutside]);
|
|
175
|
+
return ref;
|
|
176
|
+
}
|
|
160
177
|
|
|
161
178
|
// src/chat/harness-model-compat.ts
|
|
162
179
|
import {
|
|
@@ -173,21 +190,8 @@ function snapModelToHarness(harness, modelId, models) {
|
|
|
173
190
|
|
|
174
191
|
// src/chat/agent-profile-picker.tsx
|
|
175
192
|
import { Bot, Check, ChevronDown as ChevronDown2, Pencil, Plus, Trash2 } from "lucide-react";
|
|
176
|
-
import * as
|
|
193
|
+
import * as React2 from "react";
|
|
177
194
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
178
|
-
function useClickOutside(onOutside) {
|
|
179
|
-
const ref = React.useRef(null);
|
|
180
|
-
React.useEffect(() => {
|
|
181
|
-
function handler(event) {
|
|
182
|
-
if (ref.current && !ref.current.contains(event.target)) {
|
|
183
|
-
onOutside();
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
document.addEventListener("mousedown", handler);
|
|
187
|
-
return () => document.removeEventListener("mousedown", handler);
|
|
188
|
-
}, [onOutside]);
|
|
189
|
-
return ref;
|
|
190
|
-
}
|
|
191
195
|
function profileSubtitle(profile) {
|
|
192
196
|
if (profile.description) return profile.description;
|
|
193
197
|
const count = profile.capabilities?.length ?? 0;
|
|
@@ -205,8 +209,8 @@ function AgentProfilePicker({
|
|
|
205
209
|
className,
|
|
206
210
|
side = "top"
|
|
207
211
|
}) {
|
|
208
|
-
const [open, setOpen] =
|
|
209
|
-
const [composing, setComposing] =
|
|
212
|
+
const [open, setOpen] = React2.useState(false);
|
|
213
|
+
const [composing, setComposing] = React2.useState(
|
|
210
214
|
null
|
|
211
215
|
);
|
|
212
216
|
const ref = useClickOutside(() => {
|
|
@@ -373,11 +377,11 @@ function ProfileForm({
|
|
|
373
377
|
onCancel,
|
|
374
378
|
onSave
|
|
375
379
|
}) {
|
|
376
|
-
const [name, setName] =
|
|
377
|
-
const [caps, setCaps] =
|
|
380
|
+
const [name, setName] = React2.useState(initial?.name ?? "");
|
|
381
|
+
const [caps, setCaps] = React2.useState(
|
|
378
382
|
initial?.capabilities ? [...initial.capabilities] : capabilities.map((c) => c.id)
|
|
379
383
|
);
|
|
380
|
-
const [instructions, setInstructions] =
|
|
384
|
+
const [instructions, setInstructions] = React2.useState(initial?.instructions ?? "");
|
|
381
385
|
const toggle = (id) => setCaps(
|
|
382
386
|
(prev) => prev.includes(id) ? prev.filter((c) => c !== id) : [...prev, id]
|
|
383
387
|
);
|
|
@@ -466,6 +470,102 @@ function selectorIgnoreNote(harness) {
|
|
|
466
470
|
if (ignoresEffort) return "Ignores reasoning effort";
|
|
467
471
|
return null;
|
|
468
472
|
}
|
|
473
|
+
function InformativeLock({
|
|
474
|
+
label,
|
|
475
|
+
lockTitle,
|
|
476
|
+
lockBody,
|
|
477
|
+
newChatLabel,
|
|
478
|
+
onNewChat
|
|
479
|
+
}) {
|
|
480
|
+
const [open, setOpen] = React3.useState(false);
|
|
481
|
+
const closeTimer = React3.useRef(null);
|
|
482
|
+
const ref = useClickOutside(() => setOpen(false));
|
|
483
|
+
const cancelClose = React3.useCallback(() => {
|
|
484
|
+
if (closeTimer.current) {
|
|
485
|
+
clearTimeout(closeTimer.current);
|
|
486
|
+
closeTimer.current = null;
|
|
487
|
+
}
|
|
488
|
+
}, []);
|
|
489
|
+
const scheduleClose = React3.useCallback(() => {
|
|
490
|
+
cancelClose();
|
|
491
|
+
closeTimer.current = setTimeout(() => setOpen(false), 150);
|
|
492
|
+
}, [cancelClose]);
|
|
493
|
+
React3.useEffect(() => cancelClose, [cancelClose]);
|
|
494
|
+
return /* @__PURE__ */ jsxs3(
|
|
495
|
+
"div",
|
|
496
|
+
{
|
|
497
|
+
ref,
|
|
498
|
+
className: "relative inline-flex",
|
|
499
|
+
onMouseEnter: () => {
|
|
500
|
+
cancelClose();
|
|
501
|
+
setOpen(true);
|
|
502
|
+
},
|
|
503
|
+
onMouseLeave: scheduleClose,
|
|
504
|
+
onKeyDown: (event) => {
|
|
505
|
+
if (event.key === "Escape") setOpen(false);
|
|
506
|
+
},
|
|
507
|
+
children: [
|
|
508
|
+
/* @__PURE__ */ jsxs3(
|
|
509
|
+
"button",
|
|
510
|
+
{
|
|
511
|
+
type: "button",
|
|
512
|
+
onClick: () => setOpen(true),
|
|
513
|
+
"data-state": open ? "open" : "closed",
|
|
514
|
+
"aria-label": "Agent harness (locked)",
|
|
515
|
+
"aria-haspopup": "dialog",
|
|
516
|
+
"aria-expanded": open,
|
|
517
|
+
className: cn(
|
|
518
|
+
"inline-flex h-8 items-center gap-1.5 rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container px-2.5",
|
|
519
|
+
"text-xs font-medium text-foreground shadow-sm transition-colors",
|
|
520
|
+
"hover:border-[var(--md3-outline-variant)] hover:bg-surface-container-high focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
521
|
+
"data-[state=open]:border-[var(--md3-outline-variant)] data-[state=open]:bg-surface-container-high"
|
|
522
|
+
),
|
|
523
|
+
children: [
|
|
524
|
+
/* @__PURE__ */ jsx3(Lock, { className: "h-3 w-3 text-muted-foreground" }),
|
|
525
|
+
/* @__PURE__ */ jsx3("span", { children: label })
|
|
526
|
+
]
|
|
527
|
+
}
|
|
528
|
+
),
|
|
529
|
+
open && /* @__PURE__ */ jsxs3(
|
|
530
|
+
"div",
|
|
531
|
+
{
|
|
532
|
+
role: "dialog",
|
|
533
|
+
className: cn(
|
|
534
|
+
"absolute bottom-full left-0 z-50 mb-2 w-72 rounded-[var(--radius-md)] border border-[var(--md3-outline-variant)] bg-surface-container-highest p-3",
|
|
535
|
+
"shadow-[0_8px_30px_rgba(0,0,0,0.45)] ring-1 ring-[#ffffff14]"
|
|
536
|
+
),
|
|
537
|
+
children: [
|
|
538
|
+
/* @__PURE__ */ jsxs3("p", { className: "flex items-start gap-2 text-sm font-medium text-foreground", children: [
|
|
539
|
+
/* @__PURE__ */ jsx3(Lock, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
540
|
+
/* @__PURE__ */ jsx3("span", { children: lockTitle ?? `Agent fixed to ${label} for this conversation.` })
|
|
541
|
+
] }),
|
|
542
|
+
/* @__PURE__ */ jsx3("p", { className: "mt-1.5 text-xs text-muted-foreground", children: lockBody ?? "Conversations stay on one agent." }),
|
|
543
|
+
/* @__PURE__ */ jsxs3(
|
|
544
|
+
"button",
|
|
545
|
+
{
|
|
546
|
+
type: "button",
|
|
547
|
+
onClick: () => {
|
|
548
|
+
setOpen(false);
|
|
549
|
+
onNewChat();
|
|
550
|
+
},
|
|
551
|
+
className: cn(
|
|
552
|
+
"mt-3 flex w-full items-center justify-center gap-1.5 rounded-md px-2.5 py-2 text-sm font-medium text-foreground",
|
|
553
|
+
"bg-primary/10 ring-1 ring-inset ring-primary/25 transition-colors",
|
|
554
|
+
"hover:bg-primary/15 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
555
|
+
),
|
|
556
|
+
children: [
|
|
557
|
+
/* @__PURE__ */ jsx3(Plus2, { className: "h-4 w-4" }),
|
|
558
|
+
newChatLabel ?? "New chat to switch agent"
|
|
559
|
+
]
|
|
560
|
+
}
|
|
561
|
+
)
|
|
562
|
+
]
|
|
563
|
+
}
|
|
564
|
+
)
|
|
565
|
+
]
|
|
566
|
+
}
|
|
567
|
+
);
|
|
568
|
+
}
|
|
469
569
|
function HarnessDropdown({
|
|
470
570
|
value,
|
|
471
571
|
onChange,
|
|
@@ -473,6 +573,10 @@ function HarnessDropdown({
|
|
|
473
573
|
disabled,
|
|
474
574
|
locked,
|
|
475
575
|
lockReason,
|
|
576
|
+
onNewChat,
|
|
577
|
+
lockTitle,
|
|
578
|
+
lockBody,
|
|
579
|
+
newChatLabel,
|
|
476
580
|
side = "bottom",
|
|
477
581
|
align = "start",
|
|
478
582
|
avoidCollisions
|
|
@@ -482,6 +586,18 @@ function HarnessDropdown({
|
|
|
482
586
|
);
|
|
483
587
|
const options = HARNESS_OPTIONS.filter((h) => allowed.has(h.type));
|
|
484
588
|
const selected = options.find((option) => option.type === value);
|
|
589
|
+
if (locked && onNewChat) {
|
|
590
|
+
return /* @__PURE__ */ jsx3(
|
|
591
|
+
InformativeLock,
|
|
592
|
+
{
|
|
593
|
+
label: selected?.label ?? value,
|
|
594
|
+
lockTitle,
|
|
595
|
+
lockBody,
|
|
596
|
+
newChatLabel,
|
|
597
|
+
onNewChat
|
|
598
|
+
}
|
|
599
|
+
);
|
|
600
|
+
}
|
|
485
601
|
return /* @__PURE__ */ jsxs3(DropdownMenu2.Root, { children: [
|
|
486
602
|
/* @__PURE__ */ jsx3(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs3(
|
|
487
603
|
"button",
|
|
@@ -785,7 +901,7 @@ import {
|
|
|
785
901
|
Upload,
|
|
786
902
|
X
|
|
787
903
|
} from "lucide-react";
|
|
788
|
-
import * as
|
|
904
|
+
import * as React4 from "react";
|
|
789
905
|
import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
790
906
|
function AgentComposer({
|
|
791
907
|
value,
|
|
@@ -816,22 +932,22 @@ function AgentComposer({
|
|
|
816
932
|
sendLabel = "Send",
|
|
817
933
|
autoFocus
|
|
818
934
|
}) {
|
|
819
|
-
const textareaRef =
|
|
820
|
-
const fileInputRef =
|
|
821
|
-
const folderInputRef =
|
|
822
|
-
const [dragOver, setDragOver] =
|
|
823
|
-
const dragDepth =
|
|
824
|
-
const resize =
|
|
935
|
+
const textareaRef = React4.useRef(null);
|
|
936
|
+
const fileInputRef = React4.useRef(null);
|
|
937
|
+
const folderInputRef = React4.useRef(null);
|
|
938
|
+
const [dragOver, setDragOver] = React4.useState(false);
|
|
939
|
+
const dragDepth = React4.useRef(0);
|
|
940
|
+
const resize = React4.useCallback(
|
|
825
941
|
(el) => {
|
|
826
942
|
el.style.height = "auto";
|
|
827
943
|
el.style.height = `${Math.min(el.scrollHeight, maxHeight)}px`;
|
|
828
944
|
},
|
|
829
945
|
[maxHeight]
|
|
830
946
|
);
|
|
831
|
-
|
|
947
|
+
React4.useEffect(() => {
|
|
832
948
|
if (textareaRef.current) resize(textareaRef.current);
|
|
833
949
|
}, [value, resize]);
|
|
834
|
-
|
|
950
|
+
React4.useEffect(() => {
|
|
835
951
|
if (!focusShortcut || disabled) return;
|
|
836
952
|
function onKeyDown(event) {
|
|
837
953
|
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "l") {
|
|
@@ -1070,7 +1186,7 @@ function AgentComposer({
|
|
|
1070
1186
|
}
|
|
1071
1187
|
|
|
1072
1188
|
// src/chat/artifact-agent-dock.tsx
|
|
1073
|
-
import * as
|
|
1189
|
+
import * as React5 from "react";
|
|
1074
1190
|
import { Sparkles as Sparkles2, Send, Square as Square2, X as X2 } from "lucide-react";
|
|
1075
1191
|
import { ChatMessage } from "@tangle-network/ui/chat";
|
|
1076
1192
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
@@ -1119,23 +1235,23 @@ function ArtifactAgentDock({
|
|
|
1119
1235
|
onError,
|
|
1120
1236
|
className
|
|
1121
1237
|
}) {
|
|
1122
|
-
const [threadId, setThreadId] =
|
|
1123
|
-
const [messages, setMessages] =
|
|
1124
|
-
const [composer, setComposer] =
|
|
1125
|
-
const [streamContent, setStreamContent] =
|
|
1126
|
-
const [sending, setSending] =
|
|
1127
|
-
const [loading, setLoading] =
|
|
1128
|
-
const abortRef =
|
|
1129
|
-
const scrollRef =
|
|
1130
|
-
const scopeTokenRef =
|
|
1131
|
-
const reportError =
|
|
1238
|
+
const [threadId, setThreadId] = React5.useState(null);
|
|
1239
|
+
const [messages, setMessages] = React5.useState([]);
|
|
1240
|
+
const [composer, setComposer] = React5.useState(defaultPrompt ?? "");
|
|
1241
|
+
const [streamContent, setStreamContent] = React5.useState("");
|
|
1242
|
+
const [sending, setSending] = React5.useState(false);
|
|
1243
|
+
const [loading, setLoading] = React5.useState(false);
|
|
1244
|
+
const abortRef = React5.useRef(null);
|
|
1245
|
+
const scrollRef = React5.useRef(null);
|
|
1246
|
+
const scopeTokenRef = React5.useRef(0);
|
|
1247
|
+
const reportError = React5.useCallback(
|
|
1132
1248
|
(message) => {
|
|
1133
1249
|
if (onError) onError(message);
|
|
1134
1250
|
else if (typeof console !== "undefined") console.error("[ArtifactAgentDock]", message);
|
|
1135
1251
|
},
|
|
1136
1252
|
[onError]
|
|
1137
1253
|
);
|
|
1138
|
-
|
|
1254
|
+
React5.useEffect(() => {
|
|
1139
1255
|
if (!open) return;
|
|
1140
1256
|
scopeTokenRef.current += 1;
|
|
1141
1257
|
abortRef.current?.abort();
|
|
@@ -1171,11 +1287,11 @@ function ArtifactAgentDock({
|
|
|
1171
1287
|
cancelled = true;
|
|
1172
1288
|
};
|
|
1173
1289
|
}, [open, scope.kind, scope.key, transport, reportError]);
|
|
1174
|
-
|
|
1290
|
+
React5.useEffect(() => {
|
|
1175
1291
|
if (!scrollRef.current) return;
|
|
1176
1292
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
1177
1293
|
}, [messages.length, streamContent]);
|
|
1178
|
-
const send =
|
|
1294
|
+
const send = React5.useCallback(async () => {
|
|
1179
1295
|
const text = composer.trim();
|
|
1180
1296
|
if (!text || !threadId || sending) return;
|
|
1181
1297
|
const token = scopeTokenRef.current;
|
|
@@ -1225,7 +1341,7 @@ function ArtifactAgentDock({
|
|
|
1225
1341
|
if (abortRef.current === controller) abortRef.current = null;
|
|
1226
1342
|
}
|
|
1227
1343
|
}, [composer, threadId, sending, transport, reportError]);
|
|
1228
|
-
const cancel =
|
|
1344
|
+
const cancel = React5.useCallback(() => {
|
|
1229
1345
|
if (threadId && transport.cancel) {
|
|
1230
1346
|
try {
|
|
1231
1347
|
void Promise.resolve(transport.cancel({ threadId })).catch(() => {
|
|
@@ -564,13 +564,17 @@ function RailExpandable({
|
|
|
564
564
|
loadSubItems,
|
|
565
565
|
activeSubIds,
|
|
566
566
|
emptyLabel = "Nothing here yet",
|
|
567
|
+
defaultOpen,
|
|
567
568
|
onNavigate,
|
|
568
569
|
LinkComponent,
|
|
569
570
|
className
|
|
570
571
|
}) {
|
|
571
572
|
const Link = LinkComponent ?? DefaultLink;
|
|
572
|
-
const [open, setOpen] = React3.useState(false);
|
|
573
|
+
const [open, setOpen] = React3.useState(defaultOpen ?? false);
|
|
573
574
|
const { items, loading, ensureLoaded } = useExpandableItems(subItems, loadSubItems);
|
|
575
|
+
React3.useEffect(() => {
|
|
576
|
+
if (defaultOpen) ensureLoaded();
|
|
577
|
+
}, [defaultOpen, ensureLoaded]);
|
|
574
578
|
const activeSet = React3.useMemo(() => new Set(activeSubIds ?? []), [activeSubIds]);
|
|
575
579
|
const triggerRef = React3.useRef(null);
|
|
576
580
|
const closeTimer = React3.useRef(null);
|
|
@@ -589,8 +593,8 @@ function RailExpandable({
|
|
|
589
593
|
onClick: onNavigate,
|
|
590
594
|
...item.prefetch !== void 0 ? { prefetch: item.prefetch } : {},
|
|
591
595
|
className: cn(
|
|
592
|
-
"flex h-
|
|
593
|
-
active ? "bg-[var(--accent-surface-strong)] font-medium text-[var(--accent-text)]" : "text-muted-foreground hover:bg-[var(--accent-surface-soft)] hover:text-foreground"
|
|
596
|
+
"flex h-7 min-w-0 items-center gap-2 rounded-md px-2.5 text-[12px] transition-colors",
|
|
597
|
+
active ? "bg-[var(--accent-surface-strong)] font-medium text-[var(--accent-text)]" : item.emphasis ? "font-semibold text-[var(--accent-text)] hover:bg-[var(--accent-surface-soft)]" : "text-muted-foreground hover:bg-[var(--accent-surface-soft)] hover:text-foreground"
|
|
594
598
|
),
|
|
595
599
|
children: [
|
|
596
600
|
FIcon ? /* @__PURE__ */ jsx3(FIcon, { className: "h-4 w-4 shrink-0" }) : null,
|
|
@@ -719,18 +723,15 @@ function RailExpandable({
|
|
|
719
723
|
/* @__PURE__ */ jsx3(
|
|
720
724
|
Icon,
|
|
721
725
|
{
|
|
722
|
-
className:
|
|
723
|
-
"h-[17px] w-[17px] shrink-0 transition-opacity duration-150",
|
|
724
|
-
open ? "opacity-0" : "opacity-100 group-hover/exp:opacity-0"
|
|
725
|
-
)
|
|
726
|
+
className: "h-[17px] w-[17px] shrink-0 opacity-100 transition-opacity duration-150 group-hover/exp:opacity-0"
|
|
726
727
|
}
|
|
727
728
|
),
|
|
728
729
|
/* @__PURE__ */ jsx3(
|
|
729
730
|
ChevronRightIcon,
|
|
730
731
|
{
|
|
731
732
|
className: cn(
|
|
732
|
-
"absolute h-4 w-4 transition-all duration-150",
|
|
733
|
-
open
|
|
733
|
+
"absolute h-4 w-4 opacity-0 transition-all duration-150 group-hover/exp:opacity-100",
|
|
734
|
+
open && "rotate-90"
|
|
734
735
|
)
|
|
735
736
|
}
|
|
736
737
|
)
|
|
@@ -2368,6 +2369,7 @@ function SidebarLayoutInner({
|
|
|
2368
2369
|
loadSubItems: item.loadSubItems,
|
|
2369
2370
|
activeSubIds: item.subActiveIds,
|
|
2370
2371
|
emptyLabel: item.emptyLabel,
|
|
2372
|
+
defaultOpen: item.defaultOpen,
|
|
2371
2373
|
onNavigate: handleNavClick,
|
|
2372
2374
|
LinkComponent
|
|
2373
2375
|
},
|
package/dist/dashboard.d.ts
CHANGED
|
@@ -185,6 +185,9 @@ interface RailExpandableSubItem {
|
|
|
185
185
|
prefetch?: "none" | "intent" | "render" | "viewport";
|
|
186
186
|
/** Show a live working indicator on the row while the item is busy. */
|
|
187
187
|
isLoading?: boolean;
|
|
188
|
+
/** Render the row emphasized (bold + accent) so it stands out — e.g. a
|
|
189
|
+
* trailing "view all" action below a capped list. */
|
|
190
|
+
emphasis?: boolean;
|
|
188
191
|
}
|
|
189
192
|
interface RailExpandableProps {
|
|
190
193
|
icon: React.ComponentType<{
|
|
@@ -201,6 +204,8 @@ interface RailExpandableProps {
|
|
|
201
204
|
subItems?: RailExpandableSubItem[];
|
|
202
205
|
/** Lazy sub-items — called once on first open; the result is cached. */
|
|
203
206
|
loadSubItems?: () => Promise<RailExpandableSubItem[]>;
|
|
207
|
+
/** Start expanded on mount (labeled rail). Defaults to collapsed. */
|
|
208
|
+
defaultOpen?: boolean;
|
|
204
209
|
/** Ids of sub-items whose route is active (drives sub-item highlight). */
|
|
205
210
|
activeSubIds?: string[];
|
|
206
211
|
/** Shown when the resolved sub-item list is empty. */
|
|
@@ -218,7 +223,7 @@ interface RailExpandableProps {
|
|
|
218
223
|
* Sub-items can be fixed (`subItems`) or lazy (`loadSubItems`, with a loading
|
|
219
224
|
* skeleton). Used for e.g. a "History" entry fronting recent sessions.
|
|
220
225
|
*/
|
|
221
|
-
declare function RailExpandable({ icon: Icon, label, href, isActive, showLabel, subItems, loadSubItems, activeSubIds, emptyLabel, onNavigate, LinkComponent, className, }: RailExpandableProps): react_jsx_runtime.JSX.Element;
|
|
226
|
+
declare function RailExpandable({ icon: Icon, label, href, isActive, showLabel, subItems, loadSubItems, activeSubIds, emptyLabel, defaultOpen, onNavigate, LinkComponent, className, }: RailExpandableProps): react_jsx_runtime.JSX.Element;
|
|
222
227
|
interface RailModeButtonProps {
|
|
223
228
|
mode: string;
|
|
224
229
|
icon: React.ComponentType<{
|
|
@@ -913,6 +918,8 @@ interface SidebarLayoutNavItem {
|
|
|
913
918
|
subActiveIds?: string[];
|
|
914
919
|
/** Empty-state text for an `expandable` item that resolves to no sub-items. */
|
|
915
920
|
emptyLabel?: string;
|
|
921
|
+
/** Start an `expandable` item expanded on mount (labeled rail). */
|
|
922
|
+
defaultOpen?: boolean;
|
|
916
923
|
badge?: number;
|
|
917
924
|
/**
|
|
918
925
|
* React Router prefetch behavior for this link, forwarded to the underlying
|
package/dist/dashboard.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -102,7 +102,7 @@ import {
|
|
|
102
102
|
modelProvider,
|
|
103
103
|
snapHarnessToModel,
|
|
104
104
|
snapModelToHarness
|
|
105
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-2E3FJM56.js";
|
|
106
106
|
import {
|
|
107
107
|
ExpandedToolDetail,
|
|
108
108
|
InlineThinkingItem,
|
|
@@ -146,7 +146,7 @@ import {
|
|
|
146
146
|
buildUnifiedPatch,
|
|
147
147
|
computeDiffStats,
|
|
148
148
|
resolveLanguage
|
|
149
|
-
} from "./chunk-
|
|
149
|
+
} from "./chunk-6OJUOEF4.js";
|
|
150
150
|
import {
|
|
151
151
|
FileArtifactPane,
|
|
152
152
|
FilePreview,
|
|
@@ -211,7 +211,7 @@ import {
|
|
|
211
211
|
canAdminSandbox,
|
|
212
212
|
parseInsufficientBalance,
|
|
213
213
|
useSidebar
|
|
214
|
-
} from "./chunk-
|
|
214
|
+
} from "./chunk-DZA4UBXU.js";
|
|
215
215
|
import "./chunk-VIREDUBF.js";
|
|
216
216
|
import {
|
|
217
217
|
usePtySession
|
package/dist/workbench.js
CHANGED
|
@@ -12,9 +12,9 @@ import {
|
|
|
12
12
|
buildUnifiedPatch,
|
|
13
13
|
computeDiffStats,
|
|
14
14
|
resolveLanguage
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-6OJUOEF4.js";
|
|
16
16
|
import "./chunk-3J6FG3FJ.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-DZA4UBXU.js";
|
|
18
18
|
import "./chunk-VIREDUBF.js";
|
|
19
19
|
import "./chunk-77WVVJA4.js";
|
|
20
20
|
import "./chunk-OMUIPJQZ.js";
|
package/package.json
CHANGED