@workerdeck/ui 2.10.0 → 2.11.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 +4 -3
- package/build/index.mjs +12 -8
- package/build/index.mjs.map +1 -1
- package/build/scoped.css +56 -1
- package/build/{use-path-links-CvcxdUXL.mjs → use-path-links-DO_79-wX.mjs} +405 -176
- package/build/use-path-links-DO_79-wX.mjs.map +1 -0
- package/build/workspace.mjs +1 -1
- package/package.json +4 -4
- package/src/components/agent/SessionItem.tsx +4 -3
- package/src/components/agent/SessionPanel.tsx +2 -0
- package/src/components/agent/TranscriptItemView.tsx +2 -0
- package/src/components/agent/TranscriptRows.tsx +60 -56
- package/src/components/agent/UsageDialog.tsx +19 -6
- package/src/components/agent/pulse.tsx +53 -16
- package/src/components/agent/use-transcript-jumps.ts +25 -0
- package/src/components/terminal/TerminalTranscript.tsx +31 -27
- package/src/components/terminal/blocks.ts +15 -7
- package/src/components/terminal/height.ts +14 -5
- package/src/components/terminal/items.tsx +97 -11
- package/src/components/terminal/peer-names.tsx +16 -0
- package/src/components/terminal/row.tsx +1 -1
- package/src/components/terminal/tool-run.ts +68 -0
- package/src/lib/session-cost.ts +12 -2
- package/src/lib/tool-icon.ts +5 -1
- package/src/styles/terminal.css +93 -0
- package/src/styles/theme.css +1 -1
- package/build/use-path-links-CvcxdUXL.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { C as rateLimitWindowSeconds, _ as formatDuration, a as meterTintClass, b as formatRelativeTime, f as compactionText, g as formatCountdown, h as formatCost, m as formatBytes, p as formatAgoPrecise, r as meterColorClass, w as toolInputPreview, x as formatTokens, y as formatRateLimitWindowLong } from "./status-kmsBhuFG.mjs";
|
|
2
|
-
import { Fragment, createContext, forwardRef, memo, useCallback, useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { Fragment, createContext, forwardRef, memo, useCallback, useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
4
|
import { clsx } from "clsx";
|
|
5
5
|
import { extendTailwindMerge } from "tailwind-merge";
|
|
@@ -9,7 +9,7 @@ import { ArrowDown, ArrowDownCircle, ArrowLeft, ArrowRight, ArrowUp, AtSign, Bra
|
|
|
9
9
|
import { Menu } from "@base-ui/react/menu";
|
|
10
10
|
import { Dialog } from "@base-ui/react/dialog";
|
|
11
11
|
import { Tooltip } from "@base-ui/react/tooltip";
|
|
12
|
-
import { PRICING_NOTE, PROTOCOL_VERSION, UNPRICED_WARN_SHARE, canonicalModel, costOf, costOfByModel, mergeUsage, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, rateFor, sessionTasks, subagentLabel, taskCountLabel, taskSummary, toolTitle, totalTokens, usageInfos, usageIsStale, visibleTasks } from "@workerdeck/protocol";
|
|
12
|
+
import { PRICING_NOTE, PROTOCOL_VERSION, UNPRICED_WARN_SHARE, canonicalModel, costOf, costOfByModel, isPeerSendTool, mergeUsage, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredTo, pricingAgeNote, rateFor, sessionTasks, subagentLabel, taskCountLabel, taskSummary, toolTitle, totalTokens, unknownBasisModels, usageInfos, usageIsStale, visibleTasks } from "@workerdeck/protocol";
|
|
13
13
|
import { recapLine, scanPromptTokens, summarizeSince, useAttachments, useClaudeSession, useDraft, useHostFileSearch, useProfileUsage, useToolCallHost } from "@workerdeck/react";
|
|
14
14
|
import { Streamdown } from "streamdown";
|
|
15
15
|
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
|
@@ -4606,7 +4606,11 @@ function toolIcon(toolName) {
|
|
|
4606
4606
|
case "WebSearch": return Globe;
|
|
4607
4607
|
case "Task":
|
|
4608
4608
|
case "Agent": return UsersRound;
|
|
4609
|
-
case "TodoWrite":
|
|
4609
|
+
case "TodoWrite":
|
|
4610
|
+
case "TaskCreate":
|
|
4611
|
+
case "TaskUpdate":
|
|
4612
|
+
case "TaskGet":
|
|
4613
|
+
case "TaskList": return CheckSquare;
|
|
4610
4614
|
case "Skill": return Sparkles;
|
|
4611
4615
|
case "AskUserQuestion": return MessageCircleQuestion;
|
|
4612
4616
|
case "CodexCommand": return Terminal;
|
|
@@ -4634,12 +4638,53 @@ function isMutatingTool(toolName) {
|
|
|
4634
4638
|
//#endregion
|
|
4635
4639
|
//#region src/components/agent/pulse.tsx
|
|
4636
4640
|
const PULSE_FRAMES = [
|
|
4637
|
-
"
|
|
4638
|
-
"
|
|
4639
|
-
"
|
|
4640
|
-
"
|
|
4641
|
+
"⠋",
|
|
4642
|
+
"⠙",
|
|
4643
|
+
"⠹",
|
|
4644
|
+
"⠸",
|
|
4645
|
+
"⠼",
|
|
4646
|
+
"⠴",
|
|
4647
|
+
"⠦",
|
|
4648
|
+
"⠧",
|
|
4649
|
+
"⠇",
|
|
4650
|
+
"⠏"
|
|
4641
4651
|
];
|
|
4642
|
-
const
|
|
4652
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
4653
|
+
let ticker;
|
|
4654
|
+
let current = "⠿";
|
|
4655
|
+
function pulseFrameAt(now) {
|
|
4656
|
+
return PULSE_FRAMES[Math.floor(now / 90) % PULSE_FRAMES.length];
|
|
4657
|
+
}
|
|
4658
|
+
function tick() {
|
|
4659
|
+
const next = pulseFrameAt(Date.now());
|
|
4660
|
+
if (next === current) return;
|
|
4661
|
+
current = next;
|
|
4662
|
+
for (const listener of listeners) listener();
|
|
4663
|
+
}
|
|
4664
|
+
function subscribe(listener) {
|
|
4665
|
+
listeners.add(listener);
|
|
4666
|
+
if (ticker === void 0) {
|
|
4667
|
+
current = pulseFrameAt(Date.now());
|
|
4668
|
+
ticker = setInterval(tick, 90);
|
|
4669
|
+
}
|
|
4670
|
+
return () => {
|
|
4671
|
+
listeners.delete(listener);
|
|
4672
|
+
if (listeners.size === 0 && ticker !== void 0) {
|
|
4673
|
+
clearInterval(ticker);
|
|
4674
|
+
ticker = void 0;
|
|
4675
|
+
}
|
|
4676
|
+
};
|
|
4677
|
+
}
|
|
4678
|
+
function subscribeRest() {
|
|
4679
|
+
return unsubscribeRest;
|
|
4680
|
+
}
|
|
4681
|
+
function unsubscribeRest() {}
|
|
4682
|
+
function readFrame() {
|
|
4683
|
+
return current;
|
|
4684
|
+
}
|
|
4685
|
+
function readRest() {
|
|
4686
|
+
return "⠿";
|
|
4687
|
+
}
|
|
4643
4688
|
function usePrefersReducedMotion() {
|
|
4644
4689
|
const [reduced, setReduced] = useState(false);
|
|
4645
4690
|
useEffect(() => {
|
|
@@ -4655,14 +4700,7 @@ function usePrefersReducedMotion() {
|
|
|
4655
4700
|
function usePulse(animated) {
|
|
4656
4701
|
const reduced = usePrefersReducedMotion();
|
|
4657
4702
|
const running = animated && !reduced;
|
|
4658
|
-
|
|
4659
|
-
useEffect(() => {
|
|
4660
|
-
if (!running) return;
|
|
4661
|
-
const timer = setInterval(() => setFrame((f) => f + 1), 150);
|
|
4662
|
-
return () => clearInterval(timer);
|
|
4663
|
-
}, [running]);
|
|
4664
|
-
if (!running) return PULSE_REST;
|
|
4665
|
-
return PULSE_FRAMES[frame % PULSE_FRAMES.length];
|
|
4703
|
+
return useSyncExternalStore(running ? subscribe : subscribeRest, running ? readFrame : readRest, readRest);
|
|
4666
4704
|
}
|
|
4667
4705
|
//#endregion
|
|
4668
4706
|
//#region src/components/agent/PromptTokenText.tsx
|
|
@@ -5131,6 +5169,129 @@ const TerminalMarkdown = memo(function TerminalMarkdown({ children, streaming, c
|
|
|
5131
5169
|
});
|
|
5132
5170
|
}, (prev, next) => prev.children === next.children && prev.streaming === next.streaming && prev.className === next.className);
|
|
5133
5171
|
//#endregion
|
|
5172
|
+
//#region src/components/terminal/tool-run.ts
|
|
5173
|
+
function isPeerSend(item) {
|
|
5174
|
+
return item.kind === "tool_call" && isPeerSendTool(item.name);
|
|
5175
|
+
}
|
|
5176
|
+
function peerName(origin) {
|
|
5177
|
+
return origin.name ?? origin.sessionId.slice(0, 8);
|
|
5178
|
+
}
|
|
5179
|
+
function peerNamesOf(items) {
|
|
5180
|
+
const names = /* @__PURE__ */ new Map();
|
|
5181
|
+
for (const item of items) {
|
|
5182
|
+
if (item.kind === "user") {
|
|
5183
|
+
if (item.origin?.name) names.set(item.origin.sessionId, item.origin.name);
|
|
5184
|
+
continue;
|
|
5185
|
+
}
|
|
5186
|
+
if (item.kind === "tool_call" && isPeerSendTool(item.name) && item.result && !item.result.isError) {
|
|
5187
|
+
const delivered = peerDeliveredTo(item.result.text);
|
|
5188
|
+
if (delivered?.name) names.set(delivered.sessionId, delivered.name);
|
|
5189
|
+
}
|
|
5190
|
+
}
|
|
5191
|
+
return names;
|
|
5192
|
+
}
|
|
5193
|
+
function peerSendTarget(item, names) {
|
|
5194
|
+
const delivered = item.result && !item.result.isError ? peerDeliveredTo(item.result.text) : void 0;
|
|
5195
|
+
const addressed = item.input?.sessionId;
|
|
5196
|
+
const sessionId = delivered?.sessionId ?? (typeof addressed === "string" ? addressed : void 0);
|
|
5197
|
+
if (sessionId === void 0) return "peer";
|
|
5198
|
+
return delivered?.name ?? names?.get(sessionId) ?? sessionId.slice(0, 8);
|
|
5199
|
+
}
|
|
5200
|
+
function peerSendText(item) {
|
|
5201
|
+
const text = item.input?.text;
|
|
5202
|
+
return typeof text === "string" ? text : "";
|
|
5203
|
+
}
|
|
5204
|
+
function peerOneLine(text) {
|
|
5205
|
+
return text.replace(/\s+/g, " ").trim();
|
|
5206
|
+
}
|
|
5207
|
+
function foldsTogether(a, b) {
|
|
5208
|
+
if (isPeerSend(a) || isPeerSend(b)) return false;
|
|
5209
|
+
return a.parentToolUseId === b.parentToolUseId;
|
|
5210
|
+
}
|
|
5211
|
+
function toolFamily(name) {
|
|
5212
|
+
if (isShellTool(name)) return "shell";
|
|
5213
|
+
const mcp = /^mcp__([^_]+(?:_[^_]+)*?)__/.exec(name);
|
|
5214
|
+
if (mcp?.[1]) return mcp[1].replace(/_/g, "-");
|
|
5215
|
+
return name.toLowerCase();
|
|
5216
|
+
}
|
|
5217
|
+
function planRun(items) {
|
|
5218
|
+
return items.length === 1 ? {
|
|
5219
|
+
kind: "call",
|
|
5220
|
+
item: items[0]
|
|
5221
|
+
} : {
|
|
5222
|
+
kind: "summary",
|
|
5223
|
+
items
|
|
5224
|
+
};
|
|
5225
|
+
}
|
|
5226
|
+
function runSummary(items, busy) {
|
|
5227
|
+
const verb = busy ? "Running " : "Ran ";
|
|
5228
|
+
const tail = busy ? "…" : "";
|
|
5229
|
+
const n = items.length;
|
|
5230
|
+
const counts = /* @__PURE__ */ new Map();
|
|
5231
|
+
for (const item of items) {
|
|
5232
|
+
const family = toolFamily(item.name);
|
|
5233
|
+
counts.set(family, (counts.get(family) ?? 0) + 1);
|
|
5234
|
+
}
|
|
5235
|
+
if (counts.size === 1 && counts.has("shell")) return `${verb}${n} shell command${n === 1 ? "" : "s"}${tail}`;
|
|
5236
|
+
const breakdown = [...counts.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).map(([family, count]) => `${count} ${family}`).join(", ");
|
|
5237
|
+
return `${verb}${n} tool${n === 1 ? "" : "s"} · ${breakdown}${tail}`;
|
|
5238
|
+
}
|
|
5239
|
+
function clip(text, max = 80) {
|
|
5240
|
+
return text.length > max ? text.slice(0, max - 1) + "…" : text;
|
|
5241
|
+
}
|
|
5242
|
+
function trimmed(value) {
|
|
5243
|
+
return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
|
|
5244
|
+
}
|
|
5245
|
+
function taskLabel(task) {
|
|
5246
|
+
return `${task.name}(${taskIdentity(task)})`;
|
|
5247
|
+
}
|
|
5248
|
+
function taskIdentity(task) {
|
|
5249
|
+
const input = task.input;
|
|
5250
|
+
const description = trimmed(input?.description);
|
|
5251
|
+
const agent = trimmed(input?.subagent_type);
|
|
5252
|
+
return agent && description ? `${agent} · ${clip(description)}` : agent ?? (description ? clip(description) : toolInputPreview(task.input));
|
|
5253
|
+
}
|
|
5254
|
+
function taskBrief(task) {
|
|
5255
|
+
const input = task.input;
|
|
5256
|
+
return trimmed(input?.prompt);
|
|
5257
|
+
}
|
|
5258
|
+
function callBusy(call) {
|
|
5259
|
+
return call.status === "running" || call.status === "pending";
|
|
5260
|
+
}
|
|
5261
|
+
function callFailed(call) {
|
|
5262
|
+
return call.status === "failed" || call.result?.isError === true;
|
|
5263
|
+
}
|
|
5264
|
+
function runFailed(items) {
|
|
5265
|
+
const last = items[items.length - 1];
|
|
5266
|
+
return last !== void 0 && callFailed(last);
|
|
5267
|
+
}
|
|
5268
|
+
function taskBusy(task, children) {
|
|
5269
|
+
return callBusy(task) || children.some((child) => child.kind === "tool_call" && callBusy(child));
|
|
5270
|
+
}
|
|
5271
|
+
function taskFailed(task) {
|
|
5272
|
+
return callFailed(task);
|
|
5273
|
+
}
|
|
5274
|
+
function taskSummary$1(task, children) {
|
|
5275
|
+
const busy = taskBusy(task, children);
|
|
5276
|
+
const calls = children.reduce((n, child) => n + (child.kind === "tool_call" ? 1 : 0), 0);
|
|
5277
|
+
const label = taskLabel(task);
|
|
5278
|
+
if (calls === 0) return busy ? `${label} · working…` : `${label} · done`;
|
|
5279
|
+
return `${label} · ${calls} tool${calls === 1 ? "" : "s"}${busy ? "…" : ""}`;
|
|
5280
|
+
}
|
|
5281
|
+
//#endregion
|
|
5282
|
+
//#region src/components/terminal/peer-names.tsx
|
|
5283
|
+
const PeerNamesContext = createContext(/* @__PURE__ */ new Map());
|
|
5284
|
+
function PeerNamesProvider({ items, children }) {
|
|
5285
|
+
const names = useMemo(() => peerNamesOf(items), [items]);
|
|
5286
|
+
return /* @__PURE__ */ jsx(PeerNamesContext.Provider, {
|
|
5287
|
+
value: names,
|
|
5288
|
+
children
|
|
5289
|
+
});
|
|
5290
|
+
}
|
|
5291
|
+
function usePeerNames() {
|
|
5292
|
+
return useContext(PeerNamesContext);
|
|
5293
|
+
}
|
|
5294
|
+
//#endregion
|
|
5134
5295
|
//#region src/components/terminal/press.tsx
|
|
5135
5296
|
const DRAG_SLOP = 4;
|
|
5136
5297
|
function Pressable({ onPress, expanded, className, children }) {
|
|
@@ -5355,72 +5516,6 @@ function evict(cache, keep) {
|
|
|
5355
5516
|
}
|
|
5356
5517
|
}
|
|
5357
5518
|
//#endregion
|
|
5358
|
-
//#region src/components/terminal/tool-run.ts
|
|
5359
|
-
function foldsTogether(a, b) {
|
|
5360
|
-
return a.parentToolUseId === b.parentToolUseId;
|
|
5361
|
-
}
|
|
5362
|
-
function toolFamily(name) {
|
|
5363
|
-
if (isShellTool(name)) return "shell";
|
|
5364
|
-
const mcp = /^mcp__([^_]+(?:_[^_]+)*?)__/.exec(name);
|
|
5365
|
-
if (mcp?.[1]) return mcp[1].replace(/_/g, "-");
|
|
5366
|
-
return name.toLowerCase();
|
|
5367
|
-
}
|
|
5368
|
-
function runSummary(items, busy) {
|
|
5369
|
-
const verb = busy ? "Running " : "Ran ";
|
|
5370
|
-
const tail = busy ? "…" : "";
|
|
5371
|
-
const n = items.length;
|
|
5372
|
-
const counts = /* @__PURE__ */ new Map();
|
|
5373
|
-
for (const item of items) {
|
|
5374
|
-
const family = toolFamily(item.name);
|
|
5375
|
-
counts.set(family, (counts.get(family) ?? 0) + 1);
|
|
5376
|
-
}
|
|
5377
|
-
if (counts.size === 1 && counts.has("shell")) return `${verb}${n} shell command${n === 1 ? "" : "s"}${tail}`;
|
|
5378
|
-
const breakdown = [...counts.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).map(([family, count]) => `${count} ${family}`).join(", ");
|
|
5379
|
-
return `${verb}${n} tool${n === 1 ? "" : "s"} · ${breakdown}${tail}`;
|
|
5380
|
-
}
|
|
5381
|
-
function clip(text, max = 80) {
|
|
5382
|
-
return text.length > max ? text.slice(0, max - 1) + "…" : text;
|
|
5383
|
-
}
|
|
5384
|
-
function trimmed(value) {
|
|
5385
|
-
return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
|
|
5386
|
-
}
|
|
5387
|
-
function taskLabel(task) {
|
|
5388
|
-
return `${task.name}(${taskIdentity(task)})`;
|
|
5389
|
-
}
|
|
5390
|
-
function taskIdentity(task) {
|
|
5391
|
-
const input = task.input;
|
|
5392
|
-
const description = trimmed(input?.description);
|
|
5393
|
-
const agent = trimmed(input?.subagent_type);
|
|
5394
|
-
return agent && description ? `${agent} · ${clip(description)}` : agent ?? (description ? clip(description) : toolInputPreview(task.input));
|
|
5395
|
-
}
|
|
5396
|
-
function taskBrief(task) {
|
|
5397
|
-
const input = task.input;
|
|
5398
|
-
return trimmed(input?.prompt);
|
|
5399
|
-
}
|
|
5400
|
-
function callBusy(call) {
|
|
5401
|
-
return call.status === "running" || call.status === "pending";
|
|
5402
|
-
}
|
|
5403
|
-
function callFailed(call) {
|
|
5404
|
-
return call.status === "failed" || call.result?.isError === true;
|
|
5405
|
-
}
|
|
5406
|
-
function runFailed(items) {
|
|
5407
|
-
const last = items[items.length - 1];
|
|
5408
|
-
return last !== void 0 && callFailed(last);
|
|
5409
|
-
}
|
|
5410
|
-
function taskBusy(task, children) {
|
|
5411
|
-
return callBusy(task) || children.some((child) => child.kind === "tool_call" && callBusy(child));
|
|
5412
|
-
}
|
|
5413
|
-
function taskFailed(task) {
|
|
5414
|
-
return callFailed(task);
|
|
5415
|
-
}
|
|
5416
|
-
function taskSummary$1(task, children) {
|
|
5417
|
-
const busy = taskBusy(task, children);
|
|
5418
|
-
const calls = children.reduce((n, child) => n + (child.kind === "tool_call" ? 1 : 0), 0);
|
|
5419
|
-
const label = taskLabel(task);
|
|
5420
|
-
if (calls === 0) return busy ? `${label} · working…` : `${label} · done`;
|
|
5421
|
-
return `${label} · ${calls} tool${calls === 1 ? "" : "s"}${busy ? "…" : ""}`;
|
|
5422
|
-
}
|
|
5423
|
-
//#endregion
|
|
5424
5519
|
//#region src/components/terminal/todos.ts
|
|
5425
5520
|
const PREVIEW_TODOS = 8;
|
|
5426
5521
|
const GLYPH = {
|
|
@@ -5455,20 +5550,80 @@ function clipToChars(lines, maxChars) {
|
|
|
5455
5550
|
}
|
|
5456
5551
|
return out;
|
|
5457
5552
|
}
|
|
5553
|
+
function peerLabel(origin) {
|
|
5554
|
+
const who = origin.name ? `${origin.name} (${origin.sessionId.slice(0, 8)})` : origin.sessionId.slice(0, 8);
|
|
5555
|
+
return `message from ${origin.engine ? `${origin.engine} session ` : "session "}${who}`;
|
|
5556
|
+
}
|
|
5557
|
+
function PeerRow({ glyph, who, body, tone = "peer", clip }) {
|
|
5558
|
+
const line = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
5559
|
+
/* @__PURE__ */ jsx(Ink, {
|
|
5560
|
+
tone,
|
|
5561
|
+
bold: true,
|
|
5562
|
+
children: who
|
|
5563
|
+
}),
|
|
5564
|
+
": ",
|
|
5565
|
+
body
|
|
5566
|
+
] });
|
|
5567
|
+
return /* @__PURE__ */ jsx(Row, {
|
|
5568
|
+
glyph,
|
|
5569
|
+
glyphTone: tone,
|
|
5570
|
+
tone,
|
|
5571
|
+
children: clip ? /* @__PURE__ */ jsx("span", {
|
|
5572
|
+
className: "term-clip-1",
|
|
5573
|
+
children: line
|
|
5574
|
+
}) : line
|
|
5575
|
+
});
|
|
5576
|
+
}
|
|
5577
|
+
function PeerSendRow({ item }) {
|
|
5578
|
+
const [open, setOpen] = useState(false);
|
|
5579
|
+
const names = usePeerNames();
|
|
5580
|
+
const reveal = useRevealOnOpen(open);
|
|
5581
|
+
const lines = peerSendText(item).split("\n");
|
|
5582
|
+
const tone = item.status === "failed" || item.result?.isError === true ? "red" : "peer";
|
|
5583
|
+
return /* @__PURE__ */ jsx(WithActions, {
|
|
5584
|
+
actions: /* @__PURE__ */ jsx(BookmarkAction, { id: item.id }),
|
|
5585
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
5586
|
+
ref: reveal,
|
|
5587
|
+
className: open ? "term-open" : void 0,
|
|
5588
|
+
children: [/* @__PURE__ */ jsx(Pressable, {
|
|
5589
|
+
onPress: () => setOpen((v) => !v),
|
|
5590
|
+
expanded: open,
|
|
5591
|
+
children: /* @__PURE__ */ jsx(PeerRow, {
|
|
5592
|
+
glyph: "↤",
|
|
5593
|
+
who: peerSendTarget(item, names),
|
|
5594
|
+
tone,
|
|
5595
|
+
clip: !open,
|
|
5596
|
+
body: open ? lines[0] || "\xA0" : peerOneLine(lines.join(" "))
|
|
5597
|
+
})
|
|
5598
|
+
}), open ? /* @__PURE__ */ jsxs("div", { children: [lines.slice(1).map((line, index) => /* @__PURE__ */ jsx(Row, {
|
|
5599
|
+
tone,
|
|
5600
|
+
children: line || "\xA0"
|
|
5601
|
+
}, index)), item.result ? /* @__PURE__ */ jsx(Row, {
|
|
5602
|
+
tone: "faint",
|
|
5603
|
+
children: peerOneLine(item.result.text)
|
|
5604
|
+
}) : null] }) : null]
|
|
5605
|
+
})
|
|
5606
|
+
});
|
|
5607
|
+
}
|
|
5458
5608
|
function UserRow({ item }) {
|
|
5459
5609
|
return /* @__PURE__ */ jsx(WithActions, {
|
|
5460
5610
|
actions: /* @__PURE__ */ jsx(BookmarkAction, { id: item.id }),
|
|
5461
5611
|
children: /* @__PURE__ */ jsxs("div", {
|
|
5462
5612
|
className: "term-user",
|
|
5613
|
+
"data-peer": item.origin ? "" : void 0,
|
|
5463
5614
|
children: [item.attachments?.length ? /* @__PURE__ */ jsx(Row, {
|
|
5464
5615
|
glyph: "❯",
|
|
5465
5616
|
glyphTone: "dim",
|
|
5466
5617
|
tone: "dim",
|
|
5467
5618
|
children: item.attachments.map((attachment) => attachment.name).join(", ")
|
|
5468
|
-
}) : null, item.text ? item.text.split("\n").map((line, index) => /* @__PURE__ */ jsx(
|
|
5469
|
-
glyph:
|
|
5619
|
+
}) : null, item.text ? item.text.split("\n").map((line, index) => item.origin && index === 0 ? /* @__PURE__ */ jsx(PeerRow, {
|
|
5620
|
+
glyph: "↦",
|
|
5621
|
+
who: peerName(item.origin),
|
|
5622
|
+
body: line ? /* @__PURE__ */ jsx(PromptTokenText, { text: line }) : "\xA0"
|
|
5623
|
+
}, index) : /* @__PURE__ */ jsx(Row, {
|
|
5624
|
+
glyph: !item.origin && index === 0 ? "❯" : void 0,
|
|
5470
5625
|
glyphTone: "dim",
|
|
5471
|
-
tone: "fg",
|
|
5626
|
+
tone: item.origin ? "peer" : "fg",
|
|
5472
5627
|
children: line ? /* @__PURE__ */ jsx(PromptTokenText, { text: line }) : "\xA0"
|
|
5473
5628
|
}, index)) : null]
|
|
5474
5629
|
})
|
|
@@ -5553,6 +5708,7 @@ function ToolRow({ item }) {
|
|
|
5553
5708
|
/* @__PURE__ */ jsx(Ink, {
|
|
5554
5709
|
bold: true,
|
|
5555
5710
|
tone: "bright",
|
|
5711
|
+
className: busy ? "term-shimmer" : void 0,
|
|
5556
5712
|
children: title ?? item.name
|
|
5557
5713
|
}),
|
|
5558
5714
|
/* @__PURE__ */ jsxs(Ink, {
|
|
@@ -5688,11 +5844,19 @@ function ToolRunRow({ items }) {
|
|
|
5688
5844
|
glyph: busy ? pulse : void 0,
|
|
5689
5845
|
glyphTone: busy ? "mark" : void 0,
|
|
5690
5846
|
tone: failed ? "red" : "dim",
|
|
5691
|
-
children:
|
|
5847
|
+
children: busy ? /* @__PURE__ */ jsx("span", {
|
|
5848
|
+
className: "term-shimmer",
|
|
5849
|
+
children: runSummary(items, busy)
|
|
5850
|
+
}) : runSummary(items, busy)
|
|
5692
5851
|
})
|
|
5693
5852
|
}), open ? /* @__PURE__ */ jsx("div", { children: items.map((item) => /* @__PURE__ */ jsx(ToolRow, { item }, item.id)) }) : null]
|
|
5694
5853
|
});
|
|
5695
5854
|
}
|
|
5855
|
+
function RunRow({ items }) {
|
|
5856
|
+
const plan = planRun(items);
|
|
5857
|
+
if (plan.kind === "summary") return /* @__PURE__ */ jsx(ToolRunRow, { items: plan.items });
|
|
5858
|
+
return isPeerSend(plan.item) ? /* @__PURE__ */ jsx(PeerSendRow, { item: plan.item }) : /* @__PURE__ */ jsx(ToolRow, { item: plan.item });
|
|
5859
|
+
}
|
|
5696
5860
|
function TurnResultRow$1({ item }) {
|
|
5697
5861
|
return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs(Row, {
|
|
5698
5862
|
tone: item.isError ? "red" : "faint",
|
|
@@ -5770,7 +5934,10 @@ function WorkingRow({ label, startedAt, tokens }) {
|
|
|
5770
5934
|
glyph: pulse,
|
|
5771
5935
|
glyphTone: "mark",
|
|
5772
5936
|
tone: "mark",
|
|
5773
|
-
children: [
|
|
5937
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
5938
|
+
className: "term-shimmer",
|
|
5939
|
+
children: label
|
|
5940
|
+
}), readings.length ? /* @__PURE__ */ jsxs(Ink, {
|
|
5774
5941
|
tone: "faint",
|
|
5775
5942
|
children: [
|
|
5776
5943
|
" (",
|
|
@@ -7446,7 +7613,7 @@ function taskChildItems(block) {
|
|
|
7446
7613
|
}
|
|
7447
7614
|
function pushLeaf(out, item, index) {
|
|
7448
7615
|
const previous = out.at(-1);
|
|
7449
|
-
if (isRunCall(item)) {
|
|
7616
|
+
if (isRunCall(item) && !isPeerSend(item)) {
|
|
7450
7617
|
if (previous && "run" in previous && foldsTogether(previous.run[0], item)) {
|
|
7451
7618
|
previous.run.push(item);
|
|
7452
7619
|
previous.indices.push(index);
|
|
@@ -7512,12 +7679,15 @@ function terminalBlocks(items, offset = 0, fold = true) {
|
|
|
7512
7679
|
return out;
|
|
7513
7680
|
}
|
|
7514
7681
|
function needsBlank(previous, next) {
|
|
7515
|
-
if (previous
|
|
7516
|
-
return
|
|
7682
|
+
if (isPeerSend(previous) || isPeerSend(next)) return true;
|
|
7683
|
+
return !(previous.kind === "tool_call" && next.kind === "tool_call");
|
|
7684
|
+
}
|
|
7685
|
+
function blockKind(block) {
|
|
7686
|
+
if (!("item" in block)) return "tool_call";
|
|
7687
|
+
return isPeerSend(block.item) ? "peer_send" : block.item.kind;
|
|
7517
7688
|
}
|
|
7518
7689
|
function blockNeedsBlank(previous, next) {
|
|
7519
|
-
|
|
7520
|
-
return !(kind(previous) === "tool_call" && kind(next) === "tool_call");
|
|
7690
|
+
return !(blockKind(previous) === "tool_call" && blockKind(next) === "tool_call");
|
|
7521
7691
|
}
|
|
7522
7692
|
//#endregion
|
|
7523
7693
|
//#region src/components/agent/use-subagent-frame.ts
|
|
@@ -9272,12 +9442,20 @@ function itemHeight(item, m) {
|
|
|
9272
9442
|
exact: true
|
|
9273
9443
|
};
|
|
9274
9444
|
if (item.attachments?.length) acc = add(acc, rowH(item.attachments.map((a) => a.name).join(", "), m, { extraPx }));
|
|
9275
|
-
if (item.text)
|
|
9445
|
+
if (item.text) {
|
|
9446
|
+
const who = item.origin ? `${peerName(item.origin)}: ` : "";
|
|
9447
|
+
for (const [index, line] of item.text.split("\n").entries()) acc = add(acc, rowH((index === 0 ? who : "") + (line || " "), m, { extraPx }));
|
|
9448
|
+
}
|
|
9276
9449
|
return acc;
|
|
9277
9450
|
}
|
|
9278
9451
|
case "assistant_text": return markdownHeight(item.text, m, extraPx);
|
|
9279
9452
|
case "thinking": return rowH(item.text, m, { extraPx });
|
|
9280
|
-
case "tool_call":
|
|
9453
|
+
case "tool_call":
|
|
9454
|
+
if (isPeerSend(item)) return {
|
|
9455
|
+
px: m.line + extraPx,
|
|
9456
|
+
exact: true
|
|
9457
|
+
};
|
|
9458
|
+
return toolRowHeight(item, m, extraPx);
|
|
9281
9459
|
case "turn_result": {
|
|
9282
9460
|
let acc = rowH(`${item.isError ? item.subtype : "done"} · ${formatDuration(item.durationMs)} · ${formatCost(item.totalCostUsd)}`, m, { extraPx });
|
|
9283
9461
|
for (const message of item.errors ?? []) acc = add(acc, rowH(message, m, { extraPx }));
|
|
@@ -9295,8 +9473,10 @@ function itemHeight(item, m) {
|
|
|
9295
9473
|
function blockHeight(block, m) {
|
|
9296
9474
|
if ("task" in block) return rowH(taskSummary$1(block.task, taskChildItems(block)), m);
|
|
9297
9475
|
if ("run" in block) {
|
|
9298
|
-
const
|
|
9299
|
-
|
|
9476
|
+
const plan = planRun(block.run);
|
|
9477
|
+
if (plan.kind === "call") return itemHeight(plan.item, m);
|
|
9478
|
+
const busy = plan.items.some((item) => item.status === "running" || item.status === "pending");
|
|
9479
|
+
return rowH(runSummary(plan.items, busy), m);
|
|
9300
9480
|
}
|
|
9301
9481
|
return itemHeight(block.item, m);
|
|
9302
9482
|
}
|
|
@@ -10132,6 +10312,20 @@ function repinToBottom(stick) {
|
|
|
10132
10312
|
};
|
|
10133
10313
|
state.scrollTop = state.calculatedTargetScrollTop;
|
|
10134
10314
|
}
|
|
10315
|
+
function absorbScrollerResize(stick, difference) {
|
|
10316
|
+
const { state } = stick;
|
|
10317
|
+
state.resizeDifference = difference;
|
|
10318
|
+
requestAnimationFrame(() => {
|
|
10319
|
+
setTimeout(() => {
|
|
10320
|
+
if (state.resizeDifference === difference) state.resizeDifference = 0;
|
|
10321
|
+
}, 1);
|
|
10322
|
+
});
|
|
10323
|
+
if (state.animation?.ignoreEscapes) {
|
|
10324
|
+
state.scrollTop = state.calculatedTargetScrollTop;
|
|
10325
|
+
return;
|
|
10326
|
+
}
|
|
10327
|
+
stick.scrollToBottom("instant");
|
|
10328
|
+
}
|
|
10135
10329
|
function useTranscriptJumps(options) {
|
|
10136
10330
|
const { rows, terminal, stickyPrompt, epoch, promptRows, scrollElement, rowsRef, virtualizer, stick, jumpToRecapRef, repinRef } = options;
|
|
10137
10331
|
const aimTimer = useRef(void 0);
|
|
@@ -10209,7 +10403,7 @@ function TerminalItemView({ item, fileUrl }) {
|
|
|
10209
10403
|
case "user": return /* @__PURE__ */ jsx(UserRow, { item });
|
|
10210
10404
|
case "assistant_text": return /* @__PURE__ */ jsx(AssistantRow, { item });
|
|
10211
10405
|
case "thinking": return /* @__PURE__ */ jsx(ThinkingRow, { item });
|
|
10212
|
-
case "tool_call": return /* @__PURE__ */ jsx(ToolRow, { item });
|
|
10406
|
+
case "tool_call": return isPeerSend(item) ? /* @__PURE__ */ jsx(PeerSendRow, { item }) : /* @__PURE__ */ jsx(ToolRow, { item });
|
|
10213
10407
|
case "turn_result": return /* @__PURE__ */ jsx(TurnResultRow$1, { item });
|
|
10214
10408
|
case "notice": return /* @__PURE__ */ jsx(NoticeRow$1, { item });
|
|
10215
10409
|
case "compaction": return /* @__PURE__ */ jsx(CompactionRow$1, { item });
|
|
@@ -10263,14 +10457,17 @@ function TaskRow({ block, fileUrl, onOpenSubagent }) {
|
|
|
10263
10457
|
glyph: busy ? pulse : "●",
|
|
10264
10458
|
glyphTone: failed ? "red" : busy ? "mark" : "dim",
|
|
10265
10459
|
tone: failed ? "red" : "green",
|
|
10266
|
-
children:
|
|
10460
|
+
children: busy ? /* @__PURE__ */ jsx("span", {
|
|
10461
|
+
className: "term-shimmer",
|
|
10462
|
+
children: taskSummary$1(block.task, children)
|
|
10463
|
+
}) : taskSummary$1(block.task, children)
|
|
10267
10464
|
})
|
|
10268
10465
|
}), open ? /* @__PURE__ */ jsxs("div", {
|
|
10269
10466
|
className: "term-nested",
|
|
10270
10467
|
children: [brief ? /* @__PURE__ */ jsx(BriefRow, {
|
|
10271
10468
|
text: brief,
|
|
10272
10469
|
terminal: true
|
|
10273
|
-
}) : null, block.children.map((leaf, index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 && blockNeedsBlank(block.children[index - 1], leaf) ? /* @__PURE__ */ jsx(Blank, {}) : null, "run" in leaf ? /* @__PURE__ */ jsx(
|
|
10470
|
+
}) : null, block.children.map((leaf, index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 && blockNeedsBlank(block.children[index - 1], leaf) ? /* @__PURE__ */ jsx(Blank, {}) : null, "run" in leaf ? /* @__PURE__ */ jsx(RunRow, { items: leaf.run }) : /* @__PURE__ */ jsx(TerminalItemView, {
|
|
10274
10471
|
item: leaf.item,
|
|
10275
10472
|
fileUrl
|
|
10276
10473
|
})] }, leaf.key))]
|
|
@@ -10300,23 +10497,26 @@ function working(state) {
|
|
|
10300
10497
|
function TerminalTranscript({ state, fileUrl, fontSize, lineHeight, affordances, className }) {
|
|
10301
10498
|
const runStartedAt = useRunStart$1(state.status);
|
|
10302
10499
|
const blocks = useMemo(() => terminalBlocks(state.items), [state.items]);
|
|
10303
|
-
return /* @__PURE__ */
|
|
10500
|
+
return /* @__PURE__ */ jsx(TerminalSurface, {
|
|
10304
10501
|
fontSize,
|
|
10305
10502
|
lineHeight,
|
|
10306
10503
|
affordances,
|
|
10307
10504
|
bleed: "1ch",
|
|
10308
10505
|
className: cn("term-transcript", className),
|
|
10309
|
-
children:
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
|
|
10506
|
+
children: /* @__PURE__ */ jsxs(PeerNamesProvider, {
|
|
10507
|
+
items: state.items,
|
|
10508
|
+
children: [blocks.map((block, index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 && blockNeedsBlank(blocks[index - 1], block) ? /* @__PURE__ */ jsx(Blank, {}) : null, "run" in block ? /* @__PURE__ */ jsx(RunRow, { items: block.run }) : "item" in block ? /* @__PURE__ */ jsx(TerminalItemView, {
|
|
10509
|
+
item: block.item,
|
|
10510
|
+
fileUrl
|
|
10511
|
+
}) : /* @__PURE__ */ jsx(TaskRow, {
|
|
10512
|
+
block,
|
|
10513
|
+
fileUrl
|
|
10514
|
+
})] }, block.key)), working(state) ? /* @__PURE__ */ jsxs(Fragment$1, { children: [state.items.length > 0 ? /* @__PURE__ */ jsx(Blank, {}) : null, /* @__PURE__ */ jsx(WorkingRow, {
|
|
10515
|
+
label: state.status === "starting" ? "Starting…" : "Working…",
|
|
10516
|
+
startedAt: runStartedAt,
|
|
10517
|
+
tokens: state.contextUsage?.totalTokens
|
|
10518
|
+
})] }) : null]
|
|
10519
|
+
})
|
|
10320
10520
|
});
|
|
10321
10521
|
}
|
|
10322
10522
|
//#endregion
|
|
@@ -10702,10 +10902,17 @@ function TranscriptItemView({ item, fileUrl, attachmentUrl, hostImage, terminal
|
|
|
10702
10902
|
switch (item.kind) {
|
|
10703
10903
|
case "user": return /* @__PURE__ */ jsxs(Message, {
|
|
10704
10904
|
from: "user",
|
|
10705
|
-
children: [
|
|
10706
|
-
|
|
10707
|
-
|
|
10708
|
-
|
|
10905
|
+
children: [
|
|
10906
|
+
item.origin ? /* @__PURE__ */ jsx("div", {
|
|
10907
|
+
className: "wd-peer-origin text-xs text-muted-foreground",
|
|
10908
|
+
children: peerLabel(item.origin)
|
|
10909
|
+
}) : null,
|
|
10910
|
+
item.attachments?.length ? /* @__PURE__ */ jsx(SentAttachments, {
|
|
10911
|
+
attachments: item.attachments,
|
|
10912
|
+
attachmentUrl
|
|
10913
|
+
}) : null,
|
|
10914
|
+
item.text ? /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(PromptTokenText, { text: item.text }) }) : null
|
|
10915
|
+
]
|
|
10709
10916
|
});
|
|
10710
10917
|
case "assistant_text": return /* @__PURE__ */ jsx(Message, {
|
|
10711
10918
|
from: "assistant",
|
|
@@ -10880,8 +11087,9 @@ function TranscriptRows({ rows, boundary, since, terminal, replaying, stickyProm
|
|
|
10880
11087
|
const observer = new ResizeObserver(() => {
|
|
10881
11088
|
const height = scrollElement.clientHeight;
|
|
10882
11089
|
if (height === last) return;
|
|
11090
|
+
const difference = height - last;
|
|
10883
11091
|
last = height;
|
|
10884
|
-
if (stick.state.isAtBottom) stick
|
|
11092
|
+
if (stick.state.isAtBottom) absorbScrollerResize(stick, difference);
|
|
10885
11093
|
});
|
|
10886
11094
|
observer.observe(scrollElement);
|
|
10887
11095
|
return () => observer.disconnect();
|
|
@@ -11001,59 +11209,62 @@ function TranscriptRows({ rows, boundary, since, terminal, replaying, stickyProm
|
|
|
11001
11209
|
"data-slot": "transcript-rows",
|
|
11002
11210
|
className: "relative w-full",
|
|
11003
11211
|
style: { height: virtualizer.getTotalSize() },
|
|
11004
|
-
children: [
|
|
11005
|
-
|
|
11006
|
-
|
|
11007
|
-
|
|
11008
|
-
|
|
11009
|
-
|
|
11010
|
-
|
|
11011
|
-
|
|
11012
|
-
|
|
11013
|
-
|
|
11014
|
-
|
|
11015
|
-
|
|
11016
|
-
|
|
11212
|
+
children: [/* @__PURE__ */ jsx(PeerNamesProvider, {
|
|
11213
|
+
items,
|
|
11214
|
+
children: virtualizer.getVirtualItems().map((virtualRow) => {
|
|
11215
|
+
const row = rows[virtualRow.index];
|
|
11216
|
+
const gapClass = virtualRow.index > 0 && (!terminal || gapBefore(rows, virtualRow.index)) ? gap.className : void 0;
|
|
11217
|
+
const content = "run" in row ? /* @__PURE__ */ jsx("div", {
|
|
11218
|
+
className: cn(read(boundary, row.index) && "opacity-45"),
|
|
11219
|
+
children: /* @__PURE__ */ jsx(RunRow, { items: row.run })
|
|
11220
|
+
}) : "item" in row ? /* @__PURE__ */ jsx("div", {
|
|
11221
|
+
className: cn(read(boundary, row.index) && "opacity-45", nestedClass(row.item, frameParentId)),
|
|
11222
|
+
children: /* @__PURE__ */ jsx(TranscriptItemView, {
|
|
11223
|
+
item: row.item,
|
|
11224
|
+
fileUrl,
|
|
11225
|
+
attachmentUrl,
|
|
11226
|
+
hostImage,
|
|
11227
|
+
terminal
|
|
11228
|
+
})
|
|
11229
|
+
}) : "text" in row && row.key === "brief" ? /* @__PURE__ */ jsx(BriefRow, {
|
|
11230
|
+
text: row.text,
|
|
11017
11231
|
terminal
|
|
11018
|
-
})
|
|
11019
|
-
|
|
11020
|
-
|
|
11021
|
-
|
|
11022
|
-
|
|
11023
|
-
|
|
11024
|
-
|
|
11025
|
-
|
|
11026
|
-
|
|
11027
|
-
|
|
11028
|
-
|
|
11029
|
-
|
|
11030
|
-
|
|
11031
|
-
|
|
11032
|
-
|
|
11033
|
-
|
|
11034
|
-
|
|
11035
|
-
|
|
11036
|
-
|
|
11037
|
-
|
|
11038
|
-
|
|
11039
|
-
|
|
11040
|
-
|
|
11041
|
-
|
|
11042
|
-
|
|
11043
|
-
|
|
11044
|
-
|
|
11045
|
-
|
|
11046
|
-
|
|
11047
|
-
|
|
11232
|
+
}) : "line" in row ? /* @__PURE__ */ jsx(RecapRow, {
|
|
11233
|
+
line: row.line,
|
|
11234
|
+
since,
|
|
11235
|
+
terminal
|
|
11236
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
11237
|
+
className: cn(read(boundary, row.index) && "opacity-45"),
|
|
11238
|
+
children: /* @__PURE__ */ jsx(TaskRow, {
|
|
11239
|
+
block: row,
|
|
11240
|
+
fileUrl,
|
|
11241
|
+
onOpenSubagent
|
|
11242
|
+
})
|
|
11243
|
+
});
|
|
11244
|
+
if (stickyPrompt && "item" in row && row.item.kind === "user" && parentOf(row.item) === void 0) {
|
|
11245
|
+
const next = promptRows.find((index) => index > virtualRow.index);
|
|
11246
|
+
const laneEnd = next === void 0 ? virtualizer.getTotalSize() : measurements[next]?.start ?? virtualRow.start;
|
|
11247
|
+
return /* @__PURE__ */ jsx(StickyPromptLane, {
|
|
11248
|
+
top: virtualRow.start,
|
|
11249
|
+
height: Math.max(laneEnd - virtualRow.start, 0),
|
|
11250
|
+
gapClass,
|
|
11251
|
+
gapPx: gap.px,
|
|
11252
|
+
terminal,
|
|
11253
|
+
scrollRoot: scrollElement,
|
|
11254
|
+
index: virtualRow.index,
|
|
11255
|
+
measureRef: virtualizer.measureElement,
|
|
11256
|
+
head: terminal ? content : promptHeadText(row.item),
|
|
11257
|
+
content
|
|
11258
|
+
}, row.key);
|
|
11259
|
+
}
|
|
11260
|
+
return /* @__PURE__ */ jsx("div", {
|
|
11261
|
+
ref: virtualizer.measureElement,
|
|
11262
|
+
"data-index": virtualRow.index,
|
|
11263
|
+
className: cn("absolute inset-x-0 top-0", gapClass),
|
|
11264
|
+
style: { transform: `translateY(${virtualRow.start}px)` },
|
|
11265
|
+
children: content
|
|
11048
11266
|
}, row.key);
|
|
11049
|
-
}
|
|
11050
|
-
return /* @__PURE__ */ jsx("div", {
|
|
11051
|
-
ref: virtualizer.measureElement,
|
|
11052
|
-
"data-index": virtualRow.index,
|
|
11053
|
-
className: cn("absolute inset-x-0 top-0", gapClass),
|
|
11054
|
-
style: { transform: `translateY(${virtualRow.start}px)` },
|
|
11055
|
-
children: content
|
|
11056
|
-
}, row.key);
|
|
11267
|
+
})
|
|
11057
11268
|
}), scrubber && scrollElement?.parentElement ? createPortal(terminal ? /* @__PURE__ */ jsx(TerminalScrubber, {
|
|
11058
11269
|
items,
|
|
11059
11270
|
pendingApprovals,
|
|
@@ -11233,14 +11444,16 @@ function Transcript({ state, fileUrl, attachmentUrl, canBrowseFiles, hostImage,
|
|
|
11233
11444
|
const GAP_SHARE = .02;
|
|
11234
11445
|
function sessionCost(input) {
|
|
11235
11446
|
const byModel = input.usageByModel ?? {};
|
|
11236
|
-
const
|
|
11447
|
+
const pricing = input.pricing;
|
|
11448
|
+
const breakdown = costOfByModel(byModel, pricing);
|
|
11237
11449
|
const computedUsd = input.costUsd ?? (breakdown.unpriced || Object.keys(byModel).length === 0 ? void 0 : breakdown.total);
|
|
11238
11450
|
const reportedUsd = input.totalCostUsd;
|
|
11239
11451
|
const rows = Object.entries(byModel).map(([model, usage]) => ({
|
|
11240
11452
|
model: canonicalModel(model),
|
|
11241
11453
|
usage,
|
|
11242
11454
|
tokens: totalTokens(usage),
|
|
11243
|
-
costUsd: rateFor(model) ? costOf(usage, model).total : void 0
|
|
11455
|
+
costUsd: rateFor(model, pricing) ? costOf(usage, model, pricing).total : void 0,
|
|
11456
|
+
costBasis: usage.costBasis
|
|
11244
11457
|
})).sort((a, b) => b.tokens - a.tokens);
|
|
11245
11458
|
const gap = computedUsd !== void 0 && reportedUsd !== void 0 ? reportedUsd - computedUsd : void 0;
|
|
11246
11459
|
const worthShowing = gap !== void 0 && Math.abs(gap) > Math.max(.01, GAP_SHARE * Math.max(computedUsd ?? 0, reportedUsd ?? 0));
|
|
@@ -11252,6 +11465,7 @@ function sessionCost(input) {
|
|
|
11252
11465
|
rows,
|
|
11253
11466
|
unpricedShare: breakdown.unpricedShare,
|
|
11254
11467
|
showUnpricedWarning: breakdown.unpricedShare > UNPRICED_WARN_SHARE,
|
|
11468
|
+
unknownBasisModels: unknownBasisModels(byModel),
|
|
11255
11469
|
gapUsd: worthShowing ? gap : void 0
|
|
11256
11470
|
};
|
|
11257
11471
|
}
|
|
@@ -11339,6 +11553,9 @@ function UsageMeter({ window, now }) {
|
|
|
11339
11553
|
}
|
|
11340
11554
|
//#endregion
|
|
11341
11555
|
//#region src/components/agent/UsageDialog.tsx
|
|
11556
|
+
function engineLabel(engine) {
|
|
11557
|
+
return engine === "claude" ? "Claude Code" : engine;
|
|
11558
|
+
}
|
|
11342
11559
|
function Line({ label, value, tone }) {
|
|
11343
11560
|
return /* @__PURE__ */ jsxs("div", {
|
|
11344
11561
|
className: "flex items-baseline justify-between gap-4",
|
|
@@ -11416,10 +11633,19 @@ function CostEvidence({ cost, engine }) {
|
|
|
11416
11633
|
className: "text-label text-warning",
|
|
11417
11634
|
children: [Math.round(cost.unpricedShare * 100), "% of these tokens ran on a model with no bundled rate, so the total is an understatement rather than an estimate."]
|
|
11418
11635
|
}) : null,
|
|
11636
|
+
cost.unknownBasisModels.length > 0 ? /* @__PURE__ */ jsxs("p", {
|
|
11637
|
+
className: "text-label text-warning",
|
|
11638
|
+
children: [
|
|
11639
|
+
engineLabel(engine),
|
|
11640
|
+
" matched no rate table of its own to ",
|
|
11641
|
+
cost.unknownBasisModels.join(", "),
|
|
11642
|
+
", so the figure it reports for those tokens is a guess rather than a rate."
|
|
11643
|
+
]
|
|
11644
|
+
}) : null,
|
|
11419
11645
|
cost.gapUsd !== void 0 ? /* @__PURE__ */ jsxs("p", {
|
|
11420
11646
|
className: "text-label text-fg-4",
|
|
11421
11647
|
children: [
|
|
11422
|
-
engine
|
|
11648
|
+
engineLabel(engine),
|
|
11423
11649
|
" reports ",
|
|
11424
11650
|
formatCost(cost.reportedUsd),
|
|
11425
11651
|
" for the same tokens."
|
|
@@ -11460,13 +11686,15 @@ function ProfileSpendSection({ spend }) {
|
|
|
11460
11686
|
function formatMultiple(ratio) {
|
|
11461
11687
|
return ratio >= 10 ? `${Math.round(ratio)}x` : `${ratio.toFixed(1)}x`;
|
|
11462
11688
|
}
|
|
11463
|
-
function UsageDialog({ rateLimits, subscriptionType, engine, totalCostUsd, costUsd, usageByModel, spend, updatedAt, open, onOpenChange, className }) {
|
|
11689
|
+
function UsageDialog({ rateLimits, subscriptionType, engine, totalCostUsd, costUsd, usageByModel, pricing, spend, updatedAt, open, onOpenChange, className }) {
|
|
11464
11690
|
const now = useMinuteClock(open);
|
|
11465
11691
|
const cost = sessionCost({
|
|
11466
11692
|
costUsd,
|
|
11467
11693
|
totalCostUsd,
|
|
11468
|
-
usageByModel
|
|
11694
|
+
usageByModel,
|
|
11695
|
+
pricing
|
|
11469
11696
|
});
|
|
11697
|
+
const ageNote = pricingAgeNote(now);
|
|
11470
11698
|
return /* @__PURE__ */ jsx(Dialog$1, {
|
|
11471
11699
|
open,
|
|
11472
11700
|
onOpenChange,
|
|
@@ -11474,7 +11702,7 @@ function UsageDialog({ rateLimits, subscriptionType, engine, totalCostUsd, costU
|
|
|
11474
11702
|
className,
|
|
11475
11703
|
children: [/* @__PURE__ */ jsx(DialogHeader, {
|
|
11476
11704
|
title: "Usage",
|
|
11477
|
-
description: engine
|
|
11705
|
+
description: engineLabel(engine),
|
|
11478
11706
|
actions: subscriptionType ? /* @__PURE__ */ jsx(Badge, {
|
|
11479
11707
|
variant: "accent",
|
|
11480
11708
|
className: "mt-0.5 shrink-0 capitalize",
|
|
@@ -11498,7 +11726,7 @@ function UsageDialog({ rateLimits, subscriptionType, engine, totalCostUsd, costU
|
|
|
11498
11726
|
spend ? /* @__PURE__ */ jsx(ProfileSpendSection, { spend }) : null,
|
|
11499
11727
|
/* @__PURE__ */ jsx("p", {
|
|
11500
11728
|
className: "mt-3 text-label text-fg-4",
|
|
11501
|
-
children: PRICING_NOTE
|
|
11729
|
+
children: ageNote ? `${PRICING_NOTE} ${ageNote}` : PRICING_NOTE
|
|
11502
11730
|
}),
|
|
11503
11731
|
updatedAt ? /* @__PURE__ */ jsxs("p", {
|
|
11504
11732
|
className: "mt-2 text-label text-fg-4",
|
|
@@ -11550,7 +11778,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
|
|
|
11550
11778
|
const [panel, setPanel] = useState();
|
|
11551
11779
|
const [showCompletedTasks, setShowCompletedTasks] = useState(false);
|
|
11552
11780
|
const [taskReveal, setTaskReveal] = useState();
|
|
11553
|
-
const { state, connection, replaying, protocolMismatch, shell, models, effectiveModel, handle, send, runShell, approve, deny, interrupt, clearContext, setModel, setPermissionMode, reconnectNow, loadFullResult } = useClaudeSession(client, sessionId, {
|
|
11781
|
+
const { state, connection, replaying, protocolMismatch, shell, pricing, models, effectiveModel, handle, send, runShell, approve, deny, interrupt, clearContext, setModel, setPermissionMode, reconnectNow, loadFullResult } = useClaudeSession(client, sessionId, {
|
|
11554
11782
|
onProtocolError: setProtocolError,
|
|
11555
11783
|
cacheTranscript
|
|
11556
11784
|
});
|
|
@@ -12068,6 +12296,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
|
|
|
12068
12296
|
totalCostUsd: state.totalCostUsd,
|
|
12069
12297
|
costUsd: state.costUsd,
|
|
12070
12298
|
usageByModel: state.usageByModel,
|
|
12299
|
+
pricing,
|
|
12071
12300
|
spend: profileSpend,
|
|
12072
12301
|
updatedAt: usageUpdatedAt,
|
|
12073
12302
|
open: panel === "usage",
|
|
@@ -12281,4 +12510,4 @@ function resolveAgainstCwd(path, cwd) {
|
|
|
12281
12510
|
//#endregion
|
|
12282
12511
|
export { TerminalDiff as $, SelectValue as $t, PermissionPrompt as A, Spinner as At, EntryIcon as B, DialogHeader as Bt, SessionInfoDialog as C, usePromptAreaState as Ct, QuestionPrompt as D, ProgressRing as Dt, QUESTION_BEHAVIORS as E, segmentsToPlainText as Et, permissionModeMeta as F, TooltipProvider as Ft, Composer as G, MenuItem as Gt, TaskList as H, DialogTrigger as Ht, ModelSelect as I, Dialog$1 as It, useToolTitle as J, Select$1 as Jt, TerminalSurface as K, MenuSeparator as Kt, SkillsDialog as L, DialogBody as Lt, PERMISSION_MODES as M, copyText as Mt, PermissionModeSelect as N, Tip as Nt, parseUserQuestions as O, Splitter as Ot, permissionModeChoices as P, TooltipContent as Pt, parseFileLink as Q, SelectTrigger as Qt, McpDialog as R, DialogClose as Rt, STATUS_META as S, mentionTrigger as St, TerminalPermissionPrompt as T, plainTextToSegments as Tt, ContextDialog as U, Menu$1 as Ut, TasksDialog as V, DialogRow as Vt, contextNote as W, MenuContent as Wt, FileLinkProvider as X, SelectItem as Xt, TerminalMarkdown as Y, SelectContent as Yt, useFileLinks as Z, SelectItemText as Zt, Loader as _, rankComposerRows as _t, UsageDialog as a, Button as an, CopyAction as at, ConversationScrollButton as b, hashtagTrigger as bt, Transcript as c, PromptTokenText as ct, Message as d, TranscriptDensityProvider as dt, PortalScope as en, previewPatch as et, MessageContent as f, TranscriptVariantProvider as ft, SessionEmptyState as g, mergeComposerRows as gt, TerminalTranscript as h, matchClientCommand as ht, SessionPanel as i, badgeVariants as in, Row as it, Response as j, CopyButton as jt, SubagentStrip as k, CodeBlock as kt, ToolCallCard as l, isMutatingTool as lt, TerminalItemView as m, useTranscriptVariant as mt, usePathLinks as n, Input as nn, Blank as nt, UsageMeters as o, buttonVariants as on, WithActions as ot, FileCard as p, useTranscriptDensity as pt, ToolTitleProvider as q, MenuTrigger as qt, matchPath as r, Badge as rn, Ink as rt, useMinuteClock as s, cn as sn, useAffordances as st, resolveAgainstCwd as t, Textarea as tn, Band as tt, Reasoning as u, toolIcon as ut, Conversation as v, skillPrompt as vt, TerminalQuestionPrompt as w, PromptArea as wt, StatusBar as x, launchTrigger as xt, ConversationContent as y, commandTrigger as yt, HostFilesDialog as z, DialogContent as zt };
|
|
12283
12512
|
|
|
12284
|
-
//# sourceMappingURL=use-path-links-
|
|
12513
|
+
//# sourceMappingURL=use-path-links-DO_79-wX.mjs.map
|