@lukeashford/aurelius 4.3.0 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -742,6 +742,20 @@ interface MessageProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'con
742
742
  * artifact-card modal in the host app.
743
743
  */
744
744
  onAttachmentOpen?: (artifactId: string) => void;
745
+ /**
746
+ * Click handler for the bubble — when provided, the message becomes a
747
+ * navigational anchor (mirrors Checkpoint's `onJumpHere`): clicking the
748
+ * bubble moves the active leaf to this node. Suppressed when `isActive`
749
+ * is true (already here) or when the user is selecting text or clicking
750
+ * a markdown link inside the bubble.
751
+ */
752
+ onJumpHere?: () => void;
753
+ /**
754
+ * When true, this message is the active leaf — `onJumpHere` is suppressed
755
+ * (no point jumping to where you already are) and the affordance hover
756
+ * styling is skipped.
757
+ */
758
+ isActive?: boolean;
745
759
  }
746
760
  declare const Message: React$1.ForwardRefExoticComponent<MessageProps & React$1.RefAttributes<HTMLDivElement>>;
747
761
 
@@ -1417,12 +1431,12 @@ interface ChatInterfaceProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>
1417
1431
  */
1418
1432
  onRetryMessage?: (messageId: string) => void;
1419
1433
  /**
1420
- * Called when the user clicks a non-active checkpoint to rewind. Receives
1421
- * the checkpoint id; the consumer should move the active leaf there
1422
- * (without forking) so the artifacts panel and chat re-anchor.
1423
- * In tree mode only.
1434
+ * Called when the user clicks a non-active node — checkpoint or message
1435
+ * to move the active leaf there. Receives the node id; the consumer should
1436
+ * move the active leaf without forking so the artifacts panel and chat
1437
+ * re-anchor. Mirrors the per-component `onJumpHere`. In tree mode only.
1424
1438
  */
1425
- onJumpToCheckpoint?: (checkpointId: string) => void;
1439
+ onJumpHere?: (nodeId: string) => void;
1426
1440
  /**
1427
1441
  * Called when the user clicks "Jump to latest" on the greyed-future divider
1428
1442
  * or otherwise asks to return to the deepest leaf they had reached.
@@ -1682,6 +1696,18 @@ interface ChatViewMessageItem extends Omit<MessageProps, 'variant' | 'children'>
1682
1696
  actions?: MessageActionsConfig;
1683
1697
  /** When true, this row is rendered in the greyed-future region. */
1684
1698
  muted?: boolean;
1699
+ /**
1700
+ * When true, this message is the active leaf — Message will suppress its
1701
+ * `onJumpHere` click target. Mirrors `ChatViewCheckpointItem.isActive`.
1702
+ */
1703
+ isActive?: boolean;
1704
+ /**
1705
+ * Click handler for the bubble. When provided, the bubble becomes a
1706
+ * navigational anchor that moves the active leaf to this node. Aurelius
1707
+ * suppresses the click for `isActive` rows, link / button targets inside
1708
+ * the bubble, and active text selections.
1709
+ */
1710
+ onJumpHere?: () => void;
1685
1711
  }
1686
1712
  interface ChatViewCheckpointItem extends CheckpointProps {
1687
1713
  kind: 'checkpoint';
package/dist/index.d.ts CHANGED
@@ -742,6 +742,20 @@ interface MessageProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'con
742
742
  * artifact-card modal in the host app.
743
743
  */
744
744
  onAttachmentOpen?: (artifactId: string) => void;
745
+ /**
746
+ * Click handler for the bubble — when provided, the message becomes a
747
+ * navigational anchor (mirrors Checkpoint's `onJumpHere`): clicking the
748
+ * bubble moves the active leaf to this node. Suppressed when `isActive`
749
+ * is true (already here) or when the user is selecting text or clicking
750
+ * a markdown link inside the bubble.
751
+ */
752
+ onJumpHere?: () => void;
753
+ /**
754
+ * When true, this message is the active leaf — `onJumpHere` is suppressed
755
+ * (no point jumping to where you already are) and the affordance hover
756
+ * styling is skipped.
757
+ */
758
+ isActive?: boolean;
745
759
  }
746
760
  declare const Message: React$1.ForwardRefExoticComponent<MessageProps & React$1.RefAttributes<HTMLDivElement>>;
747
761
 
@@ -1417,12 +1431,12 @@ interface ChatInterfaceProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>
1417
1431
  */
1418
1432
  onRetryMessage?: (messageId: string) => void;
1419
1433
  /**
1420
- * Called when the user clicks a non-active checkpoint to rewind. Receives
1421
- * the checkpoint id; the consumer should move the active leaf there
1422
- * (without forking) so the artifacts panel and chat re-anchor.
1423
- * In tree mode only.
1434
+ * Called when the user clicks a non-active node — checkpoint or message
1435
+ * to move the active leaf there. Receives the node id; the consumer should
1436
+ * move the active leaf without forking so the artifacts panel and chat
1437
+ * re-anchor. Mirrors the per-component `onJumpHere`. In tree mode only.
1424
1438
  */
1425
- onJumpToCheckpoint?: (checkpointId: string) => void;
1439
+ onJumpHere?: (nodeId: string) => void;
1426
1440
  /**
1427
1441
  * Called when the user clicks "Jump to latest" on the greyed-future divider
1428
1442
  * or otherwise asks to return to the deepest leaf they had reached.
@@ -1682,6 +1696,18 @@ interface ChatViewMessageItem extends Omit<MessageProps, 'variant' | 'children'>
1682
1696
  actions?: MessageActionsConfig;
1683
1697
  /** When true, this row is rendered in the greyed-future region. */
1684
1698
  muted?: boolean;
1699
+ /**
1700
+ * When true, this message is the active leaf — Message will suppress its
1701
+ * `onJumpHere` click target. Mirrors `ChatViewCheckpointItem.isActive`.
1702
+ */
1703
+ isActive?: boolean;
1704
+ /**
1705
+ * Click handler for the bubble. When provided, the bubble becomes a
1706
+ * navigational anchor that moves the active leaf to this node. Aurelius
1707
+ * suppresses the click for `isActive` rows, link / button targets inside
1708
+ * the bubble, and active text selections.
1709
+ */
1710
+ onJumpHere?: () => void;
1685
1711
  }
1686
1712
  interface ChatViewCheckpointItem extends CheckpointProps {
1687
1713
  kind: 'checkpoint';
package/dist/index.js CHANGED
@@ -1498,12 +1498,12 @@ var statusBorderClass = {
1498
1498
  };
1499
1499
  var statusHoverLabel = {
1500
1500
  pending: null,
1501
- uploading: "Uploading...",
1502
- uploaded: "Upload complete. Analyzing...",
1503
- analyzing: "Upload complete. Analyzing...",
1501
+ uploading: "Uploading",
1502
+ uploaded: "Analyzing",
1503
+ analyzing: "Analyzing",
1504
1504
  analyzed: null,
1505
- upload_failed: "Upload failed. Remove and try again.",
1506
- analysis_failed: "Analysis failed. Provide a description in your next message."
1505
+ upload_failed: "Upload failed",
1506
+ analysis_failed: "Couldn't process this file"
1507
1507
  };
1508
1508
  function isErrorStatus(status) {
1509
1509
  return status === "upload_failed" || status === "analysis_failed";
@@ -1529,7 +1529,9 @@ var FileChip = import_react16.default.forwardRef(
1529
1529
  const showPreview = isImage && previewUrl;
1530
1530
  const clickable = !!(artifactId && onOpen);
1531
1531
  const hoverLabel = statusHoverLabel[status];
1532
- const tooltip = title ?? hoverLabel ?? name;
1532
+ const tooltipContent = isErrorStatus(status) ? error ?? hoverLabel ?? null : hoverLabel;
1533
+ const [hovered, setHovered] = (0, import_react16.useState)(false);
1534
+ const [focused, setFocused] = (0, import_react16.useState)(false);
1533
1535
  const showError = isErrorStatus(status);
1534
1536
  const handleClick = () => {
1535
1537
  if (clickable) {
@@ -1545,7 +1547,8 @@ var FileChip = import_react16.default.forwardRef(
1545
1547
  onOpen(artifactId);
1546
1548
  }
1547
1549
  };
1548
- return /* @__PURE__ */ import_react16.default.createElement(
1550
+ const tooltipOpen = tooltipContent !== null && (hovered || focused);
1551
+ const chip = /* @__PURE__ */ import_react16.default.createElement(
1549
1552
  "div",
1550
1553
  {
1551
1554
  ...rest,
@@ -1563,7 +1566,11 @@ var FileChip = import_react16.default.forwardRef(
1563
1566
  tabIndex: clickable ? 0 : void 0,
1564
1567
  onClick: clickable ? handleClick : void 0,
1565
1568
  onKeyDown: clickable ? handleKeyDown : void 0,
1566
- title: tooltip,
1569
+ onMouseEnter: () => setHovered(true),
1570
+ onMouseLeave: () => setHovered(false),
1571
+ onFocus: () => setFocused(true),
1572
+ onBlur: () => setFocused(false),
1573
+ title,
1567
1574
  "aria-label": hoverLabel ? `${name}: ${hoverLabel}` : name
1568
1575
  },
1569
1576
  showPreview ? /* @__PURE__ */ import_react16.default.createElement("div", { className: "w-8 h-8 flex-shrink-0 overflow-hidden bg-slate" }, /* @__PURE__ */ import_react16.default.createElement(
@@ -1600,6 +1607,10 @@ var FileChip = import_react16.default.forwardRef(
1600
1607
  /* @__PURE__ */ import_react16.default.createElement(import_lucide_react2.X, { className: "w-3.5 h-3.5" })
1601
1608
  )
1602
1609
  );
1610
+ if (tooltipContent === null) {
1611
+ return chip;
1612
+ }
1613
+ return /* @__PURE__ */ import_react16.default.createElement(Tooltip, { content: tooltipContent, open: tooltipOpen, side: "top" }, chip);
1603
1614
  }
1604
1615
  );
1605
1616
  FileChip.displayName = "FileChip";
@@ -4097,9 +4108,26 @@ var Message = import_react56.default.forwardRef(
4097
4108
  hideActions,
4098
4109
  attachments,
4099
4110
  onAttachmentOpen,
4111
+ onJumpHere,
4112
+ isActive,
4100
4113
  ...rest
4101
4114
  }, ref) => {
4102
4115
  const isUser = variant === "user";
4116
+ const isJumpInteractive = !!onJumpHere && !isActive && !isStreaming;
4117
+ const handleBubbleClick = (0, import_react56.useCallback)((e) => {
4118
+ if (!isJumpInteractive) {
4119
+ return;
4120
+ }
4121
+ const target = e.target;
4122
+ if (target.closest("a, button")) {
4123
+ return;
4124
+ }
4125
+ const selection = typeof window !== "undefined" ? window.getSelection() : null;
4126
+ if (selection && !selection.isCollapsed) {
4127
+ return;
4128
+ }
4129
+ onJumpHere();
4130
+ }, [isJumpInteractive, onJumpHere]);
4103
4131
  const { copied, copy } = useCopyToClipboard();
4104
4132
  const [isEditing, setIsEditing] = (0, import_react56.useState)(false);
4105
4133
  const [editValue, setEditValue] = (0, import_react56.useState)(typeof content === "string" ? content : "");
@@ -4206,8 +4234,12 @@ var Message = import_react56.default.forwardRef(
4206
4234
  {
4207
4235
  className: cx(
4208
4236
  "px-3 py-2 w-fit max-w-11/12",
4209
- VARIANT_STYLES3[variant]
4210
- )
4237
+ VARIANT_STYLES3[variant],
4238
+ isJumpInteractive && "cursor-pointer hover:brightness-110 transition-all duration-150"
4239
+ ),
4240
+ onClick: isJumpInteractive ? handleBubbleClick : void 0,
4241
+ role: isJumpInteractive ? "button" : void 0,
4242
+ "aria-label": isJumpInteractive ? "Jump to this message" : void 0
4211
4243
  },
4212
4244
  typeof content === "string" ? /* @__PURE__ */ import_react56.default.createElement(
4213
4245
  MarkdownContent,
@@ -6943,7 +6975,7 @@ var ChatInterface = import_react81.default.forwardRef(
6943
6975
  onMessageSubmit,
6944
6976
  onEditMessage,
6945
6977
  onRetryMessage,
6946
- onJumpToCheckpoint,
6978
+ onJumpHere,
6947
6979
  onJumpToLatest,
6948
6980
  onStop,
6949
6981
  onSelectConversation,
@@ -7119,16 +7151,16 @@ var ChatInterface = import_react81.default.forwardRef(
7119
7151
  },
7120
7152
  [tree, onTreeChange]
7121
7153
  );
7122
- const handleJumpToCheckpoint = (0, import_react81.useCallback)((checkpointId) => {
7154
+ const handleJumpHere = (0, import_react81.useCallback)((nodeId) => {
7123
7155
  if (!tree) return;
7124
- if (onJumpToCheckpoint) {
7125
- onJumpToCheckpoint(checkpointId);
7156
+ if (onJumpHere) {
7157
+ onJumpHere(nodeId);
7126
7158
  return;
7127
7159
  }
7128
7160
  if (onTreeChange) {
7129
- onTreeChange(setActiveLeaf(tree, checkpointId));
7161
+ onTreeChange(setActiveLeaf(tree, nodeId));
7130
7162
  }
7131
- }, [tree, onTreeChange, onJumpToCheckpoint]);
7163
+ }, [tree, onTreeChange, onJumpHere]);
7132
7164
  const handleJumpToLatest = (0, import_react81.useCallback)(() => {
7133
7165
  if (!tree) return;
7134
7166
  if (onJumpToLatest) {
@@ -7156,7 +7188,7 @@ var ChatInterface = import_react81.default.forwardRef(
7156
7188
  isActive: node.id === activeCheckpointId && !opts.muted,
7157
7189
  muted: opts.muted,
7158
7190
  branchInfo,
7159
- onJumpHere: () => handleJumpToCheckpoint(node.id)
7191
+ onJumpHere: () => handleJumpHere(node.id)
7160
7192
  };
7161
7193
  }
7162
7194
  const actions = enableMessageActions ? {
@@ -7164,6 +7196,7 @@ var ChatInterface = import_react81.default.forwardRef(
7164
7196
  onEdit: node.role === "user" && onEditMessage ? (newContent) => onEditMessage(node.id, newContent) : void 0,
7165
7197
  onRetry: node.role === "assistant" && onRetryMessage ? () => onRetryMessage(node.id) : void 0
7166
7198
  } : void 0;
7199
+ const isActiveLeaf = tree?.activeLeafId === node.id;
7167
7200
  return {
7168
7201
  kind: "message",
7169
7202
  id: node.id,
@@ -7180,7 +7213,9 @@ var ChatInterface = import_react81.default.forwardRef(
7180
7213
  artifactId: a.artifactId,
7181
7214
  status: a.status ?? "analyzed"
7182
7215
  })) : void 0,
7183
- onAttachmentOpen: handleAttachmentOpen
7216
+ onAttachmentOpen: handleAttachmentOpen,
7217
+ isActive: isActiveLeaf,
7218
+ onJumpHere: () => handleJumpHere(node.id)
7184
7219
  };
7185
7220
  },
7186
7221
  [
@@ -7190,7 +7225,7 @@ var ChatInterface = import_react81.default.forwardRef(
7190
7225
  onEditMessage,
7191
7226
  onRetryMessage,
7192
7227
  handleBranchSwitch,
7193
- handleJumpToCheckpoint,
7228
+ handleJumpHere,
7194
7229
  handleAttachmentOpen
7195
7230
  ]
7196
7231
  );