@agent-native/core 0.7.19 → 0.7.20

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.
Files changed (258) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  3. package/dist/agent/engine/builder-engine.js +45 -2
  4. package/dist/agent/engine/builder-engine.js.map +1 -1
  5. package/dist/agent/loop-settings.d.ts +37 -0
  6. package/dist/agent/loop-settings.d.ts.map +1 -0
  7. package/dist/agent/loop-settings.js +127 -0
  8. package/dist/agent/loop-settings.js.map +1 -0
  9. package/dist/agent/production-agent.d.ts +8 -0
  10. package/dist/agent/production-agent.d.ts.map +1 -1
  11. package/dist/agent/production-agent.js +268 -29
  12. package/dist/agent/production-agent.js.map +1 -1
  13. package/dist/agent/run-manager.d.ts.map +1 -1
  14. package/dist/agent/run-manager.js +76 -3
  15. package/dist/agent/run-manager.js.map +1 -1
  16. package/dist/agent/run-store.d.ts +1 -1
  17. package/dist/agent/run-store.d.ts.map +1 -1
  18. package/dist/agent/run-store.js +65 -2
  19. package/dist/agent/run-store.js.map +1 -1
  20. package/dist/agent/thread-data-builder.d.ts +3 -0
  21. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  22. package/dist/agent/thread-data-builder.js +52 -10
  23. package/dist/agent/thread-data-builder.js.map +1 -1
  24. package/dist/agent/tool-search.d.ts +37 -0
  25. package/dist/agent/tool-search.d.ts.map +1 -0
  26. package/dist/agent/tool-search.js +201 -0
  27. package/dist/agent/tool-search.js.map +1 -0
  28. package/dist/agent/types.d.ts +8 -1
  29. package/dist/agent/types.d.ts.map +1 -1
  30. package/dist/agent/types.js.map +1 -1
  31. package/dist/cli/create.d.ts.map +1 -1
  32. package/dist/cli/create.js +44 -9
  33. package/dist/cli/create.js.map +1 -1
  34. package/dist/cli/workspacify.d.ts +2 -0
  35. package/dist/cli/workspacify.d.ts.map +1 -1
  36. package/dist/cli/workspacify.js +34 -1
  37. package/dist/cli/workspacify.js.map +1 -1
  38. package/dist/client/AssistantChat.d.ts.map +1 -1
  39. package/dist/client/AssistantChat.js +277 -18
  40. package/dist/client/AssistantChat.js.map +1 -1
  41. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  42. package/dist/client/ConnectBuilderCard.js +1 -1
  43. package/dist/client/ConnectBuilderCard.js.map +1 -1
  44. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  45. package/dist/client/MultiTabAssistantChat.js +14 -6
  46. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  47. package/dist/client/NewWorkspaceAppFlow.d.ts +14 -0
  48. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -0
  49. package/dist/client/NewWorkspaceAppFlow.js +200 -0
  50. package/dist/client/NewWorkspaceAppFlow.js.map +1 -0
  51. package/dist/client/PoweredByBadge.d.ts +10 -1
  52. package/dist/client/PoweredByBadge.d.ts.map +1 -1
  53. package/dist/client/PoweredByBadge.js +120 -8
  54. package/dist/client/PoweredByBadge.js.map +1 -1
  55. package/dist/client/agent-chat-adapter.d.ts +3 -5
  56. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  57. package/dist/client/agent-chat-adapter.js +26 -19
  58. package/dist/client/agent-chat-adapter.js.map +1 -1
  59. package/dist/client/agent-chat.d.ts.map +1 -1
  60. package/dist/client/agent-chat.js +15 -3
  61. package/dist/client/agent-chat.js.map +1 -1
  62. package/dist/client/analytics.d.ts +1 -1
  63. package/dist/client/analytics.d.ts.map +1 -1
  64. package/dist/client/analytics.js +141 -1
  65. package/dist/client/analytics.js.map +1 -1
  66. package/dist/client/builder-frame.d.ts +10 -0
  67. package/dist/client/builder-frame.d.ts.map +1 -0
  68. package/dist/client/builder-frame.js +94 -0
  69. package/dist/client/builder-frame.js.map +1 -0
  70. package/dist/client/composer/MentionPopover.d.ts.map +1 -1
  71. package/dist/client/composer/MentionPopover.js +5 -1
  72. package/dist/client/composer/MentionPopover.js.map +1 -1
  73. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  74. package/dist/client/composer/TiptapComposer.js +11 -6
  75. package/dist/client/composer/TiptapComposer.js.map +1 -1
  76. package/dist/client/error-format.d.ts +20 -1
  77. package/dist/client/error-format.d.ts.map +1 -1
  78. package/dist/client/error-format.js +53 -5
  79. package/dist/client/error-format.js.map +1 -1
  80. package/dist/client/index.d.ts +3 -1
  81. package/dist/client/index.d.ts.map +1 -1
  82. package/dist/client/index.js +3 -1
  83. package/dist/client/index.js.map +1 -1
  84. package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
  85. package/dist/client/onboarding/OnboardingPanel.js +88 -6
  86. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  87. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  88. package/dist/client/settings/SettingsPanel.js +145 -9
  89. package/dist/client/settings/SettingsPanel.js.map +1 -1
  90. package/dist/client/settings/useBuilderStatus.d.ts +13 -0
  91. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  92. package/dist/client/settings/useBuilderStatus.js +50 -9
  93. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  94. package/dist/client/sse-event-processor.d.ts +3 -0
  95. package/dist/client/sse-event-processor.d.ts.map +1 -1
  96. package/dist/client/sse-event-processor.js +88 -7
  97. package/dist/client/sse-event-processor.js.map +1 -1
  98. package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
  99. package/dist/client/tools/ToolsListPage.js +16 -1
  100. package/dist/client/tools/ToolsListPage.js.map +1 -1
  101. package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -1
  102. package/dist/client/tools/ToolsSidebarSection.js +63 -8
  103. package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
  104. package/dist/client/tools/tool-order.d.ts +7 -0
  105. package/dist/client/tools/tool-order.d.ts.map +1 -0
  106. package/dist/client/tools/tool-order.js +47 -0
  107. package/dist/client/tools/tool-order.js.map +1 -0
  108. package/dist/client/transcription/BuilderTranscriptionCta.d.ts.map +1 -1
  109. package/dist/client/transcription/BuilderTranscriptionCta.js +71 -6
  110. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
  111. package/dist/client/use-send-to-agent-chat.d.ts.map +1 -1
  112. package/dist/client/use-send-to-agent-chat.js +11 -3
  113. package/dist/client/use-send-to-agent-chat.js.map +1 -1
  114. package/dist/client/useProductionAgent.d.ts.map +1 -1
  115. package/dist/client/useProductionAgent.js +1 -1
  116. package/dist/client/useProductionAgent.js.map +1 -1
  117. package/dist/db/client.d.ts.map +1 -1
  118. package/dist/db/client.js +5 -1
  119. package/dist/db/client.js.map +1 -1
  120. package/dist/deploy/build.d.ts +1 -0
  121. package/dist/deploy/build.d.ts.map +1 -1
  122. package/dist/deploy/build.js +4 -1
  123. package/dist/deploy/build.js.map +1 -1
  124. package/dist/oauth-tokens/index.d.ts +1 -1
  125. package/dist/oauth-tokens/index.d.ts.map +1 -1
  126. package/dist/oauth-tokens/index.js +1 -1
  127. package/dist/oauth-tokens/index.js.map +1 -1
  128. package/dist/oauth-tokens/store.d.ts.map +1 -1
  129. package/dist/oauth-tokens/store.js +6 -0
  130. package/dist/oauth-tokens/store.js.map +1 -1
  131. package/dist/observability/store.d.ts.map +1 -1
  132. package/dist/observability/store.js +19 -19
  133. package/dist/observability/store.js.map +1 -1
  134. package/dist/onboarding/default-steps.d.ts.map +1 -1
  135. package/dist/onboarding/default-steps.js +95 -61
  136. package/dist/onboarding/default-steps.js.map +1 -1
  137. package/dist/onboarding/plugin.d.ts.map +1 -1
  138. package/dist/onboarding/plugin.js +17 -8
  139. package/dist/onboarding/plugin.js.map +1 -1
  140. package/dist/org/migrations.js +2 -2
  141. package/dist/org/migrations.js.map +1 -1
  142. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  143. package/dist/scripts/agent-engines/list-agent-engines.js +2 -3
  144. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  145. package/dist/scripts/db/exec.d.ts +2 -1
  146. package/dist/scripts/db/exec.d.ts.map +1 -1
  147. package/dist/scripts/db/exec.js +264 -61
  148. package/dist/scripts/db/exec.js.map +1 -1
  149. package/dist/scripts/db/schema.d.ts.map +1 -1
  150. package/dist/scripts/db/schema.js +16 -4
  151. package/dist/scripts/db/schema.js.map +1 -1
  152. package/dist/scripts/dev/index.d.ts.map +1 -1
  153. package/dist/scripts/dev/index.js +36 -11
  154. package/dist/scripts/dev/index.js.map +1 -1
  155. package/dist/scripts/manage-agent-loop-settings.d.ts +7 -0
  156. package/dist/scripts/manage-agent-loop-settings.d.ts.map +1 -0
  157. package/dist/scripts/manage-agent-loop-settings.js +63 -0
  158. package/dist/scripts/manage-agent-loop-settings.js.map +1 -0
  159. package/dist/scripts/runner.d.ts.map +1 -1
  160. package/dist/scripts/runner.js +11 -0
  161. package/dist/scripts/runner.js.map +1 -1
  162. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  163. package/dist/server/agent-chat-plugin.js +60 -18
  164. package/dist/server/agent-chat-plugin.js.map +1 -1
  165. package/dist/server/app-url.d.ts +5 -4
  166. package/dist/server/app-url.d.ts.map +1 -1
  167. package/dist/server/app-url.js +8 -4
  168. package/dist/server/app-url.js.map +1 -1
  169. package/dist/server/auth.d.ts +8 -0
  170. package/dist/server/auth.d.ts.map +1 -1
  171. package/dist/server/auth.js +82 -29
  172. package/dist/server/auth.js.map +1 -1
  173. package/dist/server/better-auth-instance.d.ts.map +1 -1
  174. package/dist/server/better-auth-instance.js +16 -5
  175. package/dist/server/better-auth-instance.js.map +1 -1
  176. package/dist/server/builder-browser.d.ts +12 -0
  177. package/dist/server/builder-browser.d.ts.map +1 -1
  178. package/dist/server/builder-browser.js +36 -4
  179. package/dist/server/builder-browser.js.map +1 -1
  180. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  181. package/dist/server/core-routes-plugin.js +350 -53
  182. package/dist/server/core-routes-plugin.js.map +1 -1
  183. package/dist/server/credential-provider.d.ts +21 -3
  184. package/dist/server/credential-provider.d.ts.map +1 -1
  185. package/dist/server/credential-provider.js +51 -21
  186. package/dist/server/credential-provider.js.map +1 -1
  187. package/dist/server/google-oauth.d.ts +3 -0
  188. package/dist/server/google-oauth.d.ts.map +1 -1
  189. package/dist/server/google-oauth.js +27 -3
  190. package/dist/server/google-oauth.js.map +1 -1
  191. package/dist/server/index.d.ts +4 -3
  192. package/dist/server/index.d.ts.map +1 -1
  193. package/dist/server/index.js +4 -3
  194. package/dist/server/index.js.map +1 -1
  195. package/dist/server/schema-prompt.d.ts.map +1 -1
  196. package/dist/server/schema-prompt.js +2 -1
  197. package/dist/server/schema-prompt.js.map +1 -1
  198. package/dist/server/security-headers.d.ts +3 -0
  199. package/dist/server/security-headers.d.ts.map +1 -1
  200. package/dist/server/security-headers.js +7 -1
  201. package/dist/server/security-headers.js.map +1 -1
  202. package/dist/server/ssr-handler.d.ts.map +1 -1
  203. package/dist/server/ssr-handler.js +24 -4
  204. package/dist/server/ssr-handler.js.map +1 -1
  205. package/dist/templates/default/_gitignore +5 -1
  206. package/dist/templates/default/app/root.tsx +1 -0
  207. package/dist/templates/default/public/favicon.svg +3 -3
  208. package/dist/templates/default/public/icon-180.svg +3 -3
  209. package/dist/templates/default/public/icon-192.svg +3 -3
  210. package/dist/templates/default/public/icon-512.svg +3 -3
  211. package/dist/templates/workspace-core/AGENTS.md +23 -7
  212. package/dist/templates/workspace-core/package.json +2 -1
  213. package/dist/templates/workspace-core/src/credentials.ts +22 -11
  214. package/dist/templates/workspace-root/.env.example +7 -0
  215. package/dist/templates/workspace-root/README.md +6 -3
  216. package/dist/templates/workspace-root/_gitignore +3 -0
  217. package/dist/templates/workspace-root/package.json +3 -1
  218. package/dist/templates/workspace-root/scripts/workspace-dev.ts +410 -0
  219. package/dist/tools/actions.d.ts.map +1 -1
  220. package/dist/tools/actions.js +2 -0
  221. package/dist/tools/actions.js.map +1 -1
  222. package/dist/tools/html-shell.d.ts.map +1 -1
  223. package/dist/tools/html-shell.js +13 -1
  224. package/dist/tools/html-shell.js.map +1 -1
  225. package/dist/tools/store.d.ts.map +1 -1
  226. package/dist/tools/store.js +10 -10
  227. package/dist/tools/store.js.map +1 -1
  228. package/dist/tracking/providers.d.ts +1 -0
  229. package/dist/tracking/providers.d.ts.map +1 -1
  230. package/dist/tracking/providers.js +72 -0
  231. package/dist/tracking/providers.js.map +1 -1
  232. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  233. package/dist/vite/action-types-plugin.js +106 -9
  234. package/dist/vite/action-types-plugin.js.map +1 -1
  235. package/dist/vite/client.d.ts.map +1 -1
  236. package/dist/vite/client.js +67 -2
  237. package/dist/vite/client.js.map +1 -1
  238. package/docs/content/authentication.md +17 -13
  239. package/docs/content/deployment.md +11 -11
  240. package/docs/content/mcp-clients.md +2 -2
  241. package/docs/content/onboarding.md +32 -30
  242. package/docs/content/security.md +1 -1
  243. package/docs/content/tools.md +4 -0
  244. package/package.json +2 -2
  245. package/src/templates/default/_gitignore +5 -1
  246. package/src/templates/default/app/root.tsx +1 -0
  247. package/src/templates/default/public/favicon.svg +3 -3
  248. package/src/templates/default/public/icon-180.svg +3 -3
  249. package/src/templates/default/public/icon-192.svg +3 -3
  250. package/src/templates/default/public/icon-512.svg +3 -3
  251. package/src/templates/workspace-core/AGENTS.md +23 -7
  252. package/src/templates/workspace-core/package.json +2 -1
  253. package/src/templates/workspace-core/src/credentials.ts +22 -11
  254. package/src/templates/workspace-root/.env.example +7 -0
  255. package/src/templates/workspace-root/README.md +6 -3
  256. package/src/templates/workspace-root/_gitignore +3 -0
  257. package/src/templates/workspace-root/package.json +3 -1
  258. package/src/templates/workspace-root/scripts/workspace-dev.ts +410 -0
@@ -3,10 +3,11 @@ import { agentNativePath } from "../api-path.js";
3
3
  import { useState, useCallback, useMemo, useEffect } from "react";
4
4
  import { useQuery, useQueryClient } from "@tanstack/react-query";
5
5
  import { Link, useLocation, useNavigate } from "react-router";
6
- import { IconTool, IconPlus, IconStar, IconStarFilled, IconTrash, IconDots, IconHelpCircle, IconPencil, } from "@tabler/icons-react";
6
+ import { IconTool, IconPlus, IconStar, IconStarFilled, IconTrash, IconDots, IconHelpCircle, IconPencil, IconGripVertical, } from "@tabler/icons-react";
7
7
  import { cn } from "../utils.js";
8
8
  import { sendToAgentChat } from "../agent-chat.js";
9
9
  import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
10
+ import { applyToolsOrder, getToolsOrder, setToolsOrder } from "./tool-order.js";
10
11
  const FAVORITES_KEY = "tools-favorites";
11
12
  function getFavorites() {
12
13
  try {
@@ -38,6 +39,9 @@ export function ToolsSidebarSection() {
38
39
  const [renameValue, setRenameValue] = useState("");
39
40
  const [showCreate, setShowCreate] = useState(false);
40
41
  const [createPrompt, setCreatePrompt] = useState("");
42
+ const [toolOrderState, setToolOrderState] = useState(() => typeof window !== "undefined" ? getToolsOrder() : []);
43
+ const [draggingId, setDraggingId] = useState(null);
44
+ const [dragOverId, setDragOverId] = useState(null);
41
45
  const { data: tools, isLoading } = useQuery({
42
46
  queryKey: ["tools"],
43
47
  queryFn: async () => {
@@ -78,6 +82,12 @@ export function ToolsSidebarSection() {
78
82
  saveFavorites(next);
79
83
  return next;
80
84
  });
85
+ setToolOrderState((prev) => {
86
+ const next = prev.filter((id) => id !== toolId);
87
+ if (next.length !== prev.length)
88
+ setToolsOrder(next);
89
+ return next;
90
+ });
81
91
  if (location.pathname === `/tools/${toolId}` ||
82
92
  location.pathname === `/tools/${toolId}/edit`) {
83
93
  navigate("/tools");
@@ -130,14 +140,33 @@ export function ToolsSidebarSection() {
130
140
  const sortedTools = useMemo(() => {
131
141
  if (!tools)
132
142
  return [];
133
- return [...tools].sort((a, b) => {
143
+ const defaultSorted = [...tools].sort((a, b) => {
134
144
  const aFav = favoriteIds.has(a.id) ? 0 : 1;
135
145
  const bFav = favoriteIds.has(b.id) ? 0 : 1;
136
146
  if (aFav !== bFav)
137
147
  return aFav - bFav;
138
148
  return a.name.localeCompare(b.name);
139
149
  });
140
- }, [tools, favoriteIds]);
150
+ return toolOrderState.length > 0
151
+ ? applyToolsOrder(defaultSorted, toolOrderState)
152
+ : defaultSorted;
153
+ }, [tools, favoriteIds, toolOrderState]);
154
+ const reorderTool = useCallback((activeId, overId) => {
155
+ if (activeId === overId)
156
+ return;
157
+ const ids = sortedTools.map((tool) => tool.id);
158
+ const oldIndex = ids.indexOf(activeId);
159
+ const newIndex = ids.indexOf(overId);
160
+ if (oldIndex === -1 || newIndex === -1)
161
+ return;
162
+ const next = [...ids];
163
+ const [moved] = next.splice(oldIndex, 1);
164
+ if (!moved)
165
+ return;
166
+ next.splice(newIndex, 0, moved);
167
+ setToolsOrder(next);
168
+ setToolOrderState(next);
169
+ }, [sortedTools]);
141
170
  const handleCreate = () => {
142
171
  if (!createPrompt.trim())
143
172
  return;
@@ -163,7 +192,33 @@ export function ToolsSidebarSection() {
163
192
  location.pathname === `/tools/${tool.id}/edit`;
164
193
  const isFav = favoriteIds.has(tool.id);
165
194
  const isRenamingThis = renamingId === tool.id;
166
- return (_jsxs("div", { className: "group/tool relative", children: [_jsx(Link, { to: `/tools/${tool.id}`, className: cn("flex items-center rounded-md px-2 py-1.5 text-xs transition-colors", isActive
195
+ const actionsVisible = menuOpenId === tool.id || isRenamingThis;
196
+ return (_jsxs("div", { onDragOver: (e) => {
197
+ if (!draggingId || draggingId === tool.id)
198
+ return;
199
+ e.preventDefault();
200
+ e.dataTransfer.dropEffect = "move";
201
+ setDragOverId(tool.id);
202
+ }, onDragLeave: () => {
203
+ setDragOverId((current) => current === tool.id ? null : current);
204
+ }, onDrop: (e) => {
205
+ e.preventDefault();
206
+ const activeId = draggingId || e.dataTransfer.getData("text/plain");
207
+ setDraggingId(null);
208
+ setDragOverId(null);
209
+ if (activeId)
210
+ reorderTool(activeId, tool.id);
211
+ }, className: cn("group/tool relative flex items-center min-w-0 rounded-md", draggingId === tool.id && "opacity-50", dragOverId === tool.id &&
212
+ draggingId !== tool.id &&
213
+ "bg-accent/60"), children: [_jsx("button", { type: "button", draggable: true, onDragStart: (e) => {
214
+ setDraggingId(tool.id);
215
+ setDragOverId(null);
216
+ e.dataTransfer.effectAllowed = "move";
217
+ e.dataTransfer.setData("text/plain", tool.id);
218
+ }, onDragEnd: () => {
219
+ setDraggingId(null);
220
+ setDragOverId(null);
221
+ }, className: "-ml-2 cursor-grab rounded p-0.5 text-muted-foreground/30 opacity-0 transition-colors hover:text-muted-foreground/70 active:cursor-grabbing group-hover/tool:opacity-100 group-focus-within/tool:opacity-100", "aria-label": `Reorder ${tool.name}`, title: "Drag to reorder", children: _jsx(IconGripVertical, { className: "h-3 w-3" }) }), _jsx(Link, { to: `/tools/${tool.id}`, className: cn("flex min-w-0 flex-1 items-center rounded-md px-2 py-1.5 pr-12 text-xs transition-[padding,color,background-color] md:pr-2 md:group-hover/tool:pr-12 md:group-focus-within/tool:pr-12", actionsVisible && "md:pr-12", isActive
167
222
  ? "bg-accent text-accent-foreground font-medium"
168
223
  : "text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground"), children: isRenamingThis ? (_jsx("input", { autoFocus: true, value: renameValue, onChange: (e) => setRenameValue(e.target.value), onBlur: () => submitRename(tool.id), onKeyDown: (e) => {
169
224
  if (e.key === "Enter")
@@ -173,17 +228,17 @@ export function ToolsSidebarSection() {
173
228
  }, onClick: (e) => {
174
229
  e.preventDefault();
175
230
  e.stopPropagation();
176
- }, className: "flex-1 min-w-0 truncate text-xs bg-transparent border-b border-primary outline-none py-0 px-0" })) : (_jsx("span", { className: "truncate", children: tool.name })) }), _jsxs("div", { className: "absolute right-1 top-1/2 -translate-y-1/2 flex items-center gap-0.5", children: [_jsx("button", { type: "button", onClick: (e) => {
231
+ }, className: "min-w-0 flex-1 truncate border-b border-primary bg-transparent px-0 py-0 text-xs outline-none" })) : (_jsx("span", { className: "block truncate", children: tool.name })) }), _jsxs("div", { className: cn("pointer-events-none absolute right-1 top-1/2 flex -translate-y-1/2 items-center gap-0.5 opacity-100 transition-opacity md:opacity-0 md:group-hover/tool:opacity-100 md:group-focus-within/tool:opacity-100", actionsVisible && "md:opacity-100"), children: [_jsx("button", { type: "button", onClick: (e) => {
177
232
  e.preventDefault();
178
233
  e.stopPropagation();
179
234
  toggleFavorite(tool.id);
180
- }, className: cn("cursor-pointer rounded p-0.5", isFav
235
+ }, className: cn("pointer-events-auto cursor-pointer rounded p-0.5 transition-colors", isFav
181
236
  ? "text-yellow-500"
182
- : "text-muted-foreground/40 opacity-100 hover:text-yellow-500 md:opacity-0 md:group-hover/tool:opacity-100 md:group-focus-within/tool:opacity-100"), "aria-label": isFav ? "Unfavorite" : "Favorite", children: isFav ? (_jsx(IconStarFilled, { className: "h-3 w-3" })) : (_jsx(IconStar, { className: "h-3 w-3" })) }), _jsxs("div", { className: "relative", children: [_jsx("button", { type: "button", onClick: (e) => {
237
+ : "text-muted-foreground/40 hover:text-yellow-500"), "aria-label": isFav ? "Unfavorite" : "Favorite", children: isFav ? (_jsx(IconStarFilled, { className: "h-3 w-3" })) : (_jsx(IconStar, { className: "h-3 w-3" })) }), _jsxs("div", { className: "relative", children: [_jsx("button", { type: "button", onClick: (e) => {
183
238
  e.preventDefault();
184
239
  e.stopPropagation();
185
240
  setMenuOpenId(menuOpenId === tool.id ? null : tool.id);
186
- }, className: "cursor-pointer rounded p-0.5 text-muted-foreground/40 opacity-100 hover:text-foreground md:opacity-0 md:group-hover/tool:opacity-100 md:group-focus-within/tool:opacity-100", "aria-label": "Tool actions", children: _jsx(IconDots, { className: "h-3 w-3" }) }), menuOpenId === tool.id && (_jsxs("div", { className: "absolute right-0 top-full z-50 mt-1 min-w-[120px] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md", onClick: (e) => e.stopPropagation(), children: [_jsxs("button", { type: "button", onClick: () => startRename(tool), className: "flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent", children: [_jsx(IconPencil, { className: "h-3.5 w-3.5" }), "Rename"] }), _jsxs("button", { type: "button", onClick: () => handleDelete(tool.id), className: "flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-destructive hover:bg-accent", children: [_jsx(IconTrash, { className: "h-3.5 w-3.5" }), "Delete"] })] }))] })] })] }, tool.id));
241
+ }, className: "pointer-events-auto cursor-pointer rounded p-0.5 text-muted-foreground/40 transition-colors hover:text-foreground", "aria-label": "Tool actions", children: _jsx(IconDots, { className: "h-3 w-3" }) }), menuOpenId === tool.id && (_jsxs("div", { className: "absolute right-0 top-full z-50 mt-1 min-w-[120px] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md", onClick: (e) => e.stopPropagation(), children: [_jsxs("button", { type: "button", onClick: () => startRename(tool), className: "flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent", children: [_jsx(IconPencil, { className: "h-3.5 w-3.5" }), "Rename"] }), _jsxs("button", { type: "button", onClick: () => handleDelete(tool.id), className: "flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-destructive hover:bg-accent", children: [_jsx(IconTrash, { className: "h-3.5 w-3.5" }), "Delete"] })] }))] })] })] }, tool.id));
187
242
  }) }))] }));
188
243
  }
189
244
  //# sourceMappingURL=ToolsSidebarSection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolsSidebarSection.js","sourceRoot":"","sources":["../../../src/client/tools/ToolsSidebarSection.tsx"],"names":[],"mappings":"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","sourcesContent":["import { agentNativePath } from \"../api-path.js\";\nimport { useState, useCallback, useMemo, useEffect } from \"react\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { Link, useLocation, useNavigate } from \"react-router\";\nimport {\n IconTool,\n IconPlus,\n IconStar,\n IconStarFilled,\n IconTrash,\n IconDots,\n IconHelpCircle,\n IconPencil,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { sendToAgentChat } from \"../agent-chat.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\n\ninterface Tool {\n id: string;\n name: string;\n description?: string;\n icon?: string;\n}\n\nconst FAVORITES_KEY = \"tools-favorites\";\n\nfunction getFavorites(): Set<string> {\n try {\n const raw = localStorage.getItem(FAVORITES_KEY);\n if (!raw) return new Set();\n const parsed = JSON.parse(raw);\n return new Set(Array.isArray(parsed) ? parsed : []);\n } catch {\n return new Set();\n }\n}\n\nfunction saveFavorites(ids: Set<string>) {\n try {\n localStorage.setItem(FAVORITES_KEY, JSON.stringify(Array.from(ids)));\n } catch {\n // localStorage unavailable — ignore\n }\n}\n\nexport function ToolsSidebarSection() {\n const location = useLocation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const [favoriteIds, setFavoriteIds] = useState<Set<string>>(() =>\n typeof window !== \"undefined\" ? getFavorites() : new Set(),\n );\n const [menuOpenId, setMenuOpenId] = useState<string | null>(null);\n const [renamingId, setRenamingId] = useState<string | null>(null);\n const [renameValue, setRenameValue] = useState(\"\");\n const [showCreate, setShowCreate] = useState(false);\n const [createPrompt, setCreatePrompt] = useState(\"\");\n\n const { data: tools, isLoading } = useQuery<Tool[]>({\n queryKey: [\"tools\"],\n queryFn: async () => {\n const res = await fetch(agentNativePath(\"/_agent-native/tools\"));\n if (!res.ok) return [];\n return res.json();\n },\n });\n\n const toggleFavorite = useCallback((id: string) => {\n setFavoriteIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n saveFavorites(next);\n return next;\n });\n }, []);\n\n const handleDelete = useCallback(\n async (toolId: string) => {\n setMenuOpenId(null);\n const prev = queryClient.getQueryData<Tool[]>([\"tools\"]);\n queryClient.setQueryData<Tool[]>([\"tools\"], (old) =>\n (old ?? []).filter((t) => t.id !== toolId),\n );\n try {\n const res = await fetch(\n agentNativePath(`/_agent-native/tools/${toolId}`),\n {\n method: \"DELETE\",\n },\n );\n if (!res.ok) throw new Error(\"Delete failed\");\n queryClient.removeQueries({ queryKey: [\"tool\", toolId] });\n queryClient.invalidateQueries({ queryKey: [\"tools\"] });\n setFavoriteIds((prev) => {\n const next = new Set(prev);\n next.delete(toolId);\n saveFavorites(next);\n return next;\n });\n if (\n location.pathname === `/tools/${toolId}` ||\n location.pathname === `/tools/${toolId}/edit`\n ) {\n navigate(\"/tools\");\n }\n } catch {\n if (prev) queryClient.setQueryData([\"tools\"], prev);\n }\n },\n [location.pathname, navigate, queryClient],\n );\n\n const startRename = useCallback((tool: Tool) => {\n setMenuOpenId(null);\n setRenameValue(tool.name);\n setRenamingId(tool.id);\n }, []);\n\n const submitRename = useCallback(\n async (toolId: string) => {\n const trimmed = renameValue.trim();\n setRenamingId(null);\n if (!trimmed) return;\n const prev = queryClient.getQueryData<Tool[]>([\"tools\"]);\n const existing = prev?.find((t) => t.id === toolId);\n if (!existing || trimmed === existing.name) return;\n queryClient.setQueryData<Tool[]>([\"tools\"], (old) =>\n (old ?? []).map((t) => (t.id === toolId ? { ...t, name: trimmed } : t)),\n );\n queryClient.setQueryData<Tool>([\"tool\", toolId], (old) =>\n old ? { ...old, name: trimmed } : old,\n );\n try {\n await fetch(agentNativePath(`/_agent-native/tools/${toolId}`), {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ name: trimmed }),\n });\n queryClient.invalidateQueries({ queryKey: [\"tools\"] });\n queryClient.invalidateQueries({ queryKey: [\"tool\", toolId] });\n } catch {\n if (prev) queryClient.setQueryData([\"tools\"], prev);\n queryClient.invalidateQueries({ queryKey: [\"tool\", toolId] });\n }\n },\n [renameValue, queryClient],\n );\n\n // Close menu on click outside\n useEffect(() => {\n if (!menuOpenId) return;\n const handler = () => setMenuOpenId(null);\n document.addEventListener(\"click\", handler);\n return () => document.removeEventListener(\"click\", handler);\n }, [menuOpenId]);\n\n const sortedTools = useMemo(() => {\n if (!tools) return [];\n return [...tools].sort((a, b) => {\n const aFav = favoriteIds.has(a.id) ? 0 : 1;\n const bFav = favoriteIds.has(b.id) ? 0 : 1;\n if (aFav !== bFav) return aFav - bFav;\n return a.name.localeCompare(b.name);\n });\n }, [tools, favoriteIds]);\n\n const handleCreate = () => {\n if (!createPrompt.trim()) return;\n sendToAgentChat({\n message: `Create a tool: ${createPrompt.trim()}`,\n submit: true,\n openSidebar: true,\n newTab: true,\n });\n setCreatePrompt(\"\");\n setShowCreate(false);\n };\n\n return (\n <div className=\"group/help relative py-2\">\n <div\n className={cn(\n \"flex items-center justify-between px-3\",\n sortedTools.length > 0 && \"mb-1\",\n )}\n >\n <span className=\"inline-flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n <IconTool className=\"h-3.5 w-3.5 shrink-0\" />\n Tools\n <a\n href=\"https://agent-native.com/docs/tools\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"opacity-0 group-hover/help:opacity-100 transition-opacity text-muted-foreground/50 hover:text-muted-foreground\"\n aria-label=\"Tools documentation\"\n >\n <IconHelpCircle className=\"h-3 w-3\" />\n </a>\n </span>\n <Popover open={showCreate} onOpenChange={setShowCreate}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex h-5 w-5 cursor-pointer items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n aria-label=\"New tool\"\n >\n <IconPlus className=\"h-3.5 w-3.5\" />\n </button>\n </PopoverTrigger>\n <PopoverContent side=\"right\" align=\"start\" className=\"w-80 p-4\">\n <form\n onSubmit={(e) => {\n e.preventDefault();\n handleCreate();\n }}\n >\n <textarea\n autoFocus\n value={createPrompt}\n onChange={(e) => setCreatePrompt(e.target.value)}\n placeholder=\"Describe what you'd like to build...\"\n className=\"flex w-full rounded-md border border-input bg-background px-3 py-3 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring/50 min-h-[100px] resize-y\"\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"Enter\") {\n e.preventDefault();\n handleCreate();\n }\n }}\n />\n <div className=\"flex items-center justify-end gap-2 mt-3\">\n <span className=\"text-[11px] text-muted-foreground/75\">\n {/Mac|iPhone|iPad/.test(navigator.userAgent) ? \"⌘\" : \"Ctrl\"}\n +Enter\n </span>\n <button\n type=\"submit\"\n disabled={!createPrompt.trim()}\n className=\"rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer\"\n >\n Create\n </button>\n </div>\n </form>\n </PopoverContent>\n </Popover>\n </div>\n\n {isLoading ? (\n <div className=\"space-y-0.5 px-1\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"flex items-center rounded-md px-2 py-1.5\">\n <div\n className=\"h-3 rounded bg-muted animate-pulse\"\n style={{ width: `${60 + i * 20}px` }}\n />\n </div>\n ))}\n </div>\n ) : sortedTools.length === 0 ? null : (\n <div className=\"space-y-0.5 px-1\">\n {sortedTools.map((tool) => {\n const isActive =\n location.pathname === `/tools/${tool.id}` ||\n location.pathname === `/tools/${tool.id}/edit`;\n const isFav = favoriteIds.has(tool.id);\n const isRenamingThis = renamingId === tool.id;\n\n return (\n <div key={tool.id} className=\"group/tool relative\">\n <Link\n to={`/tools/${tool.id}`}\n className={cn(\n \"flex items-center rounded-md px-2 py-1.5 text-xs transition-colors\",\n isActive\n ? \"bg-accent text-accent-foreground font-medium\"\n : \"text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground\",\n )}\n >\n {isRenamingThis ? (\n <input\n autoFocus\n value={renameValue}\n onChange={(e) => setRenameValue(e.target.value)}\n onBlur={() => submitRename(tool.id)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") submitRename(tool.id);\n if (e.key === \"Escape\") setRenamingId(null);\n }}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n className=\"flex-1 min-w-0 truncate text-xs bg-transparent border-b border-primary outline-none py-0 px-0\"\n />\n ) : (\n <span className=\"truncate\">{tool.name}</span>\n )}\n </Link>\n\n <div className=\"absolute right-1 top-1/2 -translate-y-1/2 flex items-center gap-0.5\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n toggleFavorite(tool.id);\n }}\n className={cn(\n \"cursor-pointer rounded p-0.5\",\n isFav\n ? \"text-yellow-500\"\n : \"text-muted-foreground/40 opacity-100 hover:text-yellow-500 md:opacity-0 md:group-hover/tool:opacity-100 md:group-focus-within/tool:opacity-100\",\n )}\n aria-label={isFav ? \"Unfavorite\" : \"Favorite\"}\n >\n {isFav ? (\n <IconStarFilled className=\"h-3 w-3\" />\n ) : (\n <IconStar className=\"h-3 w-3\" />\n )}\n </button>\n\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setMenuOpenId(menuOpenId === tool.id ? null : tool.id);\n }}\n className=\"cursor-pointer rounded p-0.5 text-muted-foreground/40 opacity-100 hover:text-foreground md:opacity-0 md:group-hover/tool:opacity-100 md:group-focus-within/tool:opacity-100\"\n aria-label=\"Tool actions\"\n >\n <IconDots className=\"h-3 w-3\" />\n </button>\n\n {menuOpenId === tool.id && (\n <div\n className=\"absolute right-0 top-full z-50 mt-1 min-w-[120px] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md\"\n onClick={(e) => e.stopPropagation()}\n >\n <button\n type=\"button\"\n onClick={() => startRename(tool)}\n className=\"flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent\"\n >\n <IconPencil className=\"h-3.5 w-3.5\" />\n Rename\n </button>\n <button\n type=\"button\"\n onClick={() => handleDelete(tool.id)}\n className=\"flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-destructive hover:bg-accent\"\n >\n <IconTrash className=\"h-3.5 w-3.5\" />\n Delete\n </button>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"ToolsSidebarSection.js","sourceRoot":"","sources":["../../../src/client/tools/ToolsSidebarSection.tsx"],"names":[],"mappings":"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","sourcesContent":["import { agentNativePath } from \"../api-path.js\";\nimport { useState, useCallback, useMemo, useEffect } from \"react\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { Link, useLocation, useNavigate } from \"react-router\";\nimport {\n IconTool,\n IconPlus,\n IconStar,\n IconStarFilled,\n IconTrash,\n IconDots,\n IconHelpCircle,\n IconPencil,\n IconGripVertical,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { sendToAgentChat } from \"../agent-chat.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport { applyToolsOrder, getToolsOrder, setToolsOrder } from \"./tool-order.js\";\n\ninterface Tool {\n id: string;\n name: string;\n description?: string;\n icon?: string;\n}\n\nconst FAVORITES_KEY = \"tools-favorites\";\n\nfunction getFavorites(): Set<string> {\n try {\n const raw = localStorage.getItem(FAVORITES_KEY);\n if (!raw) return new Set();\n const parsed = JSON.parse(raw);\n return new Set(Array.isArray(parsed) ? parsed : []);\n } catch {\n return new Set();\n }\n}\n\nfunction saveFavorites(ids: Set<string>) {\n try {\n localStorage.setItem(FAVORITES_KEY, JSON.stringify(Array.from(ids)));\n } catch {\n // localStorage unavailable — ignore\n }\n}\n\nexport function ToolsSidebarSection() {\n const location = useLocation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const [favoriteIds, setFavoriteIds] = useState<Set<string>>(() =>\n typeof window !== \"undefined\" ? getFavorites() : new Set(),\n );\n const [menuOpenId, setMenuOpenId] = useState<string | null>(null);\n const [renamingId, setRenamingId] = useState<string | null>(null);\n const [renameValue, setRenameValue] = useState(\"\");\n const [showCreate, setShowCreate] = useState(false);\n const [createPrompt, setCreatePrompt] = useState(\"\");\n const [toolOrderState, setToolOrderState] = useState<string[]>(() =>\n typeof window !== \"undefined\" ? getToolsOrder() : [],\n );\n const [draggingId, setDraggingId] = useState<string | null>(null);\n const [dragOverId, setDragOverId] = useState<string | null>(null);\n\n const { data: tools, isLoading } = useQuery<Tool[]>({\n queryKey: [\"tools\"],\n queryFn: async () => {\n const res = await fetch(agentNativePath(\"/_agent-native/tools\"));\n if (!res.ok) return [];\n return res.json();\n },\n });\n\n const toggleFavorite = useCallback((id: string) => {\n setFavoriteIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n saveFavorites(next);\n return next;\n });\n }, []);\n\n const handleDelete = useCallback(\n async (toolId: string) => {\n setMenuOpenId(null);\n const prev = queryClient.getQueryData<Tool[]>([\"tools\"]);\n queryClient.setQueryData<Tool[]>([\"tools\"], (old) =>\n (old ?? []).filter((t) => t.id !== toolId),\n );\n try {\n const res = await fetch(\n agentNativePath(`/_agent-native/tools/${toolId}`),\n {\n method: \"DELETE\",\n },\n );\n if (!res.ok) throw new Error(\"Delete failed\");\n queryClient.removeQueries({ queryKey: [\"tool\", toolId] });\n queryClient.invalidateQueries({ queryKey: [\"tools\"] });\n setFavoriteIds((prev) => {\n const next = new Set(prev);\n next.delete(toolId);\n saveFavorites(next);\n return next;\n });\n setToolOrderState((prev) => {\n const next = prev.filter((id) => id !== toolId);\n if (next.length !== prev.length) setToolsOrder(next);\n return next;\n });\n if (\n location.pathname === `/tools/${toolId}` ||\n location.pathname === `/tools/${toolId}/edit`\n ) {\n navigate(\"/tools\");\n }\n } catch {\n if (prev) queryClient.setQueryData([\"tools\"], prev);\n }\n },\n [location.pathname, navigate, queryClient],\n );\n\n const startRename = useCallback((tool: Tool) => {\n setMenuOpenId(null);\n setRenameValue(tool.name);\n setRenamingId(tool.id);\n }, []);\n\n const submitRename = useCallback(\n async (toolId: string) => {\n const trimmed = renameValue.trim();\n setRenamingId(null);\n if (!trimmed) return;\n const prev = queryClient.getQueryData<Tool[]>([\"tools\"]);\n const existing = prev?.find((t) => t.id === toolId);\n if (!existing || trimmed === existing.name) return;\n queryClient.setQueryData<Tool[]>([\"tools\"], (old) =>\n (old ?? []).map((t) => (t.id === toolId ? { ...t, name: trimmed } : t)),\n );\n queryClient.setQueryData<Tool>([\"tool\", toolId], (old) =>\n old ? { ...old, name: trimmed } : old,\n );\n try {\n await fetch(agentNativePath(`/_agent-native/tools/${toolId}`), {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ name: trimmed }),\n });\n queryClient.invalidateQueries({ queryKey: [\"tools\"] });\n queryClient.invalidateQueries({ queryKey: [\"tool\", toolId] });\n } catch {\n if (prev) queryClient.setQueryData([\"tools\"], prev);\n queryClient.invalidateQueries({ queryKey: [\"tool\", toolId] });\n }\n },\n [renameValue, queryClient],\n );\n\n // Close menu on click outside\n useEffect(() => {\n if (!menuOpenId) return;\n const handler = () => setMenuOpenId(null);\n document.addEventListener(\"click\", handler);\n return () => document.removeEventListener(\"click\", handler);\n }, [menuOpenId]);\n\n const sortedTools = useMemo(() => {\n if (!tools) return [];\n const defaultSorted = [...tools].sort((a, b) => {\n const aFav = favoriteIds.has(a.id) ? 0 : 1;\n const bFav = favoriteIds.has(b.id) ? 0 : 1;\n if (aFav !== bFav) return aFav - bFav;\n return a.name.localeCompare(b.name);\n });\n return toolOrderState.length > 0\n ? applyToolsOrder(defaultSorted, toolOrderState)\n : defaultSorted;\n }, [tools, favoriteIds, toolOrderState]);\n\n const reorderTool = useCallback(\n (activeId: string, overId: string) => {\n if (activeId === overId) return;\n const ids = sortedTools.map((tool) => tool.id);\n const oldIndex = ids.indexOf(activeId);\n const newIndex = ids.indexOf(overId);\n if (oldIndex === -1 || newIndex === -1) return;\n const next = [...ids];\n const [moved] = next.splice(oldIndex, 1);\n if (!moved) return;\n next.splice(newIndex, 0, moved);\n setToolsOrder(next);\n setToolOrderState(next);\n },\n [sortedTools],\n );\n\n const handleCreate = () => {\n if (!createPrompt.trim()) return;\n sendToAgentChat({\n message: `Create a tool: ${createPrompt.trim()}`,\n submit: true,\n openSidebar: true,\n newTab: true,\n });\n setCreatePrompt(\"\");\n setShowCreate(false);\n };\n\n return (\n <div className=\"group/help relative py-2\">\n <div\n className={cn(\n \"flex items-center justify-between px-3\",\n sortedTools.length > 0 && \"mb-1\",\n )}\n >\n <span className=\"inline-flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n <IconTool className=\"h-3.5 w-3.5 shrink-0\" />\n Tools\n <a\n href=\"https://agent-native.com/docs/tools\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"opacity-0 group-hover/help:opacity-100 transition-opacity text-muted-foreground/50 hover:text-muted-foreground\"\n aria-label=\"Tools documentation\"\n >\n <IconHelpCircle className=\"h-3 w-3\" />\n </a>\n </span>\n <Popover open={showCreate} onOpenChange={setShowCreate}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex h-5 w-5 cursor-pointer items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n aria-label=\"New tool\"\n >\n <IconPlus className=\"h-3.5 w-3.5\" />\n </button>\n </PopoverTrigger>\n <PopoverContent side=\"right\" align=\"start\" className=\"w-80 p-4\">\n <form\n onSubmit={(e) => {\n e.preventDefault();\n handleCreate();\n }}\n >\n <textarea\n autoFocus\n value={createPrompt}\n onChange={(e) => setCreatePrompt(e.target.value)}\n placeholder=\"Describe what you'd like to build...\"\n className=\"flex w-full rounded-md border border-input bg-background px-3 py-3 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring/50 min-h-[100px] resize-y\"\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"Enter\") {\n e.preventDefault();\n handleCreate();\n }\n }}\n />\n <div className=\"flex items-center justify-end gap-2 mt-3\">\n <span className=\"text-[11px] text-muted-foreground/75\">\n {/Mac|iPhone|iPad/.test(navigator.userAgent) ? \"⌘\" : \"Ctrl\"}\n +Enter\n </span>\n <button\n type=\"submit\"\n disabled={!createPrompt.trim()}\n className=\"rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer\"\n >\n Create\n </button>\n </div>\n </form>\n </PopoverContent>\n </Popover>\n </div>\n\n {isLoading ? (\n <div className=\"space-y-0.5 px-1\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"flex items-center rounded-md px-2 py-1.5\">\n <div\n className=\"h-3 rounded bg-muted animate-pulse\"\n style={{ width: `${60 + i * 20}px` }}\n />\n </div>\n ))}\n </div>\n ) : sortedTools.length === 0 ? null : (\n <div className=\"space-y-0.5 px-1\">\n {sortedTools.map((tool) => {\n const isActive =\n location.pathname === `/tools/${tool.id}` ||\n location.pathname === `/tools/${tool.id}/edit`;\n const isFav = favoriteIds.has(tool.id);\n const isRenamingThis = renamingId === tool.id;\n const actionsVisible = menuOpenId === tool.id || isRenamingThis;\n\n return (\n <div\n key={tool.id}\n onDragOver={(e) => {\n if (!draggingId || draggingId === tool.id) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n setDragOverId(tool.id);\n }}\n onDragLeave={() => {\n setDragOverId((current) =>\n current === tool.id ? null : current,\n );\n }}\n onDrop={(e) => {\n e.preventDefault();\n const activeId =\n draggingId || e.dataTransfer.getData(\"text/plain\");\n setDraggingId(null);\n setDragOverId(null);\n if (activeId) reorderTool(activeId, tool.id);\n }}\n className={cn(\n \"group/tool relative flex items-center min-w-0 rounded-md\",\n draggingId === tool.id && \"opacity-50\",\n dragOverId === tool.id &&\n draggingId !== tool.id &&\n \"bg-accent/60\",\n )}\n >\n <button\n type=\"button\"\n draggable\n onDragStart={(e) => {\n setDraggingId(tool.id);\n setDragOverId(null);\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", tool.id);\n }}\n onDragEnd={() => {\n setDraggingId(null);\n setDragOverId(null);\n }}\n className=\"-ml-2 cursor-grab rounded p-0.5 text-muted-foreground/30 opacity-0 transition-colors hover:text-muted-foreground/70 active:cursor-grabbing group-hover/tool:opacity-100 group-focus-within/tool:opacity-100\"\n aria-label={`Reorder ${tool.name}`}\n title=\"Drag to reorder\"\n >\n <IconGripVertical className=\"h-3 w-3\" />\n </button>\n <Link\n to={`/tools/${tool.id}`}\n className={cn(\n \"flex min-w-0 flex-1 items-center rounded-md px-2 py-1.5 pr-12 text-xs transition-[padding,color,background-color] md:pr-2 md:group-hover/tool:pr-12 md:group-focus-within/tool:pr-12\",\n actionsVisible && \"md:pr-12\",\n isActive\n ? \"bg-accent text-accent-foreground font-medium\"\n : \"text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground\",\n )}\n >\n {isRenamingThis ? (\n <input\n autoFocus\n value={renameValue}\n onChange={(e) => setRenameValue(e.target.value)}\n onBlur={() => submitRename(tool.id)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") submitRename(tool.id);\n if (e.key === \"Escape\") setRenamingId(null);\n }}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n className=\"min-w-0 flex-1 truncate border-b border-primary bg-transparent px-0 py-0 text-xs outline-none\"\n />\n ) : (\n <span className=\"block truncate\">{tool.name}</span>\n )}\n </Link>\n\n <div\n className={cn(\n \"pointer-events-none absolute right-1 top-1/2 flex -translate-y-1/2 items-center gap-0.5 opacity-100 transition-opacity md:opacity-0 md:group-hover/tool:opacity-100 md:group-focus-within/tool:opacity-100\",\n actionsVisible && \"md:opacity-100\",\n )}\n >\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n toggleFavorite(tool.id);\n }}\n className={cn(\n \"pointer-events-auto cursor-pointer rounded p-0.5 transition-colors\",\n isFav\n ? \"text-yellow-500\"\n : \"text-muted-foreground/40 hover:text-yellow-500\",\n )}\n aria-label={isFav ? \"Unfavorite\" : \"Favorite\"}\n >\n {isFav ? (\n <IconStarFilled className=\"h-3 w-3\" />\n ) : (\n <IconStar className=\"h-3 w-3\" />\n )}\n </button>\n\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setMenuOpenId(menuOpenId === tool.id ? null : tool.id);\n }}\n className=\"pointer-events-auto cursor-pointer rounded p-0.5 text-muted-foreground/40 transition-colors hover:text-foreground\"\n aria-label=\"Tool actions\"\n >\n <IconDots className=\"h-3 w-3\" />\n </button>\n\n {menuOpenId === tool.id && (\n <div\n className=\"absolute right-0 top-full z-50 mt-1 min-w-[120px] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md\"\n onClick={(e) => e.stopPropagation()}\n >\n <button\n type=\"button\"\n onClick={() => startRename(tool)}\n className=\"flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent\"\n >\n <IconPencil className=\"h-3.5 w-3.5\" />\n Rename\n </button>\n <button\n type=\"button\"\n onClick={() => handleDelete(tool.id)}\n className=\"flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-destructive hover:bg-accent\"\n >\n <IconTrash className=\"h-3.5 w-3.5\" />\n Delete\n </button>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n"]}
@@ -0,0 +1,7 @@
1
+ export declare const TOOLS_ORDER_CHANGE_EVENT = "tools-order-change";
2
+ export declare function getToolsOrder(): string[];
3
+ export declare function setToolsOrder(order: string[]): void;
4
+ export declare function applyToolsOrder<T extends {
5
+ id: string;
6
+ }>(items: T[], savedOrder: string[]): T[];
7
+ //# sourceMappingURL=tool-order.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-order.d.ts","sourceRoot":"","sources":["../../../src/client/tools/tool-order.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAI7D,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAYxC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAU5C;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EACtD,KAAK,EAAE,CAAC,EAAE,EACV,UAAU,EAAE,MAAM,EAAE,GACnB,CAAC,EAAE,CAeL"}
@@ -0,0 +1,47 @@
1
+ export const TOOLS_ORDER_CHANGE_EVENT = "tools-order-change";
2
+ const TOOLS_ORDER_KEY = "tools-order";
3
+ export function getToolsOrder() {
4
+ if (typeof window === "undefined")
5
+ return [];
6
+ try {
7
+ const raw = window.localStorage.getItem(TOOLS_ORDER_KEY);
8
+ if (!raw)
9
+ return [];
10
+ const parsed = JSON.parse(raw);
11
+ return Array.isArray(parsed)
12
+ ? parsed.filter((id) => typeof id === "string")
13
+ : [];
14
+ }
15
+ catch {
16
+ return [];
17
+ }
18
+ }
19
+ export function setToolsOrder(order) {
20
+ if (typeof window === "undefined")
21
+ return;
22
+ try {
23
+ window.localStorage.setItem(TOOLS_ORDER_KEY, JSON.stringify(order));
24
+ window.dispatchEvent(new CustomEvent(TOOLS_ORDER_CHANGE_EVENT, { detail: order }));
25
+ }
26
+ catch {
27
+ // localStorage unavailable / quota — ignore, order is best-effort
28
+ }
29
+ }
30
+ export function applyToolsOrder(items, savedOrder) {
31
+ if (savedOrder.length === 0)
32
+ return items;
33
+ const idToItem = new Map(items.map((item) => [item.id, item]));
34
+ const ordered = [];
35
+ for (const id of savedOrder) {
36
+ const item = idToItem.get(id);
37
+ if (item) {
38
+ ordered.push(item);
39
+ idToItem.delete(id);
40
+ }
41
+ }
42
+ for (const item of idToItem.values()) {
43
+ ordered.push(item);
44
+ }
45
+ return ordered;
46
+ }
47
+ //# sourceMappingURL=tool-order.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-order.js","sourceRoot":"","sources":["../../../src/client/tools/tool-order.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;AAE7D,MAAM,eAAe,GAAG,aAAa,CAAC;AAEtC,MAAM,UAAU,aAAa;IAC3B,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACzD,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAC1B,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC;YAC/C,CAAC,CAAC,EAAE,CAAC;IACT,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAe;IAC3C,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO;IAC1C,IAAI,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,wBAAwB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAC7D,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;IACpE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAU,EACV,UAAoB;IAEpB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAQ,EAAE,CAAC;IACxB,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["export const TOOLS_ORDER_CHANGE_EVENT = \"tools-order-change\";\n\nconst TOOLS_ORDER_KEY = \"tools-order\";\n\nexport function getToolsOrder(): string[] {\n if (typeof window === \"undefined\") return [];\n try {\n const raw = window.localStorage.getItem(TOOLS_ORDER_KEY);\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed)\n ? parsed.filter((id) => typeof id === \"string\")\n : [];\n } catch {\n return [];\n }\n}\n\nexport function setToolsOrder(order: string[]) {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(TOOLS_ORDER_KEY, JSON.stringify(order));\n window.dispatchEvent(\n new CustomEvent(TOOLS_ORDER_CHANGE_EVENT, { detail: order }),\n );\n } catch {\n // localStorage unavailable / quota — ignore, order is best-effort\n }\n}\n\nexport function applyToolsOrder<T extends { id: string }>(\n items: T[],\n savedOrder: string[],\n): T[] {\n if (savedOrder.length === 0) return items;\n const idToItem = new Map(items.map((item) => [item.id, item]));\n const ordered: T[] = [];\n for (const id of savedOrder) {\n const item = idToItem.get(id);\n if (item) {\n ordered.push(item);\n idToItem.delete(id);\n }\n }\n for (const item of idToItem.values()) {\n ordered.push(item);\n }\n return ordered;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"BuilderTranscriptionCta.d.ts","sourceRoot":"","sources":["../../../src/client/transcription/BuilderTranscriptionCta.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,wBAAgB,uBAAuB,4CAmBtC"}
1
+ {"version":3,"file":"BuilderTranscriptionCta.d.ts","sourceRoot":"","sources":["../../../src/client/transcription/BuilderTranscriptionCta.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,wBAAgB,uBAAuB,4CAoGtC"}
@@ -6,13 +6,78 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
6
  *
7
7
  * Drop this next to transcript displays in any template.
8
8
  */
9
- import { IconArrowUp } from "@tabler/icons-react";
10
- import { useBuilderStatus } from "../settings/useBuilderStatus.js";
9
+ import { useCallback, useEffect, useRef, useState } from "react";
10
+ import { IconBolt, IconExternalLink, IconLoader2 } from "@tabler/icons-react";
11
+ import { agentNativePath } from "../api-path.js";
12
+ import { getCallbackOrigin } from "../frame.js";
11
13
  export function BuilderTranscriptionCta() {
12
- const { status, loading } = useBuilderStatus();
13
- // Still loading or already connected — render nothing.
14
- if (loading || status?.configured)
14
+ const [configured, setConfigured] = useState(null);
15
+ const [connecting, setConnecting] = useState(false);
16
+ const [error, setError] = useState(null);
17
+ const pollRef = useRef(null);
18
+ const mountedRef = useRef(true);
19
+ useEffect(() => {
20
+ mountedRef.current = true;
21
+ fetch(agentNativePath("/_agent-native/builder/status"))
22
+ .then((r) => r.ok
23
+ ? r.json()
24
+ : null)
25
+ .then((s) => {
26
+ if (!mountedRef.current)
27
+ return;
28
+ // Env-managed mode counts as configured for the CTA — the deploy
29
+ // already routes transcription through Builder, no per-user prompt.
30
+ setConfigured(!!(s?.configured || s?.envManaged));
31
+ })
32
+ .catch(() => {
33
+ if (mountedRef.current)
34
+ setConfigured(false);
35
+ });
36
+ return () => {
37
+ mountedRef.current = false;
38
+ if (pollRef.current)
39
+ clearInterval(pollRef.current);
40
+ };
41
+ }, []);
42
+ const handleConnect = useCallback(() => {
43
+ if (pollRef.current)
44
+ clearInterval(pollRef.current);
45
+ setConnecting(true);
46
+ setError(null);
47
+ const origin = getCallbackOrigin() || window.location.origin;
48
+ window.open(new URL(agentNativePath("/_agent-native/builder/connect"), origin).href, "_blank", "noopener,noreferrer");
49
+ const start = Date.now();
50
+ pollRef.current = setInterval(async () => {
51
+ try {
52
+ const r = await fetch(agentNativePath("/_agent-native/builder/status"));
53
+ if (!r.ok)
54
+ return;
55
+ const s = (await r.json());
56
+ if (!mountedRef.current) {
57
+ clearInterval(pollRef.current);
58
+ return;
59
+ }
60
+ if (s.configured) {
61
+ clearInterval(pollRef.current);
62
+ setConfigured(true);
63
+ setConnecting(false);
64
+ }
65
+ else if (Date.now() - start > 5 * 60 * 1000) {
66
+ clearInterval(pollRef.current);
67
+ setConnecting(false);
68
+ setError("Didn't hear back from Builder. Allow popups and try again.");
69
+ }
70
+ }
71
+ catch {
72
+ // transient — keep polling
73
+ }
74
+ }, 2000);
75
+ }, []);
76
+ // Already connected or still loading — render nothing
77
+ if (configured === null || configured)
15
78
  return null;
16
- return (_jsxs("div", { className: "flex items-center gap-2 rounded-md border border-border/50 bg-muted/30 px-3 py-2 text-xs text-muted-foreground", children: [_jsx(IconArrowUp, { size: 16, className: "shrink-0 text-muted-foreground/70", "aria-hidden": "true" }), _jsx("span", { children: "Connect Builder.io for higher-quality transcription" }), _jsx("span", { className: "ml-auto shrink-0 rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground/60", children: "Coming soon" })] }));
79
+ return (_jsxs("div", { className: "flex items-center gap-2 rounded-md border border-border/50 bg-muted/30 px-3 py-2 text-xs text-muted-foreground", children: [_jsx(IconBolt, { size: 14, className: "shrink-0 text-muted-foreground/70", "aria-hidden": "true" }), _jsx("span", { className: "flex-1", children: connecting
80
+ ? "Waiting for Builder.io…"
81
+ : "Connect Builder.io for higher-quality transcription — free, no API key needed." }), error ? (_jsx("span", { className: "text-destructive text-[10px]", children: error })) : connecting ? (_jsx(IconLoader2, { size: 12, className: "shrink-0 animate-spin" })) : (_jsxs("button", { type: "button", onClick: handleConnect, className: "ml-auto shrink-0 inline-flex items-center gap-1 rounded bg-foreground px-2 py-1 text-[10px] font-semibold text-background hover:opacity-90 transition-opacity", children: ["Connect", _jsx(IconExternalLink, { size: 10 })] }))] }));
17
82
  }
18
83
  //# sourceMappingURL=BuilderTranscriptionCta.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BuilderTranscriptionCta.js","sourceRoot":"","sources":["../../../src/client/transcription/BuilderTranscriptionCta.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,MAAM,UAAU,uBAAuB;IACrC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAE/C,uDAAuD;IACvD,IAAI,OAAO,IAAI,MAAM,EAAE,UAAU;QAAE,OAAO,IAAI,CAAC;IAE/C,OAAO,CACL,eAAK,SAAS,EAAC,gHAAgH,aAC7H,KAAC,WAAW,IACV,IAAI,EAAE,EAAE,EACR,SAAS,EAAC,mCAAmC,iBACjC,MAAM,GAClB,EACF,iFAAgE,EAChE,eAAM,SAAS,EAAC,0HAA0H,4BAEnI,IACH,CACP,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Lightweight inline CTA that nudges users to connect Builder.io for\n * higher-quality transcription. Renders nothing when Builder is already\n * connected.\n *\n * Drop this next to transcript displays in any template.\n */\n\nimport { IconArrowUp } from \"@tabler/icons-react\";\nimport { useBuilderStatus } from \"../settings/useBuilderStatus.js\";\n\nexport function BuilderTranscriptionCta() {\n const { status, loading } = useBuilderStatus();\n\n // Still loading or already connected — render nothing.\n if (loading || status?.configured) return null;\n\n return (\n <div className=\"flex items-center gap-2 rounded-md border border-border/50 bg-muted/30 px-3 py-2 text-xs text-muted-foreground\">\n <IconArrowUp\n size={16}\n className=\"shrink-0 text-muted-foreground/70\"\n aria-hidden=\"true\"\n />\n <span>Connect Builder.io for higher-quality transcription</span>\n <span className=\"ml-auto shrink-0 rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground/60\">\n Coming soon\n </span>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"BuilderTranscriptionCta.js","sourceRoot":"","sources":["../../../src/client/transcription/BuilderTranscriptionCta.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lightweight inline CTA that nudges users to connect Builder.io for\n * higher-quality transcription. Renders nothing when Builder is already\n * connected.\n *\n * Drop this next to transcript displays in any template.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { IconBolt, IconExternalLink, IconLoader2 } from \"@tabler/icons-react\";\nimport { agentNativePath } from \"../api-path.js\";\nimport { getCallbackOrigin } from \"../frame.js\";\n\nexport function BuilderTranscriptionCta() {\n const [configured, setConfigured] = useState<boolean | null>(null);\n const [connecting, setConnecting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const mountedRef = useRef(true);\n\n useEffect(() => {\n mountedRef.current = true;\n fetch(agentNativePath(\"/_agent-native/builder/status\"))\n .then((r) =>\n r.ok\n ? (r.json() as Promise<{ configured: boolean; envManaged?: boolean }>)\n : null,\n )\n .then((s) => {\n if (!mountedRef.current) return;\n // Env-managed mode counts as configured for the CTA — the deploy\n // already routes transcription through Builder, no per-user prompt.\n setConfigured(!!(s?.configured || s?.envManaged));\n })\n .catch(() => {\n if (mountedRef.current) setConfigured(false);\n });\n return () => {\n mountedRef.current = false;\n if (pollRef.current) clearInterval(pollRef.current);\n };\n }, []);\n\n const handleConnect = useCallback(() => {\n if (pollRef.current) clearInterval(pollRef.current);\n setConnecting(true);\n setError(null);\n\n const origin = getCallbackOrigin() || window.location.origin;\n window.open(\n new URL(agentNativePath(\"/_agent-native/builder/connect\"), origin).href,\n \"_blank\",\n \"noopener,noreferrer\",\n );\n\n const start = Date.now();\n pollRef.current = setInterval(async () => {\n try {\n const r = await fetch(agentNativePath(\"/_agent-native/builder/status\"));\n if (!r.ok) return;\n const s = (await r.json()) as { configured: boolean };\n if (!mountedRef.current) {\n clearInterval(pollRef.current!);\n return;\n }\n if (s.configured) {\n clearInterval(pollRef.current!);\n setConfigured(true);\n setConnecting(false);\n } else if (Date.now() - start > 5 * 60 * 1000) {\n clearInterval(pollRef.current!);\n setConnecting(false);\n setError(\n \"Didn't hear back from Builder. Allow popups and try again.\",\n );\n }\n } catch {\n // transient keep polling\n }\n }, 2000);\n }, []);\n\n // Already connected or still loading — render nothing\n if (configured === null || configured) return null;\n\n return (\n <div className=\"flex items-center gap-2 rounded-md border border-border/50 bg-muted/30 px-3 py-2 text-xs text-muted-foreground\">\n <IconBolt\n size={14}\n className=\"shrink-0 text-muted-foreground/70\"\n aria-hidden=\"true\"\n />\n <span className=\"flex-1\">\n {connecting\n ? \"Waiting for Builder.io…\"\n : \"Connect Builder.io for higher-quality transcription — free, no API key needed.\"}\n </span>\n {error ? (\n <span className=\"text-destructive text-[10px]\">{error}</span>\n ) : connecting ? (\n <IconLoader2 size={12} className=\"shrink-0 animate-spin\" />\n ) : (\n <button\n type=\"button\"\n onClick={handleConnect}\n className=\"ml-auto shrink-0 inline-flex items-center gap-1 rounded bg-foreground px-2 py-1 text-[10px] font-semibold text-background hover:opacity-90 transition-opacity\"\n >\n Connect\n <IconExternalLink size={10} />\n </button>\n )}\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"use-send-to-agent-chat.d.ts","sourceRoot":"","sources":["../../src/client/use-send-to-agent-chat.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAKzE;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,IAAI,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,MAAM,GAAG,IAAI,CAAC;IAChD,YAAY,EAAE,OAAO,CAAC;IACtB,+DAA+D;IAC/D,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE,KAAK,CAAC,SAAS,CAAC;CACrC,CAoDA"}
1
+ {"version":3,"file":"use-send-to-agent-chat.d.ts","sourceRoot":"","sources":["../../src/client/use-send-to-agent-chat.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAMzE;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,IAAI,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,MAAM,GAAG,IAAI,CAAC;IAChD,YAAY,EAAE,OAAO,CAAC;IACtB,+DAA+D;IAC/D,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE,KAAK,CAAC,SAAS,CAAC;CACrC,CA2DA"}
@@ -2,6 +2,7 @@ import { useState, useEffect, useCallback, createElement } from "react";
2
2
  import { sendToAgentChat } from "./agent-chat.js";
3
3
  import { useAgentChatGenerating } from "./use-agent-chat.js";
4
4
  import { isInFrame, isTrustedFrameMessage } from "./frame.js";
5
+ import { isInBuilderFrame, isTrustedBuilderMessage } from "./builder-frame.js";
5
6
  import { CodeRequiredDialog } from "./components/CodeRequiredDialog.js";
6
7
  /**
7
8
  * Wraps sendToAgentChat with code-request gating.
@@ -24,11 +25,18 @@ export function useSendToAgentChat() {
24
25
  if (!codeAgentWorking)
25
26
  return;
26
27
  function handler(event) {
27
- if (!isTrustedFrameMessage(event))
28
+ const fromAgentFrame = isTrustedFrameMessage(event);
29
+ const fromBuilderFrame = isTrustedBuilderMessage(event);
30
+ if (!fromAgentFrame && !fromBuilderFrame)
28
31
  return;
32
+ const runningDetail = event.data?.detail ?? event.data?.data;
29
33
  if (event.data?.type === "agentNative.codeComplete" ||
34
+ (fromBuilderFrame && event.data?.type === "builder.codeComplete") ||
30
35
  (event.data?.type === "agentNative.chatRunning" &&
31
- !event.data?.detail?.isRunning)) {
36
+ !runningDetail?.isRunning) ||
37
+ (fromBuilderFrame &&
38
+ event.data?.type === "builder.chatRunning" &&
39
+ !runningDetail?.isRunning)) {
32
40
  setCodeAgentWorking(false);
33
41
  }
34
42
  }
@@ -37,7 +45,7 @@ export function useSendToAgentChat() {
37
45
  }, [codeAgentWorking]);
38
46
  const send = useCallback((opts) => {
39
47
  const isCodeRequest = opts.type === "code" || opts.requiresCode === true;
40
- if (isCodeRequest && !isInFrame()) {
48
+ if (isCodeRequest && !isInFrame() && !isInBuilderFrame()) {
41
49
  setFeatureLabel(opts.message?.slice(0, 80));
42
50
  setDialogOpen(true);
43
51
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"use-send-to-agent-chat.js","sourceRoot":"","sources":["../../src/client/use-send-to-agent-chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,eAAe,EAAyB,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAExE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB;IAOhC,MAAM,CAAC,eAAe,CAAC,GAAG,sBAAsB,EAAE,CAAC;IACnD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,EAAsB,CAAC;IACvE,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEhE,wCAAwC;IACxC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAC9B,SAAS,OAAO,CAAC,KAAmB;YAClC,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC;gBAAE,OAAO;YAC1C,IACE,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,0BAA0B;gBAC/C,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,yBAAyB;oBAC7C,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EACjC,CAAC;gBACD,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC5C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,IAAsB,EAAiB,EAAE;QACjE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC;QAEzE,IAAI,aAAa,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YAClC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAC5C,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACnC,CAAC;QAED,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,MAAM,GAAG,aAAa,CAAC,kBAAkB,EAAE;QAC/C,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC;QACnC,YAAY;KACb,CAAC,CAAC;IAEH,OAAO;QACL,IAAI;QACJ,YAAY,EAAE,eAAe;QAC7B,kBAAkB,EAAE,gBAAgB;QACpC,kBAAkB,EAAE,MAAM;KAC3B,CAAC;AACJ,CAAC","sourcesContent":["import { useState, useEffect, useCallback, createElement } from \"react\";\nimport { sendToAgentChat, type AgentChatMessage } from \"./agent-chat.js\";\nimport { useAgentChatGenerating } from \"./use-agent-chat.js\";\nimport { isInFrame, isTrustedFrameMessage } from \"./frame.js\";\nimport { CodeRequiredDialog } from \"./components/CodeRequiredDialog.js\";\n\n/**\n * Wraps sendToAgentChat with code-request gating.\n *\n * When a message has `type: \"code\"` (or `requiresCode: true`) and no\n * frame is connected, shows a dialog explaining code changes need a\n * dev frame. When a frame IS connected, the message is sent to the\n * frame and a code-agent indicator is shown.\n *\n * Returns a `codeRequiredDialog` React element that must be rendered\n * somewhere in the consumer's JSX tree.\n */\nexport function useSendToAgentChat(): {\n send: (opts: AgentChatMessage) => string | null;\n isGenerating: boolean;\n /** True when a code request is being processed by the frame */\n isCodeAgentWorking: boolean;\n codeRequiredDialog: React.ReactNode;\n} {\n const [agentGenerating] = useAgentChatGenerating();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [featureLabel, setFeatureLabel] = useState<string | undefined>();\n const [codeAgentWorking, setCodeAgentWorking] = useState(false);\n\n // Listen for code completion from frame\n useEffect(() => {\n if (!codeAgentWorking) return;\n function handler(event: MessageEvent) {\n if (!isTrustedFrameMessage(event)) return;\n if (\n event.data?.type === \"agentNative.codeComplete\" ||\n (event.data?.type === \"agentNative.chatRunning\" &&\n !event.data?.detail?.isRunning)\n ) {\n setCodeAgentWorking(false);\n }\n }\n window.addEventListener(\"message\", handler);\n return () => window.removeEventListener(\"message\", handler);\n }, [codeAgentWorking]);\n\n const send = useCallback((opts: AgentChatMessage): string | null => {\n const isCodeRequest = opts.type === \"code\" || opts.requiresCode === true;\n\n if (isCodeRequest && !isInFrame()) {\n setFeatureLabel(opts.message?.slice(0, 80));\n setDialogOpen(true);\n return null;\n }\n\n if (isCodeRequest) {\n setCodeAgentWorking(true);\n opts = { ...opts, type: \"code\" };\n }\n\n return sendToAgentChat(opts);\n }, []);\n\n const dialog = createElement(CodeRequiredDialog, {\n open: dialogOpen,\n onClose: () => setDialogOpen(false),\n featureLabel,\n });\n\n return {\n send,\n isGenerating: agentGenerating,\n isCodeAgentWorking: codeAgentWorking,\n codeRequiredDialog: dialog,\n };\n}\n"]}
1
+ {"version":3,"file":"use-send-to-agent-chat.js","sourceRoot":"","sources":["../../src/client/use-send-to-agent-chat.ts"],"names":[],"mappings":"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","sourcesContent":["import { useState, useEffect, useCallback, createElement } from \"react\";\nimport { sendToAgentChat, type AgentChatMessage } from \"./agent-chat.js\";\nimport { useAgentChatGenerating } from \"./use-agent-chat.js\";\nimport { isInFrame, isTrustedFrameMessage } from \"./frame.js\";\nimport { isInBuilderFrame, isTrustedBuilderMessage } from \"./builder-frame.js\";\nimport { CodeRequiredDialog } from \"./components/CodeRequiredDialog.js\";\n\n/**\n * Wraps sendToAgentChat with code-request gating.\n *\n * When a message has `type: \"code\"` (or `requiresCode: true`) and no\n * frame is connected, shows a dialog explaining code changes need a\n * dev frame. When a frame IS connected, the message is sent to the\n * frame and a code-agent indicator is shown.\n *\n * Returns a `codeRequiredDialog` React element that must be rendered\n * somewhere in the consumer's JSX tree.\n */\nexport function useSendToAgentChat(): {\n send: (opts: AgentChatMessage) => string | null;\n isGenerating: boolean;\n /** True when a code request is being processed by the frame */\n isCodeAgentWorking: boolean;\n codeRequiredDialog: React.ReactNode;\n} {\n const [agentGenerating] = useAgentChatGenerating();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [featureLabel, setFeatureLabel] = useState<string | undefined>();\n const [codeAgentWorking, setCodeAgentWorking] = useState(false);\n\n // Listen for code completion from frame\n useEffect(() => {\n if (!codeAgentWorking) return;\n function handler(event: MessageEvent) {\n const fromAgentFrame = isTrustedFrameMessage(event);\n const fromBuilderFrame = isTrustedBuilderMessage(event);\n if (!fromAgentFrame && !fromBuilderFrame) return;\n const runningDetail = event.data?.detail ?? event.data?.data;\n if (\n event.data?.type === \"agentNative.codeComplete\" ||\n (fromBuilderFrame && event.data?.type === \"builder.codeComplete\") ||\n (event.data?.type === \"agentNative.chatRunning\" &&\n !runningDetail?.isRunning) ||\n (fromBuilderFrame &&\n event.data?.type === \"builder.chatRunning\" &&\n !runningDetail?.isRunning)\n ) {\n setCodeAgentWorking(false);\n }\n }\n window.addEventListener(\"message\", handler);\n return () => window.removeEventListener(\"message\", handler);\n }, [codeAgentWorking]);\n\n const send = useCallback((opts: AgentChatMessage): string | null => {\n const isCodeRequest = opts.type === \"code\" || opts.requiresCode === true;\n\n if (isCodeRequest && !isInFrame() && !isInBuilderFrame()) {\n setFeatureLabel(opts.message?.slice(0, 80));\n setDialogOpen(true);\n return null;\n }\n\n if (isCodeRequest) {\n setCodeAgentWorking(true);\n opts = { ...opts, type: \"code\" };\n }\n\n return sendToAgentChat(opts);\n }, []);\n\n const dialog = createElement(CodeRequiredDialog, {\n open: dialogOpen,\n onClose: () => setDialogOpen(false),\n featureLabel,\n });\n\n return {\n send,\n isGenerating: agentGenerating,\n isCodeAgentWorking: codeAgentWorking,\n codeRequiredDialog: dialog,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"useProductionAgent.d.ts","sourceRoot":"","sources":["../../src/client/useProductionAgent.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,yBAAyB;IACxC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,CAChC,OAAO,CAAC,EAAE,yBAAyB,GAClC,wBAAwB,CAiN1B"}
1
+ {"version":3,"file":"useProductionAgent.d.ts","sourceRoot":"","sources":["../../src/client/useProductionAgent.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,yBAAyB;IACxC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,CAChC,OAAO,CAAC,EAAE,yBAAyB,GAClC,wBAAwB,CAkN1B"}
@@ -137,7 +137,7 @@ export function useProductionAgent(options) {
137
137
  }
138
138
  else if (ev.type === "done" || ev.type === "error") {
139
139
  if (ev.type === "error") {
140
- const fallbackContent = formatChatErrorText(ev.error ?? "Unknown error", ev.upgradeUrl);
140
+ const fallbackContent = formatChatErrorText(ev.error ?? "Unknown error", ev.upgradeUrl, ev.errorCode);
141
141
  setMessages((prev) => prev.map((m) => m.id === assistantId
142
142
  ? { ...m, content: m.content || fallbackContent }
143
143
  : m));