@ggui-ai/dev-stack 0.26.0 → 0.28.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.
@@ -21210,7 +21210,7 @@ function resolveToneCss(tone) {
21210
21210
  case "muted":
21211
21211
  return "var(--ggui-color-onSunken, #52525b)";
21212
21212
  case "subtle":
21213
- return "var(--ggui-color-neutral-500, #71717a)";
21213
+ return "var(--ggui-color-onSunken, #52525b)";
21214
21214
  case "emphasized":
21215
21215
  return "var(--ggui-color-link, var(--ggui-color-primary-700, #0369a1))";
21216
21216
  case "loud":
@@ -27656,11 +27656,11 @@ function FormField({ label, children, error, helperText, required, description,
27656
27656
  color: "var(--ggui-color-onContainer, #374151)"
27657
27657
  }, children: [label, required && (0, import_jsx_runtime32.jsx)("span", { style: { color: "var(--ggui-color-error-500, #ef4444)", marginLeft: "2px" }, children: "*" })] }), description && (0, import_jsx_runtime32.jsx)("span", { style: {
27658
27658
  fontSize: fontSize.xs,
27659
- color: "var(--ggui-color-neutral-500, #6b7280)",
27659
+ color: resolveToneCss("subtle"),
27660
27660
  marginBottom: "4px"
27661
27661
  }, children: description }), children, (error || helperText) && (0, import_jsx_runtime32.jsx)("span", { style: {
27662
27662
  fontSize: fontSize.xs,
27663
- color: hasError ? "var(--ggui-color-error-500, #ef4444)" : "var(--ggui-color-neutral-500, #6b7280)"
27663
+ color: hasError ? "var(--ggui-color-error-500, #ef4444)" : resolveToneCss("subtle")
27664
27664
  }, children: error || helperText })] });
27665
27665
  }
27666
27666
  function MenuItem({ label, icon, rightElement, onClick, disabled, active, danger, style, className }) {
@@ -27892,7 +27892,7 @@ function Autocomplete({ value = "", onChange, onSelect, options, placeholder, la
27892
27892
  }, children: loading ? (0, import_jsx_runtime36.jsx)("div", { style: { padding: "12px", display: "flex", justifyContent: "center" }, children: (0, import_jsx_runtime36.jsx)(Spinner, { size: 20 }) }) : filteredOptions.length === 0 ? (0, import_jsx_runtime36.jsx)("div", { style: {
27893
27893
  padding: "12px",
27894
27894
  textAlign: "center",
27895
- color: "var(--ggui-color-neutral-500, #6b7280)",
27895
+ color: resolveToneCss("subtle"),
27896
27896
  fontSize: fontSize.sm
27897
27897
  }, children: noResultsText }) : filteredOptions.map((option, index) => (0, import_jsx_runtime36.jsxs)("div", { onClick: () => !option.disabled && handleSelect(option), style: {
27898
27898
  padding: "8px 12px",
@@ -27903,7 +27903,7 @@ function Autocomplete({ value = "", onChange, onSelect, options, placeholder, la
27903
27903
  display: "flex",
27904
27904
  alignItems: "center",
27905
27905
  gap: "8px"
27906
- }, onMouseEnter: () => setHighlightedIndex(index), children: [option.icon && (0, import_jsx_runtime36.jsx)("span", { style: { flexShrink: 0 }, children: option.icon }), (0, import_jsx_runtime36.jsxs)("div", { style: { flex: 1 }, children: [(0, import_jsx_runtime36.jsx)("div", { children: option.label }), option.description && (0, import_jsx_runtime36.jsx)("div", { style: { fontSize: fontSize.xs, color: "var(--ggui-color-neutral-500, #6b7280)" }, children: option.description })] })] }, option.value)) })] });
27906
+ }, onMouseEnter: () => setHighlightedIndex(index), children: [option.icon && (0, import_jsx_runtime36.jsx)("span", { style: { flexShrink: 0 }, children: option.icon }), (0, import_jsx_runtime36.jsxs)("div", { style: { flex: 1 }, children: [(0, import_jsx_runtime36.jsx)("div", { children: option.label }), option.description && (0, import_jsx_runtime36.jsx)("div", { style: { fontSize: fontSize.xs, color: resolveToneCss("subtle") }, children: option.description })] })] }, option.value)) })] });
27907
27907
  }
27908
27908
  function Breadcrumb({ items, separator = "/", onItemClick, style, className }) {
27909
27909
  return (0, import_jsx_runtime37.jsx)("nav", { "aria-label": "Breadcrumb", className, style: {
@@ -27917,7 +27917,7 @@ function Breadcrumb({ items, separator = "/", onItemClick, style, className }) {
27917
27917
  return (0, import_jsx_runtime37.jsxs)(import_react33.Fragment, { children: [index > 0 && (0, import_jsx_runtime37.jsx)("span", { style: { color: "var(--ggui-color-neutral-400, #9ca3af)" }, children: separator }), item.icon && (0, import_jsx_runtime37.jsx)("span", { style: {
27918
27918
  display: "flex",
27919
27919
  alignItems: "center",
27920
- color: isLast ? "var(--ggui-color-onContainer, #111827)" : "var(--ggui-color-neutral-500, #6b7280)"
27920
+ color: isLast ? "var(--ggui-color-onContainer, #111827)" : resolveToneCss("subtle")
27921
27921
  }, children: item.icon }), isLast ? (0, import_jsx_runtime37.jsx)("span", { style: {
27922
27922
  color: "var(--ggui-color-onContainer, #111827)",
27923
27923
  fontWeight: 500
@@ -27930,7 +27930,7 @@ function Breadcrumb({ items, separator = "/", onItemClick, style, className }) {
27930
27930
  background: "none",
27931
27931
  border: "none",
27932
27932
  padding: 0,
27933
- color: "var(--ggui-color-neutral-500, #6b7280)",
27933
+ color: resolveToneCss("subtle"),
27934
27934
  cursor: "pointer",
27935
27935
  fontSize: "inherit"
27936
27936
  }, children: item.label })] }, index);
@@ -28641,7 +28641,7 @@ function CommentItem({ comment, onReply, onReaction, depth = 0 }) {
28641
28641
  }
28642
28642
  };
28643
28643
  const timestamp = comment.timestamp instanceof Date ? comment.timestamp.toLocaleString() : comment.timestamp;
28644
- return (0, import_jsx_runtime46.jsxs)("div", { style: { marginLeft: depth > 0 ? "40px" : 0 }, children: [(0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", gap: "12px" }, children: [(0, import_jsx_runtime46.jsx)(Avatar, { name: comment.author.name, src: comment.author.avatar, size: "sm" }), (0, import_jsx_runtime46.jsxs)("div", { style: { flex: 1 }, children: [(0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [(0, import_jsx_runtime46.jsx)("span", { style: { fontWeight: 500, fontSize: fontSize.sm }, children: comment.author.name }), (0, import_jsx_runtime46.jsx)("span", { style: { color: "var(--ggui-color-neutral-500, #6b7280)", fontSize: fontSize.xs }, children: timestamp })] }), (0, import_jsx_runtime46.jsx)("p", { style: { margin: "4px 0 8px", fontSize: fontSize.sm, color: "var(--ggui-color-onContainer, #374151)" }, children: comment.content }), (0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [comment.reactions?.map((reaction) => (0, import_jsx_runtime46.jsxs)("button", { onClick: () => onReaction?.(comment.id, reaction.emoji), style: {
28644
+ return (0, import_jsx_runtime46.jsxs)("div", { style: { marginLeft: depth > 0 ? "40px" : 0 }, children: [(0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", gap: "12px" }, children: [(0, import_jsx_runtime46.jsx)(Avatar, { name: comment.author.name, src: comment.author.avatar, size: "sm" }), (0, import_jsx_runtime46.jsxs)("div", { style: { flex: 1 }, children: [(0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [(0, import_jsx_runtime46.jsx)("span", { style: { fontWeight: 500, fontSize: fontSize.sm }, children: comment.author.name }), (0, import_jsx_runtime46.jsx)("span", { style: { color: resolveToneCss("subtle"), fontSize: fontSize.xs }, children: timestamp })] }), (0, import_jsx_runtime46.jsx)("p", { style: { margin: "4px 0 8px", fontSize: fontSize.sm, color: "var(--ggui-color-onContainer, #374151)" }, children: comment.content }), (0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [comment.reactions?.map((reaction) => (0, import_jsx_runtime46.jsxs)("button", { onClick: () => onReaction?.(comment.id, reaction.emoji), style: {
28645
28645
  padding: "2px 8px",
28646
28646
  border: `1px solid var(--ggui-color-outlineVariant, #e5e7eb)`,
28647
28647
  borderRadius: "12px",
@@ -28651,7 +28651,7 @@ function CommentItem({ comment, onReply, onReaction, depth = 0 }) {
28651
28651
  }, children: [reaction.emoji, " ", reaction.count] }, reaction.emoji)), (0, import_jsx_runtime46.jsx)("button", { onClick: () => setShowReplyInput(!showReplyInput), style: {
28652
28652
  background: "none",
28653
28653
  border: "none",
28654
- color: "var(--ggui-color-neutral-500, #6b7280)",
28654
+ color: resolveToneCss("subtle"),
28655
28655
  fontSize: fontSize.xs,
28656
28656
  cursor: "pointer"
28657
28657
  }, children: "Reply" })] }), showReplyInput && (0, import_jsx_runtime46.jsxs)("div", { style: { marginTop: "12px" }, children: [(0, import_jsx_runtime46.jsx)(TextArea, { value: replyContent, onChange: setReplyContent, placeholder: "Write a reply...", rows: 2 }), (0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", gap: "8px", marginTop: "8px" }, children: [(0, import_jsx_runtime46.jsx)(Button, { size: "sm", onClick: handleSubmitReply, children: "Reply" }), (0, import_jsx_runtime46.jsx)(Button, { size: "sm", variant: "ghost", onClick: () => setShowReplyInput(false), children: "Cancel" })] })] })] })] }), comment.replies?.map((reply) => (0, import_jsx_runtime46.jsx)("div", { style: { marginTop: "16px" }, children: (0, import_jsx_runtime46.jsx)(CommentItem, { comment: reply, onReply, onReaction, depth: depth + 1 }) }, reply.id))] });
@@ -28706,7 +28706,7 @@ function DataTable({ columns, data, rowKey = "id", loading, emptyText = "No data
28706
28706
  borderBottom: "1px solid var(--ggui-color-outlineVariant, #e5e7eb)",
28707
28707
  cursor: col.sortable ? "pointer" : void 0,
28708
28708
  width: col.width
28709
- }, onClick: () => col.sortable && onSort?.(col.key, sortKey === col.key && sortDirection === "asc" ? "desc" : "asc"), children: (0, import_jsx_runtime47.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [col.header, col.sortable && sortKey === col.key && (0, import_jsx_runtime47.jsx)(Icon, { name: sortDirection === "asc" ? "chevron-up" : "chevron-down", size: 14 })] }) }, col.key))] }) }), (0, import_jsx_runtime47.jsx)("tbody", { children: loading ? (0, import_jsx_runtime47.jsx)("tr", { children: (0, import_jsx_runtime47.jsx)("td", { colSpan: columns.length + (selectable ? 1 : 0), style: { padding: "48px", textAlign: "center" }, children: (0, import_jsx_runtime47.jsx)(Spinner, { size: 24 }) }) }) : data.length === 0 ? (0, import_jsx_runtime47.jsx)("tr", { children: (0, import_jsx_runtime47.jsx)("td", { colSpan: columns.length + (selectable ? 1 : 0), style: { padding: "48px", textAlign: "center", color: "var(--ggui-color-neutral-500, #6b7280)" }, children: emptyText }) }) : data.map((row, index) => {
28709
+ }, onClick: () => col.sortable && onSort?.(col.key, sortKey === col.key && sortDirection === "asc" ? "desc" : "asc"), children: (0, import_jsx_runtime47.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [col.header, col.sortable && sortKey === col.key && (0, import_jsx_runtime47.jsx)(Icon, { name: sortDirection === "asc" ? "chevron-up" : "chevron-down", size: 14 })] }) }, col.key))] }) }), (0, import_jsx_runtime47.jsx)("tbody", { children: loading ? (0, import_jsx_runtime47.jsx)("tr", { children: (0, import_jsx_runtime47.jsx)("td", { colSpan: columns.length + (selectable ? 1 : 0), style: { padding: "48px", textAlign: "center" }, children: (0, import_jsx_runtime47.jsx)(Spinner, { size: 24 }) }) }) : data.length === 0 ? (0, import_jsx_runtime47.jsx)("tr", { children: (0, import_jsx_runtime47.jsx)("td", { colSpan: columns.length + (selectable ? 1 : 0), style: { padding: "48px", textAlign: "center", color: resolveToneCss("subtle") }, children: emptyText }) }) : data.map((row, index) => {
28710
28710
  const key = getRowKey(row, index);
28711
28711
  const isSelected = selectedKeys.includes(key);
28712
28712
  return (0, import_jsx_runtime47.jsxs)("tr", { onClick: () => onRowClick?.(row, index), style: {
@@ -28783,7 +28783,7 @@ function ChatWindow({ messages, currentUserId, onSendMessage, loading, typing, p
28783
28783
  // takes the muted tier itself (ggui#1566).
28784
28784
  ...isOwn ? { opacity: 0.7 } : { color: "var(--ggui-color-onSunken, #52525b)" }
28785
28785
  }, children: [(0, import_jsx_runtime48.jsx)("span", { children: timestamp }), isOwn && message.status && (0, import_jsx_runtime48.jsxs)("span", { children: [message.status === "sending" && "\u2022", message.status === "sent" && "\u2713", message.status === "delivered" && "\u2713\u2713", message.status === "read" && "\u2713\u2713", message.status === "error" && "!"] })] })] })] }, message.id);
28786
- }), typing && (0, import_jsx_runtime48.jsx)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: (0, import_jsx_runtime48.jsxs)("span", { style: { fontSize: fontSize.xs, color: "var(--ggui-color-neutral-500, #6b7280)" }, children: [typing.name, " is typing..."] }) }), (0, import_jsx_runtime48.jsx)("div", { ref: messagesEndRef })] }), (0, import_jsx_runtime48.jsxs)("div", { style: {
28786
+ }), typing && (0, import_jsx_runtime48.jsx)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: (0, import_jsx_runtime48.jsxs)("span", { style: { fontSize: fontSize.xs, color: resolveToneCss("subtle") }, children: [typing.name, " is typing..."] }) }), (0, import_jsx_runtime48.jsx)("div", { ref: messagesEndRef })] }), (0, import_jsx_runtime48.jsxs)("div", { style: {
28787
28787
  padding: "12px 16px",
28788
28788
  borderTop: `1px solid var(--ggui-color-outlineVariant, #e5e7eb)`,
28789
28789
  display: "flex",
@@ -28904,7 +28904,7 @@ function FileUploader({ files = [], onFilesSelected, onFileRemove, accept, multi
28904
28904
  cursor: disabled ? "not-allowed" : "pointer",
28905
28905
  transition: "all 0.2s",
28906
28906
  opacity: disabled ? 0.5 : 1
28907
- }, children: [(0, import_jsx_runtime50.jsx)("input", { ref: inputRef, type: "file", accept, multiple, onChange: (e) => handleFiles(e.target.files), disabled, style: { display: "none" } }), (0, import_jsx_runtime50.jsx)(Icon, { name: "plus", size: 32, tone: "subtle" }), (0, import_jsx_runtime50.jsx)("p", { style: { margin: "12px 0 4px", color: "var(--ggui-color-onContainer, #374151)", fontSize: fontSize.sm }, children: dragDrop ? "Drag and drop files here, or click to browse" : "Click to browse files" }), (0, import_jsx_runtime50.jsxs)("p", { style: { margin: 0, color: "var(--ggui-color-neutral-500, #6b7280)", fontSize: fontSize.xs }, children: [accept && `Accepted: ${accept}`, maxSize && ` \u2022 Max size: ${formatFileSize(maxSize)}`, maxFiles && ` \u2022 Max files: ${maxFiles}`] })] }), files.length > 0 && (0, import_jsx_runtime50.jsx)("div", { style: { marginTop: "16px", display: "flex", flexDirection: "column", gap: "8px" }, children: files.map((file) => (0, import_jsx_runtime50.jsxs)("div", { style: {
28907
+ }, children: [(0, import_jsx_runtime50.jsx)("input", { ref: inputRef, type: "file", accept, multiple, onChange: (e) => handleFiles(e.target.files), disabled, style: { display: "none" } }), (0, import_jsx_runtime50.jsx)(Icon, { name: "plus", size: 32, tone: "subtle" }), (0, import_jsx_runtime50.jsx)("p", { style: { margin: "12px 0 4px", color: "var(--ggui-color-onContainer, #374151)", fontSize: fontSize.sm }, children: dragDrop ? "Drag and drop files here, or click to browse" : "Click to browse files" }), (0, import_jsx_runtime50.jsxs)("p", { style: { margin: 0, color: resolveToneCss("subtle"), fontSize: fontSize.xs }, children: [accept && `Accepted: ${accept}`, maxSize && ` \u2022 Max size: ${formatFileSize(maxSize)}`, maxFiles && ` \u2022 Max files: ${maxFiles}`] })] }), files.length > 0 && (0, import_jsx_runtime50.jsx)("div", { style: { marginTop: "16px", display: "flex", flexDirection: "column", gap: "8px" }, children: files.map((file) => (0, import_jsx_runtime50.jsxs)("div", { style: {
28908
28908
  display: "flex",
28909
28909
  alignItems: "center",
28910
28910
  gap: "12px",
@@ -28919,7 +28919,7 @@ function FileUploader({ files = [], onFilesSelected, onFileRemove, accept, multi
28919
28919
  whiteSpace: "nowrap",
28920
28920
  overflow: "hidden",
28921
28921
  textOverflow: "ellipsis"
28922
- }, children: file.name }), (0, import_jsx_runtime50.jsxs)("p", { style: { margin: "2px 0 0", fontSize: fontSize.xs, color: "var(--ggui-color-neutral-500, #6b7280)" }, children: [formatFileSize(file.size), file.error && (0, import_jsx_runtime50.jsx)("span", { style: { color: "var(--ggui-color-error-500, #ef4444)", marginLeft: "8px" }, children: file.error })] }), file.status === "uploading" && file.progress !== void 0 && (0, import_jsx_runtime50.jsx)(Progress, { value: file.progress, size: "sm", style: { marginTop: "8px" } })] }), (0, import_jsx_runtime50.jsx)(Button, { variant: "ghost", size: "sm", onClick: () => onFileRemove?.(file.id), children: (0, import_jsx_runtime50.jsx)(Icon, { name: "x", size: 16 }) })] }, file.id)) })] });
28922
+ }, children: file.name }), (0, import_jsx_runtime50.jsxs)("p", { style: { margin: "2px 0 0", fontSize: fontSize.xs, color: resolveToneCss("subtle") }, children: [formatFileSize(file.size), file.error && (0, import_jsx_runtime50.jsx)("span", { style: { color: "var(--ggui-color-error-500, #ef4444)", marginLeft: "8px" }, children: file.error })] }), file.status === "uploading" && file.progress !== void 0 && (0, import_jsx_runtime50.jsx)(Progress, { value: file.progress, size: "sm", style: { marginTop: "8px" } })] }), (0, import_jsx_runtime50.jsx)(Button, { variant: "ghost", size: "sm", onClick: () => onFileRemove?.(file.id), children: (0, import_jsx_runtime50.jsx)(Icon, { name: "x", size: 16 }) })] }, file.id)) })] });
28923
28923
  }
28924
28924
  var variantColors2 = {
28925
28925
  info: "var(--ggui-color-info-500, #06b6d4)",
@@ -28934,7 +28934,10 @@ function NotificationItem({ notification, onMarkAsRead, onDismiss }) {
28934
28934
  display: "flex",
28935
28935
  gap: "12px",
28936
28936
  padding: "12px",
28937
- backgroundColor: notification.read ? "transparent" : "var(--ggui-color-primaryContainer, #f0f9ff)",
28937
+ // Unread is carried by the dot and the title's weight; the row takes the
28938
+ // ground its muted text is measured on (ggui#1567), not a raised accent
28939
+ // ground where that text falls under AA in dark themes.
28940
+ backgroundColor: notification.read ? "transparent" : "var(--ggui-color-sunken, #f4f4f5)",
28938
28941
  borderRadius: radius.md,
28939
28942
  transition: "background-color 0.15s"
28940
28943
  }, children: [(0, import_jsx_runtime51.jsx)("div", { style: {
@@ -28960,7 +28963,7 @@ function NotificationItem({ notification, onMarkAsRead, onDismiss }) {
28960
28963
  margin: "4px 0 0",
28961
28964
  color: "var(--ggui-color-onSunken, #4b5563)",
28962
28965
  fontSize: fontSize.xs
28963
- }, children: notification.message }), (0, import_jsx_runtime51.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px", marginTop: "8px" }, children: [(0, import_jsx_runtime51.jsx)("span", { style: { color: "var(--ggui-color-neutral-400, #9ca3af)", fontSize: fontSize.xs }, children: timestamp }), !notification.read && (0, import_jsx_runtime51.jsx)("button", { onClick: () => onMarkAsRead?.(notification.id), style: {
28966
+ }, children: notification.message }), (0, import_jsx_runtime51.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px", marginTop: "8px" }, children: [(0, import_jsx_runtime51.jsx)("span", { style: { color: resolveToneCss("subtle"), fontSize: fontSize.xs }, children: timestamp }), !notification.read && (0, import_jsx_runtime51.jsx)("button", { onClick: () => onMarkAsRead?.(notification.id), style: {
28964
28967
  background: "none",
28965
28968
  border: "none",
28966
28969
  padding: 0,
@@ -28995,7 +28998,7 @@ function NotificationCenter({ notifications, onMarkAsRead, onMarkAllAsRead, onDi
28995
28998
  color: "var(--ggui-color-onPrimaryContainer, #0369a1)",
28996
28999
  fontSize: fontSize.xs,
28997
29000
  fontWeight: fontWeight.medium
28998
- }, children: unreadCount })] }), (0, import_jsx_runtime51.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [unreadCount > 0 && (0, import_jsx_runtime51.jsx)(Button, { variant: "ghost", size: "sm", onClick: onMarkAllAsRead, children: "Mark all read" }), notifications.length > 0 && (0, import_jsx_runtime51.jsx)(Button, { variant: "ghost", size: "sm", onClick: onClearAll, children: "Clear all" })] })] }), (0, import_jsx_runtime51.jsx)("div", { style: { flex: 1, overflowY: "auto", padding: "8px" }, children: loading ? (0, import_jsx_runtime51.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: (0, import_jsx_runtime51.jsx)(Spinner, { size: 24 }) }) : notifications.length === 0 ? (0, import_jsx_runtime51.jsx)("div", { style: { textAlign: "center", padding: "32px", color: "var(--ggui-color-neutral-500, #6b7280)" }, children: emptyText }) : (0, import_jsx_runtime51.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: notifications.map((notification) => (0, import_jsx_runtime51.jsx)(NotificationItem, { notification, onMarkAsRead, onDismiss }, notification.id)) }) })] });
29001
+ }, children: unreadCount })] }), (0, import_jsx_runtime51.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [unreadCount > 0 && (0, import_jsx_runtime51.jsx)(Button, { variant: "ghost", size: "sm", onClick: onMarkAllAsRead, children: "Mark all read" }), notifications.length > 0 && (0, import_jsx_runtime51.jsx)(Button, { variant: "ghost", size: "sm", onClick: onClearAll, children: "Clear all" })] })] }), (0, import_jsx_runtime51.jsx)("div", { style: { flex: 1, overflowY: "auto", padding: "8px" }, children: loading ? (0, import_jsx_runtime51.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: (0, import_jsx_runtime51.jsx)(Spinner, { size: 24 }) }) : notifications.length === 0 ? (0, import_jsx_runtime51.jsx)("div", { style: { textAlign: "center", padding: "32px", color: resolveToneCss("subtle") }, children: emptyText }) : (0, import_jsx_runtime51.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: notifications.map((notification) => (0, import_jsx_runtime51.jsx)(NotificationItem, { notification, onMarkAsRead, onDismiss }, notification.id)) }) })] });
28999
29002
  }
29000
29003
  var sizeWidths = {
29001
29004
  sm: "400px",
@@ -29177,11 +29180,11 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
29177
29180
  fontSize: fontSize.base,
29178
29181
  outline: "none",
29179
29182
  backgroundColor: "transparent"
29180
- } })] }) }), (0, import_jsx_runtime53.jsx)("div", { style: { flex: 1, overflowY: "auto", padding: "8px" }, children: loading ? (0, import_jsx_runtime53.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: (0, import_jsx_runtime53.jsx)(Spinner, { size: 24 }) }) : flatCommands.length === 0 ? (0, import_jsx_runtime53.jsx)("div", { style: { textAlign: "center", padding: "32px", color: "var(--ggui-color-neutral-500, #6b7280)" }, children: "No commands found" }) : Array.from(filteredCommands.entries()).map(([group, cmds]) => (0, import_jsx_runtime53.jsxs)("div", { style: { marginBottom: "8px" }, children: [(0, import_jsx_runtime53.jsx)("div", { style: {
29183
+ } })] }) }), (0, import_jsx_runtime53.jsx)("div", { style: { flex: 1, overflowY: "auto", padding: "8px" }, children: loading ? (0, import_jsx_runtime53.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: (0, import_jsx_runtime53.jsx)(Spinner, { size: 24 }) }) : flatCommands.length === 0 ? (0, import_jsx_runtime53.jsx)("div", { style: { textAlign: "center", padding: "32px", color: resolveToneCss("subtle") }, children: "No commands found" }) : Array.from(filteredCommands.entries()).map(([group, cmds]) => (0, import_jsx_runtime53.jsxs)("div", { style: { marginBottom: "8px" }, children: [(0, import_jsx_runtime53.jsx)("div", { style: {
29181
29184
  padding: "8px 12px",
29182
29185
  fontSize: fontSize.xs,
29183
29186
  fontWeight: fontWeight.semibold,
29184
- color: "var(--ggui-color-neutral-500, #6b7280)",
29187
+ color: resolveToneCss("subtle"),
29185
29188
  textTransform: "uppercase",
29186
29189
  letterSpacing: "0.05em"
29187
29190
  }, children: group }), cmds.map((cmd) => {
@@ -29204,12 +29207,12 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
29204
29207
  color: cmd.disabled ? "var(--ggui-color-neutral-400, #9ca3af)" : "var(--ggui-color-onElevated, #111827)",
29205
29208
  textAlign: "left",
29206
29209
  cursor: cmd.disabled ? "not-allowed" : "pointer"
29207
- }, children: [cmd.icon && (0, import_jsx_runtime53.jsx)("span", { style: { display: "flex", color: "var(--ggui-color-neutral-500, #6b7280)" }, children: cmd.icon }), (0, import_jsx_runtime53.jsxs)("div", { style: { flex: 1 }, children: [(0, import_jsx_runtime53.jsx)("div", { style: { fontSize: fontSize.sm }, children: cmd.label }), cmd.description && (0, import_jsx_runtime53.jsx)("div", { style: { fontSize: fontSize.xs, color: "var(--ggui-color-neutral-500, #6b7280)" }, children: cmd.description })] }), cmd.shortcut && (0, import_jsx_runtime53.jsx)("kbd", { style: {
29210
+ }, children: [cmd.icon && (0, import_jsx_runtime53.jsx)("span", { style: { display: "flex", color: resolveToneCss("subtle") }, children: cmd.icon }), (0, import_jsx_runtime53.jsxs)("div", { style: { flex: 1 }, children: [(0, import_jsx_runtime53.jsx)("div", { style: { fontSize: fontSize.sm }, children: cmd.label }), cmd.description && (0, import_jsx_runtime53.jsx)("div", { style: { fontSize: fontSize.xs, color: resolveToneCss("subtle") }, children: cmd.description })] }), cmd.shortcut && (0, import_jsx_runtime53.jsx)("kbd", { style: {
29208
29211
  padding: "2px 6px",
29209
29212
  backgroundColor: "var(--ggui-color-sunken, #f3f4f6)",
29210
29213
  borderRadius: radius.sm,
29211
29214
  fontSize: fontSize.xs,
29212
- color: "var(--ggui-color-neutral-500, #6b7280)",
29215
+ color: resolveToneCss("subtle"),
29213
29216
  fontFamily: "inherit"
29214
29217
  }, children: cmd.shortcut })] }, cmd.id);
29215
29218
  })] }, group)) }), (0, import_jsx_runtime53.jsxs)("div", { style: {
@@ -29219,7 +29222,7 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
29219
29222
  alignItems: "center",
29220
29223
  gap: "16px",
29221
29224
  fontSize: fontSize.xs,
29222
- color: "var(--ggui-color-neutral-500, #6b7280)"
29225
+ color: resolveToneCss("subtle")
29223
29226
  }, children: [(0, import_jsx_runtime53.jsx)("span", { children: "\u2191\u2193 Navigate" }), (0, import_jsx_runtime53.jsx)("span", { children: "\u21B5 Select" }), (0, import_jsx_runtime53.jsx)("span", { children: "Esc Close" })] })] })] });
29224
29227
  }
29225
29228
  function Footer({ brand, columns, socialLinks, bottomText, bottomLinks, background, bordered = true, style, className }) {
@@ -29269,20 +29272,20 @@ function Footer({ brand, columns, socialLinks, bottomText, bottomLinks, backgrou
29269
29272
  borderTop: "1px solid var(--ggui-color-outlineVariant, #e5e7eb)"
29270
29273
  }, children: [bottomText && (0, import_jsx_runtime54.jsx)("span", { style: {
29271
29274
  fontSize: fontSize.sm,
29272
- color: "var(--ggui-color-neutral-500, #6b7280)",
29275
+ color: resolveToneCss("subtle"),
29273
29276
  lineHeight: lineHeight.normal
29274
29277
  }, children: bottomText }), (0, import_jsx_runtime54.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "20px" }, children: [socialLinks?.map((social, idx) => (0, import_jsx_runtime54.jsx)("a", { href: social.href, "aria-label": social.label, style: {
29275
29278
  display: "flex",
29276
29279
  alignItems: "center",
29277
29280
  justifyContent: "center",
29278
- color: "var(--ggui-color-neutral-500, #6b7280)",
29281
+ color: resolveToneCss("subtle"),
29279
29282
  transition: "color 0.15s"
29280
29283
  }, children: social.icon }, idx)), bottomLinks?.map((link, idx) => (0, import_jsx_runtime54.jsx)("a", { href: link.href, onClick: link.onClick ? (e) => {
29281
29284
  e.preventDefault();
29282
29285
  link.onClick?.();
29283
29286
  } : void 0, style: {
29284
29287
  fontSize: fontSize.sm,
29285
- color: "var(--ggui-color-neutral-500, #6b7280)",
29288
+ color: resolveToneCss("subtle"),
29286
29289
  textDecoration: "none",
29287
29290
  transition: "color 0.15s"
29288
29291
  }, children: link.label }, idx))] })] })] });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ggui-ai/dev-stack",
3
- "version": "0.26.0",
4
- "description": "Shared local dev engine for the ggui protocol: local UI registry discovery, compile-on-demand, filesystem watcher with SSE, and a read-only HTTP surface for dev tooling. Framework-neutral — agent runtime supervision plugs in via an adapter seam, so no agent SDK is hardcoded.",
3
+ "version": "0.28.0",
4
+ "description": "Shared local dev engine for the GGUI protocol: local UI registry discovery, compile-on-demand, filesystem watcher with SSE, and a read-only HTTP surface for dev tooling. Framework-neutral — agent runtime supervision plugs in via an adapter seam, so no agent SDK is hardcoded.",
5
5
  "keywords": [
6
6
  "ggui",
7
7
  "dev-server",
@@ -28,9 +28,9 @@
28
28
  "dependencies": {
29
29
  "chokidar": "^4.0.3",
30
30
  "esbuild": "^0.28.2",
31
- "@ggui-ai/agent-runtime": "0.26.0",
32
- "@ggui-ai/ui-registry": "0.26.0",
33
- "@ggui-ai/project-config": "0.26.0"
31
+ "@ggui-ai/project-config": "0.28.0",
32
+ "@ggui-ai/agent-runtime": "0.28.0",
33
+ "@ggui-ai/ui-registry": "0.28.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^24.0.0",
@@ -40,9 +40,9 @@
40
40
  "react-dom": "^19.0.0",
41
41
  "typescript": "^5.0.0",
42
42
  "vitest": "^3.2.6",
43
- "@ggui-ai/design": "0.26.0",
44
- "@ggui-ai/mcp-apps-react": "0.26.0",
45
- "@ggui-ai/wire": "0.26.0"
43
+ "@ggui-ai/design": "0.28.0",
44
+ "@ggui-ai/mcp-apps-react": "0.28.0",
45
+ "@ggui-ai/wire": "0.28.0"
46
46
  },
47
47
  "repository": {
48
48
  "type": "git",