@percena/weft-react 0.1.4 → 0.1.5-next.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/dist/index.cjs CHANGED
@@ -30,9 +30,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
+ ActivityDetailsPanel: () => ActivityDetailsPanel,
34
+ ActivityInspector: () => ActivityInspector,
33
35
  AgentChatPanel: () => AgentChatPanel,
34
36
  AnnotationIslandMenu: () => AnnotationIslandMenu,
35
37
  AnnotationOverlayLayer: () => AnnotationOverlayLayer,
38
+ AssistantTurnCard: () => AssistantTurnCard,
36
39
  ChatTranscript: () => ChatTranscript,
37
40
  CodeBlock: () => CodeBlock,
38
41
  CollapsibleMarkdownProvider: () => CollapsibleMarkdownProvider,
@@ -43,6 +46,7 @@ __export(src_exports, {
43
46
  Markdown: () => Markdown,
44
47
  MemoizedMarkdown: () => MemoizedMarkdown,
45
48
  PendingIndicator: () => PendingIndicator,
49
+ PermissionModeMenu: () => PermissionModeMenu,
46
50
  PermissionRequestCard: () => PermissionRequestCard,
47
51
  PlatformProvider: () => PlatformProvider,
48
52
  ResponseCard: () => ResponseCard,
@@ -240,6 +244,12 @@ var import_jsx_runtime32 = require("react/jsx-runtime");
240
244
  var import_jsx_runtime33 = require("react/jsx-runtime");
241
245
  var import_jsx_runtime34 = require("react/jsx-runtime");
242
246
  var import_react15 = require("react");
247
+ var import_jsx_runtime35 = require("react/jsx-runtime");
248
+ var import_jsx_runtime36 = require("react/jsx-runtime");
249
+ var import_react16 = require("react");
250
+ var import_jsx_runtime37 = require("react/jsx-runtime");
251
+ var import_jsx_runtime38 = require("react/jsx-runtime");
252
+ var import_react17 = require("react");
243
253
  function getAssistantTurnUiKey(turn, index) {
244
254
  if (turn.response?.messageId) {
245
255
  return `assistant:msg:${turn.response.messageId}`;
@@ -5190,6 +5200,162 @@ function PendingIndicator({
5190
5200
  delay
5191
5201
  )) }) });
5192
5202
  }
5203
+ function AssistantTurnCard({
5204
+ sessionId,
5205
+ turn,
5206
+ isLast,
5207
+ onInspectActivity
5208
+ }) {
5209
+ const [isExpanded, setIsExpanded] = (0, import_react15.useState)(true);
5210
+ const [expandedActivityGroups, setExpandedActivityGroups] = (0, import_react15.useState)(/* @__PURE__ */ new Set());
5211
+ (0, import_react15.useEffect)(() => {
5212
+ if (turn.isStreaming) {
5213
+ setIsExpanded(true);
5214
+ }
5215
+ }, [turn.isStreaming]);
5216
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
5217
+ TurnCard,
5218
+ {
5219
+ sessionId,
5220
+ turnId: turn.turnId,
5221
+ activities: turn.activities,
5222
+ response: turn.response,
5223
+ intent: turn.intent,
5224
+ isStreaming: turn.isStreaming,
5225
+ isComplete: turn.isComplete,
5226
+ isExpanded,
5227
+ onExpandedChange: setIsExpanded,
5228
+ expandedActivityGroups,
5229
+ onExpandedActivityGroupsChange: setExpandedActivityGroups,
5230
+ onOpenActivityDetails: onInspectActivity,
5231
+ hasEditOrWriteActivities: turn.activities.some(
5232
+ (activity) => activity.toolName === "Edit" || activity.toolName === "Write"
5233
+ ),
5234
+ todos: turn.todos,
5235
+ isLastResponse: isLast,
5236
+ displayMode: "detailed",
5237
+ animateResponse: true,
5238
+ annotationInteractionMode: "tooltip-only"
5239
+ }
5240
+ );
5241
+ }
5242
+ function ActivityInspector({
5243
+ activity,
5244
+ onClose
5245
+ }) {
5246
+ if (!activity) {
5247
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "rounded-[8px] bg-background shadow-minimal p-4 text-[13px] text-muted-foreground", children: "Select an activity from the turn card to inspect its input and output." });
5248
+ }
5249
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-col overflow-hidden", children: [
5250
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-start justify-between gap-3 border-b border-border px-4 py-3", children: [
5251
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "min-w-0", children: [
5252
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "truncate text-[13px] font-medium text-foreground", children: activity.displayName ?? activity.toolName ?? "Activity" }),
5253
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mt-1 text-[12px] text-muted-foreground", children: activity.intent ?? activity.status ?? "unknown" })
5254
+ ] }),
5255
+ onClose && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
5256
+ "button",
5257
+ {
5258
+ type: "button",
5259
+ onClick: onClose,
5260
+ className: "flex h-7 w-7 items-center justify-center rounded-[6px] text-[16px] leading-none text-muted-foreground transition hover:bg-foreground/[0.06] hover:text-foreground",
5261
+ "aria-label": "Close activity details",
5262
+ children: "\u2715"
5263
+ }
5264
+ )
5265
+ ] }),
5266
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "overflow-y-auto space-y-4 p-4", children: [
5267
+ activity.toolInput && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
5268
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mb-2 text-[12px] font-medium text-muted-foreground", children: "Input" }),
5269
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("pre", { className: "max-h-[280px] overflow-auto rounded-[6px] bg-foreground/[0.04] p-3 text-[12px] leading-relaxed text-foreground", children: JSON.stringify(activity.toolInput, null, 2) })
5270
+ ] }),
5271
+ activity.error && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
5272
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mb-2 text-[12px] font-medium text-muted-foreground", children: "Error" }),
5273
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("pre", { className: "max-h-[320px] overflow-auto whitespace-pre-wrap rounded-[6px] bg-foreground/[0.04] p-3 text-[12px] leading-relaxed text-foreground", children: activity.error })
5274
+ ] }),
5275
+ activity.content && !activity.error && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
5276
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mb-2 text-[12px] font-medium text-muted-foreground", children: "Output" }),
5277
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "max-h-[320px] overflow-y-auto rounded-[6px] bg-foreground/[0.04] px-3 py-2 text-[12px] text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Markdown, { mode: "minimal", className: "text-[12px] leading-relaxed", children: activity.content }) })
5278
+ ] })
5279
+ ] })
5280
+ ] });
5281
+ }
5282
+ function ActivityDetailsPanel({
5283
+ activity,
5284
+ onClose
5285
+ }) {
5286
+ (0, import_react16.useEffect)(() => {
5287
+ if (!activity) return;
5288
+ const handleKeyDown = (e) => {
5289
+ if (e.key === "Escape") onClose();
5290
+ };
5291
+ window.addEventListener("keydown", handleKeyDown);
5292
+ return () => window.removeEventListener("keydown", handleKeyDown);
5293
+ }, [activity, onClose]);
5294
+ if (!activity) return null;
5295
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
5296
+ "div",
5297
+ {
5298
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-background/60 backdrop-blur-sm",
5299
+ onClick: onClose,
5300
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
5301
+ "div",
5302
+ {
5303
+ className: "relative w-full max-w-[640px] max-h-[80vh] overflow-hidden rounded-[12px] border border-border bg-background shadow-strong mx-4",
5304
+ onClick: (e) => e.stopPropagation(),
5305
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ActivityInspector, { activity, onClose })
5306
+ }
5307
+ )
5308
+ }
5309
+ );
5310
+ }
5311
+ var PERMISSION_CONFIG = [
5312
+ { mode: "safe", label: "Explore", description: "Read-only planning and inspection.", icon: "\u25CE" },
5313
+ { mode: "ask", label: "Ask", description: "Review changes before execution.", icon: "\u24D8" },
5314
+ { mode: "allow-all", label: "Execute", description: "Allow edits and commands in this session.", icon: "\u21C4" }
5315
+ ];
5316
+ function PermissionModeMenu({
5317
+ value,
5318
+ onChange,
5319
+ onClose,
5320
+ isOpen,
5321
+ onToggle
5322
+ }) {
5323
+ const selected = PERMISSION_CONFIG.find((o) => o.mode === value) ?? PERMISSION_CONFIG[1];
5324
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "relative", children: [
5325
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "absolute bottom-[calc(100%+6px)] left-0 z-20 w-[204px] rounded-[9px] border border-border bg-background p-1.5 shadow-modal-small", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "space-y-0.5", children: PERMISSION_CONFIG.map((option) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
5326
+ "button",
5327
+ {
5328
+ type: "button",
5329
+ onClick: () => {
5330
+ onChange(option.mode);
5331
+ onClose?.();
5332
+ },
5333
+ className: `flex h-8 w-full items-center gap-2 rounded-[6px] px-2 text-left text-[12px] transition ${option.mode === value ? "bg-foreground/[0.08] text-foreground" : "text-muted-foreground hover:bg-foreground/[0.05] hover:text-foreground"}`,
5334
+ children: [
5335
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "w-4 text-center text-[12px]", children: option.icon }),
5336
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "flex-1", children: option.label }),
5337
+ option.mode === value && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { "aria-hidden": "true", className: "text-[12px] text-foreground", children: "\u25CF" })
5338
+ ]
5339
+ },
5340
+ option.mode
5341
+ )) }) }),
5342
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
5343
+ "button",
5344
+ {
5345
+ type: "button",
5346
+ "aria-haspopup": "menu",
5347
+ "aria-expanded": isOpen,
5348
+ onClick: onToggle,
5349
+ className: "inline-flex h-8 items-center gap-1.5 rounded-[7px] border border-border bg-foreground/[0.035] px-2.5 text-[12px] text-foreground transition hover:bg-foreground/[0.06]",
5350
+ children: [
5351
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-muted-foreground", children: selected.icon }),
5352
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: selected.label }),
5353
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-muted-foreground", children: "\u2304" })
5354
+ ]
5355
+ }
5356
+ )
5357
+ ] });
5358
+ }
5193
5359
  function generateMessageId2() {
5194
5360
  return generateMessageId();
5195
5361
  }
@@ -5272,6 +5438,24 @@ function handleTextDelta(state, event) {
5272
5438
  const streamingIndex = findStreamingMessage(session.messages, event.turnId);
5273
5439
  if (streamingIndex !== -1) {
5274
5440
  const currentMsg = session.messages[streamingIndex];
5441
+ if (currentMsg.isIntermediate && !event.isIntermediate) {
5442
+ const closedSession = updateMessageAt(session, streamingIndex, {
5443
+ isStreaming: false
5444
+ });
5445
+ const newMessage2 = {
5446
+ id: generateMessageId2(),
5447
+ role: "assistant",
5448
+ content: event.delta,
5449
+ timestamp: event.timestamp ?? Date.now(),
5450
+ isStreaming: true,
5451
+ isPending: true,
5452
+ turnId: event.turnId
5453
+ };
5454
+ return {
5455
+ session: appendMessage(closedSession, newMessage2, false),
5456
+ streaming: { content: event.delta, turnId: event.turnId }
5457
+ };
5458
+ }
5275
5459
  const updatedSession = updateMessageAt(session, streamingIndex, {
5276
5460
  content: currentMsg.content + event.delta
5277
5461
  });
@@ -5284,7 +5468,8 @@ function handleTextDelta(state, event) {
5284
5468
  timestamp: event.timestamp ?? Date.now(),
5285
5469
  isStreaming: true,
5286
5470
  isPending: true,
5287
- turnId: event.turnId
5471
+ turnId: event.turnId,
5472
+ ...event.isIntermediate ? { isIntermediate: true } : {}
5288
5473
  };
5289
5474
  return {
5290
5475
  session: appendMessage(session, newMessage, false),
@@ -5294,12 +5479,15 @@ function handleTextDelta(state, event) {
5294
5479
  function handleTextComplete(state, event) {
5295
5480
  const { session, streaming } = state;
5296
5481
  let msgIndex = findStreamingMessage(session.messages, event.turnId);
5482
+ if (msgIndex !== -1 && event.isIntermediate && !session.messages[msgIndex].isIntermediate) {
5483
+ msgIndex = -1;
5484
+ }
5297
5485
  if (msgIndex === -1) {
5298
5486
  msgIndex = findAssistantMessage(session.messages, event.turnId);
5299
5487
  }
5300
5488
  if (msgIndex !== -1) {
5301
5489
  const existingMsg = session.messages[msgIndex];
5302
- if (!existingMsg.isStreaming && existingMsg.isIntermediate && event.isIntermediate) {
5490
+ if (!existingMsg.isStreaming && existingMsg.isIntermediate && !existingMsg.isPending) {
5303
5491
  msgIndex = -1;
5304
5492
  }
5305
5493
  }
@@ -6367,14 +6555,16 @@ function mapCoreEventToProcessorEvent(coreEvent, sessionId) {
6367
6555
  type: "text_delta",
6368
6556
  sessionId,
6369
6557
  delta: coreEvent.text,
6370
- turnId: coreEvent.turnId
6558
+ turnId: coreEvent.turnId,
6559
+ isIntermediate: true
6371
6560
  };
6372
6561
  case "reasoning":
6373
6562
  return {
6374
6563
  type: "text_complete",
6375
6564
  sessionId,
6376
6565
  text: coreEvent.text,
6377
- turnId: coreEvent.turnId
6566
+ turnId: coreEvent.turnId,
6567
+ isIntermediate: true
6378
6568
  };
6379
6569
  case "permission_response":
6380
6570
  return {
@@ -6414,7 +6604,8 @@ function mapTimelineEnvelopeToProcessorEvent(envelope) {
6414
6604
  sessionId,
6415
6605
  delta: item.text,
6416
6606
  turnId: item.turnId,
6417
- timestamp
6607
+ timestamp,
6608
+ ...item.type === "reasoning_delta" && { isIntermediate: true }
6418
6609
  };
6419
6610
  case "assistant_message":
6420
6611
  case "reasoning":
@@ -6424,7 +6615,8 @@ function mapTimelineEnvelopeToProcessorEvent(envelope) {
6424
6615
  text: item.text,
6425
6616
  turnId: item.turnId,
6426
6617
  timestamp,
6427
- messageId: item.messageId
6618
+ messageId: item.messageId,
6619
+ ...item.type === "reasoning" && { isIntermediate: true }
6428
6620
  };
6429
6621
  case "tool_call":
6430
6622
  return {
@@ -6591,6 +6783,10 @@ function normalizeTimelineToolName(name) {
6591
6783
  return name;
6592
6784
  }
6593
6785
  function optionalToolDisplayName(toolName, detail) {
6786
+ if (detail && typeof detail === "object") {
6787
+ const explicit = detail.displayName;
6788
+ if (typeof explicit === "string" && explicit) return { toolDisplayName: explicit };
6789
+ }
6594
6790
  if (toolName !== "commandExecution") return {};
6595
6791
  const displayName = commandDisplayName(detail);
6596
6792
  return displayName ? { toolDisplayName: displayName } : {};
@@ -6726,12 +6922,12 @@ function normalizeTokenUsage(usage) {
6726
6922
  }
6727
6923
  function useEventProcessor(options) {
6728
6924
  const { eventSource, sessionId, workspaceId, workspaceName, onEffect, onError, onClose } = options;
6729
- const [session, setSession] = (0, import_react15.useState)(null);
6730
- const sessionRef = (0, import_react15.useRef)(null);
6731
- const streamingStates = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
6732
- const [isConnected, setIsConnected] = (0, import_react15.useState)(false);
6733
- const processedCount = (0, import_react15.useRef)(0);
6734
- const processAgentEvent = (0, import_react15.useCallback)((event) => {
6925
+ const [session, setSession] = (0, import_react17.useState)(null);
6926
+ const sessionRef = (0, import_react17.useRef)(null);
6927
+ const streamingStates = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
6928
+ const [isConnected, setIsConnected] = (0, import_react17.useState)(false);
6929
+ const processedCount = (0, import_react17.useRef)(0);
6930
+ const processAgentEvent = (0, import_react17.useCallback)((event) => {
6735
6931
  const processorEvent = mapCoreEventToProcessorEvent(event, sessionId);
6736
6932
  const currentSession = sessionRef.current ?? createEmptySession(sessionId, workspaceId, workspaceName ?? "");
6737
6933
  const currentState = {
@@ -6751,7 +6947,7 @@ function useEventProcessor(options) {
6751
6947
  effects: result.effects
6752
6948
  };
6753
6949
  }, [sessionId, workspaceId, workspaceName]);
6754
- (0, import_react15.useEffect)(() => {
6950
+ (0, import_react17.useEffect)(() => {
6755
6951
  eventSource.connect(
6756
6952
  (coreEvent) => {
6757
6953
  const result = processAgentEvent(coreEvent);
@@ -6774,10 +6970,10 @@ function useEventProcessor(options) {
6774
6970
  setIsConnected(false);
6775
6971
  };
6776
6972
  }, [eventSource, processAgentEvent, onEffect, onError, onClose]);
6777
- const clearStreamingState = (0, import_react15.useCallback)(() => {
6973
+ const clearStreamingState = (0, import_react17.useCallback)(() => {
6778
6974
  streamingStates.current.delete(sessionId);
6779
6975
  }, [sessionId]);
6780
- const getStreamingState = (0, import_react15.useCallback)(() => {
6976
+ const getStreamingState = (0, import_react17.useCallback)(() => {
6781
6977
  return streamingStates.current.get(sessionId) ?? null;
6782
6978
  }, [sessionId]);
6783
6979
  return {
@@ -6909,8 +7105,8 @@ var InProcessEventSource = class {
6909
7105
  };
6910
7106
 
6911
7107
  // ../local-chat/dist/index.js
6912
- var import_react16 = require("react");
6913
- var import_react17 = require("react");
7108
+ var import_react18 = require("react");
7109
+ var import_react19 = require("react");
6914
7110
 
6915
7111
  // ../timeline/dist/index.js
6916
7112
  function createTimelineCursor(cursor) {
@@ -6958,9 +7154,9 @@ function timelineKey(item) {
6958
7154
  }
6959
7155
 
6960
7156
  // ../local-chat/dist/index.js
6961
- var import_jsx_runtime35 = require("react/jsx-runtime");
6962
- var import_react18 = require("react");
6963
- var import_jsx_runtime36 = require("react/jsx-runtime");
7157
+ var import_jsx_runtime39 = require("react/jsx-runtime");
7158
+ var import_react20 = require("react");
7159
+ var import_jsx_runtime40 = require("react/jsx-runtime");
6964
7160
  function createAgentChatPanelModel(args) {
6965
7161
  return {
6966
7162
  turns: args.session ? groupMessagesByTurn(args.session.messages) : [],
@@ -7047,8 +7243,8 @@ function createTimelineDetailItems(timeline) {
7047
7243
  }
7048
7244
  function useAgentChatSession(options) {
7049
7245
  const { runtime, workspaceId = "local-workspace", workspaceName = "Local Workspace" } = options;
7050
- const [auth, setAuth] = (0, import_react17.useState)(null);
7051
- const [error, setError] = (0, import_react17.useState)(null);
7246
+ const [auth, setAuth] = (0, import_react19.useState)(null);
7247
+ const [error, setError] = (0, import_react19.useState)(null);
7052
7248
  const processor = useEventProcessor({
7053
7249
  eventSource: runtime.events,
7054
7250
  sessionId: runtime.sessionId,
@@ -7056,7 +7252,7 @@ function useAgentChatSession(options) {
7056
7252
  workspaceName,
7057
7253
  onError: setError
7058
7254
  });
7059
- const sendMessage = (0, import_react17.useCallback)(async (message) => {
7255
+ const sendMessage = (0, import_react19.useCallback)(async (message) => {
7060
7256
  setError(null);
7061
7257
  try {
7062
7258
  if (!auth) {
@@ -7072,13 +7268,13 @@ function useAgentChatSession(options) {
7072
7268
  throw err;
7073
7269
  }
7074
7270
  }, [auth, runtime]);
7075
- const abort = (0, import_react17.useCallback)(async () => {
7271
+ const abort = (0, import_react19.useCallback)(async () => {
7076
7272
  await runtime.commands.abort("User aborted");
7077
7273
  }, [runtime]);
7078
- const respondToPermission = (0, import_react17.useCallback)(async (requestId, allowed, remember) => {
7274
+ const respondToPermission = (0, import_react19.useCallback)(async (requestId, allowed, remember) => {
7079
7275
  await runtime.commands.respondToPermission(requestId, allowed, remember);
7080
7276
  }, [runtime]);
7081
- const model = (0, import_react17.useMemo)(
7277
+ const model = (0, import_react19.useMemo)(
7082
7278
  () => createAgentChatPanelModel({ session: processor.session, runtime, auth, error }),
7083
7279
  [processor.session, runtime, auth, error]
7084
7280
  );
@@ -7095,13 +7291,13 @@ function useAgentChatSession(options) {
7095
7291
  }
7096
7292
  function useTimelineAgentChatSession(options) {
7097
7293
  const { runtime, workspaceId = "local-workspace", workspaceName = "Local Workspace" } = options;
7098
- const [timeline, setTimeline] = (0, import_react17.useState)([]);
7099
- const [capabilityReport, setCapabilityReport] = (0, import_react17.useState)(null);
7100
- const [error, setError] = (0, import_react17.useState)(null);
7101
- const [isReconnecting, setIsReconnecting] = (0, import_react17.useState)(false);
7102
- const [hasGap, setHasGap] = (0, import_react17.useState)(false);
7103
- const lastCursorRef = (0, import_react17.useRef)(null);
7104
- (0, import_react17.useEffect)(() => {
7294
+ const [timeline, setTimeline] = (0, import_react19.useState)([]);
7295
+ const [capabilityReport, setCapabilityReport] = (0, import_react19.useState)(null);
7296
+ const [error, setError] = (0, import_react19.useState)(null);
7297
+ const [isReconnecting, setIsReconnecting] = (0, import_react19.useState)(false);
7298
+ const [hasGap, setHasGap] = (0, import_react19.useState)(false);
7299
+ const lastCursorRef = (0, import_react19.useRef)(null);
7300
+ (0, import_react19.useEffect)(() => {
7105
7301
  let catchupAbort = false;
7106
7302
  const onEvent = (envelope) => {
7107
7303
  lastCursorRef.current = { epoch: envelope.epoch, afterSeq: envelope.seq };
@@ -7137,7 +7333,7 @@ function useTimelineAgentChatSession(options) {
7137
7333
  runtime.events.disconnect();
7138
7334
  };
7139
7335
  }, [runtime]);
7140
- const sendMessage = (0, import_react17.useCallback)(async (message, options2) => {
7336
+ const sendMessage = (0, import_react19.useCallback)(async (message, options2) => {
7141
7337
  setError(null);
7142
7338
  setHasGap(false);
7143
7339
  try {
@@ -7152,13 +7348,13 @@ function useTimelineAgentChatSession(options) {
7152
7348
  throw err;
7153
7349
  }
7154
7350
  }, [capabilityReport, runtime]);
7155
- const abort = (0, import_react17.useCallback)(async () => {
7351
+ const abort = (0, import_react19.useCallback)(async () => {
7156
7352
  await runtime.commands.abort("User aborted");
7157
7353
  }, [runtime]);
7158
- const respondToPermission = (0, import_react17.useCallback)(async (requestId, allowed, remember) => {
7354
+ const respondToPermission = (0, import_react19.useCallback)(async (requestId, allowed, remember) => {
7159
7355
  await runtime.commands.respondToPermission(requestId, allowed, remember);
7160
7356
  }, [runtime]);
7161
- const model = (0, import_react17.useMemo)(
7357
+ const model = (0, import_react19.useMemo)(
7162
7358
  () => createTimelineAgentChatPanelModel({
7163
7359
  timeline,
7164
7360
  sessionId: runtime.sessionId,
@@ -7395,7 +7591,7 @@ function AgentChatPanel({
7395
7591
  className
7396
7592
  }) {
7397
7593
  const chat = useAgentChatSession({ runtime, workspaceId, workspaceName });
7398
- const [draft, setDraft] = (0, import_react16.useState)("");
7594
+ const [draft, setDraft] = (0, import_react18.useState)("");
7399
7595
  async function handleSubmit(event) {
7400
7596
  event.preventDefault();
7401
7597
  const message = draft.trim();
@@ -7407,8 +7603,8 @@ function AgentChatPanel({
7407
7603
  }
7408
7604
  }
7409
7605
  const storedSession = chat.session ? toStoredSession(chat.session, workspaceId) : createEmptyStoredSession(runtime.sessionId, workspaceId, workspaceName);
7410
- const footer = /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("form", { onSubmit: handleSubmit, className: "flex gap-2 p-3", children: [
7411
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
7606
+ const footer = /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("form", { onSubmit: handleSubmit, className: "flex gap-2 p-3", children: [
7607
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7412
7608
  "textarea",
7413
7609
  {
7414
7610
  value: draft,
@@ -7418,7 +7614,7 @@ function AgentChatPanel({
7418
7614
  className: "min-h-10 flex-1 resize-none rounded-md border px-3 py-2 text-sm"
7419
7615
  }
7420
7616
  ),
7421
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
7617
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7422
7618
  "button",
7423
7619
  {
7424
7620
  type: "submit",
@@ -7427,7 +7623,7 @@ function AgentChatPanel({
7427
7623
  children: "Send"
7428
7624
  }
7429
7625
  ),
7430
- chat.isRunning && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
7626
+ chat.isRunning && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7431
7627
  "button",
7432
7628
  {
7433
7629
  type: "button",
@@ -7437,9 +7633,9 @@ function AgentChatPanel({
7437
7633
  }
7438
7634
  )
7439
7635
  ] });
7440
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className, children: [
7441
- chat.error && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "border-b px-3 py-2 text-sm text-red-600", children: chat.error.message }),
7442
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
7636
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className, children: [
7637
+ chat.error && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "border-b px-3 py-2 text-sm text-red-600", children: chat.error.message }),
7638
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7443
7639
  SessionViewer,
7444
7640
  {
7445
7641
  session: storedSession,
@@ -7511,27 +7707,24 @@ function TimelineAgentChatPanel({
7511
7707
  className
7512
7708
  }) {
7513
7709
  const chat = useTimelineAgentChatSession({ runtime, workspaceId, workspaceName });
7514
- const [draft, setDraft] = (0, import_react18.useState)("");
7515
- const [selectedActivity, setSelectedActivity] = (0, import_react18.useState)(null);
7516
- const [selectedDetail, setSelectedDetail] = (0, import_react18.useState)(null);
7517
- const [permissionMode, setPermissionMode] = (0, import_react18.useState)("ask");
7518
- const [turnExpandOverride, setTurnExpandOverride] = (0, import_react18.useState)({});
7519
- const handleTurnExpandedChange = (0, import_react18.useCallback)((turnId, expanded) => {
7520
- setTurnExpandOverride((prev) => ({ ...prev, [turnId]: expanded }));
7521
- }, []);
7710
+ const [draft, setDraft] = (0, import_react20.useState)("");
7711
+ const [selectedActivity, setSelectedActivity] = (0, import_react20.useState)(null);
7712
+ const [selectedDetail, setSelectedDetail] = (0, import_react20.useState)(null);
7713
+ const [permissionMode, setPermissionMode] = (0, import_react20.useState)("ask");
7714
+ const [isPermMenuOpen, setIsPermMenuOpen] = (0, import_react20.useState)(false);
7522
7715
  const runtimeState = runtime.getState();
7523
7716
  const isWaitingPermission = runtimeState.status === "waiting_for_permission";
7524
7717
  const waitingRequestId = runtimeState.waitingPermissionRequestId;
7525
- const permissionRequest = (0, import_react18.useMemo)(() => {
7718
+ const permissionRequest = (0, import_react20.useMemo)(() => {
7526
7719
  if (!isWaitingPermission || !waitingRequestId) return null;
7527
7720
  return findActivePermissionRequest(chat.timeline);
7528
7721
  }, [isWaitingPermission, waitingRequestId, chat.timeline]);
7529
- const detailItems = (0, import_react18.useMemo)(
7722
+ const detailItems = (0, import_react20.useMemo)(
7530
7723
  () => createTimelineDetailItems(chat.timeline),
7531
7724
  [chat.timeline]
7532
7725
  );
7533
- const scrollRef = (0, import_react18.useRef)(null);
7534
- (0, import_react18.useEffect)(() => {
7726
+ const scrollRef = (0, import_react20.useRef)(null);
7727
+ (0, import_react20.useEffect)(() => {
7535
7728
  if (scrollRef.current) {
7536
7729
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
7537
7730
  }
@@ -7546,60 +7739,45 @@ function TimelineAgentChatPanel({
7546
7739
  } catch {
7547
7740
  }
7548
7741
  }
7549
- const handlePermissionAllow = (0, import_react18.useCallback)((requestId, remember) => {
7742
+ const handlePermissionAllow = (0, import_react20.useCallback)((requestId, remember) => {
7550
7743
  void chat.respondToPermission(requestId, true, remember);
7551
7744
  }, [chat]);
7552
- const handlePermissionDeny = (0, import_react18.useCallback)((requestId) => {
7745
+ const handlePermissionDeny = (0, import_react20.useCallback)((requestId) => {
7553
7746
  void chat.respondToPermission(requestId, false);
7554
7747
  }, [chat]);
7555
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: `flex flex-col h-full ${className ?? ""}`, children: [
7556
- showStatusBar && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "shrink-0 border-b border-border bg-background/70 px-4 py-2 backdrop-blur", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
7557
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-2 text-[12px] text-muted-foreground", children: [
7558
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: chat.isConnected ? "text-green-500" : "text-muted-foreground", children: chat.isConnected ? "\u25CF" : "\u25CB" }),
7559
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { children: chat.isConnected ? "Connected" : chat.isReconnecting ? "Reconnecting" : "Disconnected" }),
7560
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: isWaitingPermission ? "text-yellow-500" : chat.isRunning ? "text-green-500" : "", children: isWaitingPermission ? " \u25C9 Awaiting approval" : chat.isRunning ? " \u25CF Running" : "" })
7748
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: `flex flex-col h-full ${className ?? ""}`, children: [
7749
+ showStatusBar && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "shrink-0 border-b border-border bg-background/70 px-4 py-2 backdrop-blur", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
7750
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-2 text-[12px] text-muted-foreground", children: [
7751
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: chat.isConnected ? "text-green-500" : "text-muted-foreground", children: chat.isConnected ? "\u25CF" : "\u25CB" }),
7752
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { children: chat.isConnected ? "Connected" : chat.isReconnecting ? "Reconnecting" : "Disconnected" }),
7753
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: isWaitingPermission ? "text-yellow-500" : chat.isRunning ? "text-green-500" : "", children: isWaitingPermission ? " \u25C9 Awaiting approval" : chat.isRunning ? " \u25CF Running" : "" })
7561
7754
  ] }),
7562
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "text-[12px] text-muted-foreground", children: [
7563
- chat.hasGap && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-yellow-500", children: "\u26A0 Gap detected \xB7 " }),
7755
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "text-[12px] text-muted-foreground", children: [
7756
+ chat.hasGap && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-yellow-500", children: "\u26A0 Gap detected \xB7 " }),
7564
7757
  summarizeCapability(chat.capabilityReport)
7565
7758
  ] })
7566
7759
  ] }) }),
7567
- chat.error && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "shrink-0 border-b border-border bg-red-500/[0.08] px-4 py-2 text-[13px] text-red-600", children: chat.error.message }),
7568
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex-1 min-h-0 overflow-y-auto", ref: scrollRef, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "mx-auto max-w-[760px] flex flex-col gap-4 px-4 py-6", children: [
7569
- chat.turns.length === 0 && !chat.isRunning && !isWaitingPermission && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "rounded-[8px] bg-background shadow-minimal p-5 text-[13px] text-muted-foreground", children: "Send a message to start an agent session." }),
7760
+ chat.error && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "shrink-0 border-b border-border bg-red-500/[0.08] px-4 py-2 text-[13px] text-red-600", children: chat.error.message }),
7761
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex-1 min-h-0 overflow-y-auto", ref: scrollRef, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "mx-auto max-w-[760px] flex flex-col gap-4 px-4 py-6", children: [
7762
+ chat.turns.length === 0 && !chat.isRunning && !isWaitingPermission && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "rounded-[8px] bg-background shadow-minimal p-5 text-[13px] text-muted-foreground", children: "Send a message to start an agent session." }),
7570
7763
  chat.turns.map((turn, index) => {
7571
7764
  if (turn.type === "user") {
7572
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex justify-end py-1", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(UserMessageBubble, { content: turn.message.content }) }, `user-${turn.message.id}`);
7765
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex justify-end py-1", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(UserMessageBubble, { content: turn.message.content }) }, `user-${turn.message.id}`);
7573
7766
  }
7574
7767
  if (turn.type === "assistant") {
7575
- const isLast = index === chat.turns.length - 1;
7576
- const defaultExpanded = turn.isStreaming || isLast && chat.isRunning;
7577
- const isExpanded = turnExpandOverride[turn.turnId] ?? defaultExpanded;
7578
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7579
- TurnCard,
7768
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7769
+ AssistantTurnCard,
7580
7770
  {
7581
7771
  sessionId: workspaceId,
7582
- turnId: turn.turnId,
7583
- activities: turn.activities,
7584
- response: turn.response,
7585
- intent: turn.intent,
7586
- isStreaming: turn.isStreaming,
7587
- isComplete: turn.isComplete,
7588
- isExpanded,
7589
- onExpandedChange: (expanded) => handleTurnExpandedChange(turn.turnId, expanded),
7590
- onOpenActivityDetails: setSelectedActivity,
7591
- hasEditOrWriteActivities: turn.activities.some(
7592
- (a) => a.toolName === "Edit" || a.toolName === "Write"
7593
- ),
7594
- todos: turn.todos,
7595
- isLastResponse: isLast,
7596
- displayMode: "detailed"
7772
+ turn,
7773
+ isLast: index === chat.turns.length - 1,
7774
+ onInspectActivity: setSelectedActivity
7597
7775
  },
7598
7776
  `assistant-${turn.turnId}`
7599
7777
  );
7600
7778
  }
7601
7779
  if (turn.type === "auth-request") {
7602
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7780
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7603
7781
  PermissionRequestCard,
7604
7782
  {
7605
7783
  requestId: turn.message.authRequestId ?? turn.message.id,
@@ -7614,7 +7792,7 @@ function TimelineAgentChatPanel({
7614
7792
  }
7615
7793
  return null;
7616
7794
  }),
7617
- isWaitingPermission && permissionRequest && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7795
+ isWaitingPermission && permissionRequest && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7618
7796
  PermissionRequestCard,
7619
7797
  {
7620
7798
  requestId: permissionRequest.requestId,
@@ -7627,7 +7805,7 @@ function TimelineAgentChatPanel({
7627
7805
  onDeny: handlePermissionDeny
7628
7806
  }
7629
7807
  ),
7630
- isWaitingPermission && !permissionRequest && waitingRequestId && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7808
+ isWaitingPermission && !permissionRequest && waitingRequestId && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7631
7809
  PermissionRequestCard,
7632
7810
  {
7633
7811
  requestId: waitingRequestId,
@@ -7639,9 +7817,9 @@ function TimelineAgentChatPanel({
7639
7817
  }
7640
7818
  )
7641
7819
  ] }) }),
7642
- showDetailPanel && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "shrink-0 border-t border-border bg-background/70 max-h-[260px] overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "px-4 py-3 space-y-2", children: [
7643
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "text-[12px] font-medium uppercase text-muted-foreground", children: "Runtime Details" }),
7644
- detailItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "text-[12px] text-muted-foreground", children: "No runtime details yet." }) : detailItems.slice(-10).map((item) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7820
+ showDetailPanel && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "shrink-0 border-t border-border bg-background/70 max-h-[260px] overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "px-4 py-3 space-y-2", children: [
7821
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "text-[12px] font-medium uppercase text-muted-foreground", children: "Runtime Details" }),
7822
+ detailItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "text-[12px] text-muted-foreground", children: "No runtime details yet." }) : detailItems.slice(-10).map((item) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7645
7823
  "button",
7646
7824
  {
7647
7825
  type: "button",
@@ -7652,9 +7830,9 @@ function TimelineAgentChatPanel({
7652
7830
  item.id
7653
7831
  ))
7654
7832
  ] }) }),
7655
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "shrink-0 border-t border-border", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("form", { onSubmit: handleSubmit, className: "flex flex-col gap-2 p-3", children: [
7656
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex gap-2", children: [
7657
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7833
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "shrink-0 border-t border-border", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("form", { onSubmit: handleSubmit, className: "flex flex-col gap-2 p-3", children: [
7834
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex gap-2", children: [
7835
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7658
7836
  "textarea",
7659
7837
  {
7660
7838
  value: draft,
@@ -7664,7 +7842,7 @@ function TimelineAgentChatPanel({
7664
7842
  className: "min-h-10 flex-1 resize-none rounded-[7px] border border-border bg-background px-3 py-2 text-[13px] text-foreground outline-none placeholder:text-muted-foreground focus:ring-2 focus:ring-accent"
7665
7843
  }
7666
7844
  ),
7667
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7845
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7668
7846
  "button",
7669
7847
  {
7670
7848
  type: "submit",
@@ -7673,7 +7851,7 @@ function TimelineAgentChatPanel({
7673
7851
  children: "Send"
7674
7852
  }
7675
7853
  ),
7676
- chat.isRunning && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7854
+ chat.isRunning && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7677
7855
  "button",
7678
7856
  {
7679
7857
  type: "button",
@@ -7683,24 +7861,19 @@ function TimelineAgentChatPanel({
7683
7861
  }
7684
7862
  )
7685
7863
  ] }),
7686
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("label", { className: "flex items-center gap-2 text-[12px] text-muted-foreground", children: [
7687
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "shrink-0", children: "Tool permissions" }),
7688
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
7689
- "select",
7690
- {
7691
- value: permissionMode,
7692
- onChange: (e) => setPermissionMode(e.currentTarget.value),
7693
- className: "rounded-[6px] border border-border bg-background px-2 py-1 text-[12px] text-foreground outline-none focus:ring-1 focus:ring-accent",
7694
- children: [
7695
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("option", { value: "ask", children: "Ask before each tool" }),
7696
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("option", { value: "allow-all", children: "Auto-run (no prompts)" })
7697
- ]
7698
- }
7699
- )
7700
- ] })
7864
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7865
+ PermissionModeMenu,
7866
+ {
7867
+ value: permissionMode,
7868
+ onChange: setPermissionMode,
7869
+ onClose: () => setIsPermMenuOpen(false),
7870
+ isOpen: isPermMenuOpen,
7871
+ onToggle: () => setIsPermMenuOpen((o) => !o)
7872
+ }
7873
+ )
7701
7874
  ] }) }),
7702
- selectedActivity && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7703
- ActivityDetailOverlay,
7875
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7876
+ ActivityDetailsPanel,
7704
7877
  {
7705
7878
  activity: selectedActivity,
7706
7879
  onClose: () => setSelectedActivity(null)
@@ -7708,74 +7881,6 @@ function TimelineAgentChatPanel({
7708
7881
  )
7709
7882
  ] });
7710
7883
  }
7711
- function formatActivityValue(value) {
7712
- if (value == null) return "";
7713
- if (typeof value === "string") return value;
7714
- try {
7715
- return JSON.stringify(value, null, 2);
7716
- } catch {
7717
- return String(value);
7718
- }
7719
- }
7720
- function ActivityDetailOverlay({
7721
- activity,
7722
- onClose
7723
- }) {
7724
- const title = activity.displayName || activity.toolName || activity.type;
7725
- const input = activity.toolInput && Object.keys(activity.toolInput).length > 0 ? formatActivityValue(activity.toolInput) : "";
7726
- const result = formatActivityValue(activity.content);
7727
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7728
- "div",
7729
- {
7730
- className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",
7731
- onClick: onClose,
7732
- role: "presentation",
7733
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
7734
- "div",
7735
- {
7736
- className: "flex max-h-[80vh] w-full max-w-[640px] flex-col overflow-hidden rounded-[10px] border border-border bg-background shadow-lg",
7737
- onClick: (e) => e.stopPropagation(),
7738
- role: "dialog",
7739
- "aria-modal": "true",
7740
- "aria-label": `${title} details`,
7741
- children: [
7742
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center justify-between gap-2 border-b border-border px-4 py-3", children: [
7743
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "min-w-0", children: [
7744
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "truncate text-[13px] font-medium text-foreground", children: title }),
7745
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "text-[11px] text-muted-foreground", children: [
7746
- activity.type,
7747
- " \xB7 ",
7748
- activity.status
7749
- ] })
7750
- ] }),
7751
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7752
- "button",
7753
- {
7754
- type: "button",
7755
- onClick: onClose,
7756
- className: "shrink-0 rounded-[6px] px-2 py-1 text-[12px] text-muted-foreground transition hover:bg-foreground/[0.06] hover:text-foreground",
7757
- children: "Close"
7758
- }
7759
- )
7760
- ] }),
7761
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex-1 overflow-y-auto px-4 py-3 space-y-3", children: [
7762
- activity.error && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "rounded-[6px] bg-red-500/[0.08] px-3 py-2 text-[12px] text-red-600", children: activity.error }),
7763
- input && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
7764
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground", children: "Request" }),
7765
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("pre", { className: "overflow-x-auto rounded-[6px] bg-foreground/[0.04] px-3 py-2 text-[12px] text-foreground whitespace-pre-wrap break-words", children: input })
7766
- ] }),
7767
- result && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
7768
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground", children: "Result" }),
7769
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("pre", { className: "overflow-x-auto rounded-[6px] bg-foreground/[0.04] px-3 py-2 text-[12px] text-foreground whitespace-pre-wrap break-words", children: result })
7770
- ] }),
7771
- !input && !result && !activity.error && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "text-[12px] text-muted-foreground", children: "No additional detail for this step." })
7772
- ] })
7773
- ]
7774
- }
7775
- )
7776
- }
7777
- );
7778
- }
7779
7884
 
7780
7885
  // ../runtime-core/dist/index.js
7781
7886
  var RUNTIME_KINDS = ["native-sdk", "app-server", "compatible-sdk", "cli-fallback"];
@@ -8337,13 +8442,13 @@ var PushTimelineStream = class {
8337
8442
  };
8338
8443
 
8339
8444
  // src/use-agent-session.ts
8340
- var import_react19 = require("react");
8445
+ var import_react21 = require("react");
8341
8446
  function useAgentSession(options) {
8342
- const onTokenExpiredRef = (0, import_react19.useRef)(options.onTokenExpired);
8447
+ const onTokenExpiredRef = (0, import_react21.useRef)(options.onTokenExpired);
8343
8448
  onTokenExpiredRef.current = options.onTokenExpired;
8344
- const tokenRef = (0, import_react19.useRef)(options.token);
8449
+ const tokenRef = (0, import_react21.useRef)(options.token);
8345
8450
  tokenRef.current = options.token;
8346
- const runtime = (0, import_react19.useMemo)(() => {
8451
+ const runtime = (0, import_react21.useMemo)(() => {
8347
8452
  return createDeferredAgentRuntime({
8348
8453
  provider: "flitro",
8349
8454
  runtimeKind: "app-server",
@@ -8356,7 +8461,7 @@ function useAgentSession(options) {
8356
8461
  })
8357
8462
  });
8358
8463
  }, [options.server, options.sessionId]);
8359
- (0, import_react19.useEffect)(() => {
8464
+ (0, import_react21.useEffect)(() => {
8360
8465
  return () => {
8361
8466
  void runtime.disposeIfCreated();
8362
8467
  };
@@ -8441,9 +8546,12 @@ function createDeferredAgentRuntime(options) {
8441
8546
  }
8442
8547
  // Annotate the CommonJS export names for ESM import in node:
8443
8548
  0 && (module.exports = {
8549
+ ActivityDetailsPanel,
8550
+ ActivityInspector,
8444
8551
  AgentChatPanel,
8445
8552
  AnnotationIslandMenu,
8446
8553
  AnnotationOverlayLayer,
8554
+ AssistantTurnCard,
8447
8555
  ChatTranscript,
8448
8556
  CodeBlock,
8449
8557
  CollapsibleMarkdownProvider,
@@ -8454,6 +8562,7 @@ function createDeferredAgentRuntime(options) {
8454
8562
  Markdown,
8455
8563
  MemoizedMarkdown,
8456
8564
  PendingIndicator,
8565
+ PermissionModeMenu,
8457
8566
  PermissionRequestCard,
8458
8567
  PlatformProvider,
8459
8568
  ResponseCard,