@agent-native/core 0.153.1 → 0.153.4

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 (41) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +21 -19
  3. package/corpus/templates/analytics/AGENTS.md +4 -0
  4. package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -0
  5. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +0 -11
  6. package/corpus/templates/clips/app/components/player/share-dialog.tsx +32 -33
  7. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +29 -39
  8. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +0 -1
  9. package/corpus/templates/clips/desktop/src/app.tsx +817 -441
  10. package/corpus/templates/clips/desktop/src/styles.css +234 -0
  11. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
  12. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +593 -7
  13. package/corpus/templates/clips/desktop/src-tauri/src/rewind_clip.rs +95 -10
  14. package/corpus/templates/forms/AGENTS.md +6 -0
  15. package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -0
  16. package/corpus/templates/mail/AGENTS.md +5 -4
  17. package/corpus/templates/mail/actions/get-automation-settings.ts +17 -6
  18. package/corpus/templates/mail/actions/send-email.ts +17 -9
  19. package/corpus/templates/mail/actions/send-queued-drafts.ts +21 -11
  20. package/corpus/templates/mail/actions/update-automation-settings.ts +20 -6
  21. package/corpus/templates/mail/app/i18n/en-US.ts +5 -0
  22. package/corpus/templates/mail/app/pages/SettingsPage.tsx +68 -7
  23. package/corpus/templates/mail/server/lib/automation-settings.ts +27 -0
  24. package/corpus/templates/mail/server/plugins/agent-chat.ts +2 -0
  25. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +3 -3
  26. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +17 -4
  27. package/corpus/templates/slides/app/context/DeckContext.tsx +3 -2
  28. package/corpus/templates/slides/app/pages/DeckEditor.tsx +44 -0
  29. package/corpus/templates/slides/changelog/2026-08-12-arrow-key-navigation-in-the-slide-film-strip-now-scrolls-sli.md +6 -0
  30. package/corpus/templates/slides/changelog/2026-08-12-duplicate-a-slide-from-the-film-strip-with-cmd-ctrl-c-then-c.md +6 -0
  31. package/corpus/templates/slides/changelog/2026-08-12-presenting-a-deck-now-returns-you-to-the-slide-you-were-view.md +6 -0
  32. package/dist/client/resources/mcp-integration-catalog.d.ts +7 -0
  33. package/dist/client/resources/mcp-integration-catalog.js +14 -1
  34. package/dist/client/settings/AgentsSection.js +46 -30
  35. package/dist/client/sharing/ShareDialog.js +4 -2
  36. package/dist/collab/awareness.d.ts +2 -2
  37. package/dist/observability/routes.d.ts +5 -5
  38. package/dist/secrets/routes.d.ts +9 -9
  39. package/dist/server/agent-chat-plugin.js +1 -0
  40. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  41. package/package.json +1 -1
@@ -239,6 +239,17 @@ export default function PresentationView({
239
239
 
240
240
  const isShared = deckId.startsWith("__shared__/");
241
241
 
242
+ // Exit handlers read these instead of closing over `currentIndex`/`deckId`/
243
+ // `isShared` so the mount-only fullscreenchange listener still lands on the
244
+ // right deck and slide even if this component is reused for a different
245
+ // deck without remounting (e.g. an agent-driven navigation).
246
+ const currentIndexRef = useRef(currentIndex);
247
+ currentIndexRef.current = currentIndex;
248
+ const deckIdRef = useRef(deckId);
249
+ deckIdRef.current = deckId;
250
+ const isSharedRef = useRef(isShared);
251
+ isSharedRef.current = isShared;
252
+
242
253
  useEffect(() => {
243
254
  setCurrentIndex((prev) => clampIndex(prev));
244
255
  setPrevIndex((prev) =>
@@ -348,7 +359,7 @@ export default function PresentationView({
348
359
  const token = deckId.replace("__shared__/", "");
349
360
  navigate(`/share/${token}`);
350
361
  } else {
351
- navigate(`/deck/${deckId}`);
362
+ navigate(`/deck/${deckId}?slide=${currentIndexRef.current + 1}`);
352
363
  }
353
364
  }, [navigate, deckId, isShared]);
354
365
 
@@ -465,11 +476,13 @@ export default function PresentationView({
465
476
  // fullscreen first — otherwise the gesture-fallback overlay handles it.
466
477
  if (enteredFullscreenRef.current && !document.fullscreenElement) {
467
478
  enteredFullscreenRef.current = false;
468
- if (isShared) {
469
- const token = deckId.replace("__shared__/", "");
479
+ if (isSharedRef.current) {
480
+ const token = deckIdRef.current.replace("__shared__/", "");
470
481
  navigate(`/share/${token}`);
471
482
  } else {
472
- navigate(`/deck/${deckId}`);
483
+ navigate(
484
+ `/deck/${deckIdRef.current}?slide=${currentIndexRef.current + 1}`,
485
+ );
473
486
  }
474
487
  }
475
488
  };
@@ -223,7 +223,7 @@ interface DeckContextType {
223
223
  options?: UpdateSlideOptions,
224
224
  ) => void;
225
225
  deleteSlide: (deckId: string, slideId: string) => void;
226
- duplicateSlide: (deckId: string, slideId: string) => void;
226
+ duplicateSlide: (deckId: string, slideId: string) => string | undefined;
227
227
  reorderSlides: (deckId: string, oldIndex: number, newIndex: number) => void;
228
228
  setDeckSlides: (deckId: string, slides: Slide[]) => void;
229
229
  /**
@@ -2223,7 +2223,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
2223
2223
  (deckId: string, slideId: string) => {
2224
2224
  const before = decksRef.current.find((d) => d.id === deckId);
2225
2225
  const original = before?.slides.find((slide) => slide.id === slideId);
2226
- if (!before || !original) return;
2226
+ if (!before || !original) return undefined;
2227
2227
 
2228
2228
  markDeckDirty(deckId);
2229
2229
  const copiedSlide: Slide = { ...original, id: nanoid(8) };
@@ -2254,6 +2254,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
2254
2254
  };
2255
2255
  enqueueDeckOp(deckId, op);
2256
2256
  recordUndo(before, op, { label: "Duplicate slide" });
2257
+ return copiedSlide.id;
2257
2258
  },
2258
2259
  [markDeckDirty, recordUndo, setDecksLocal],
2259
2260
  );
@@ -807,6 +807,50 @@ export default function DeckEditor() {
807
807
  return () => document.removeEventListener("keydown", handleKeyDown);
808
808
  }, [deck, id, activeSlideId, deleteSlideWithUndo, pinMode, drawMode]);
809
809
 
810
+ // Cmd/Ctrl+C then Cmd/Ctrl+V duplicates a slide thumbnail in the film
811
+ // strip. Scoped to an actually-focused thumbnail (rather than "no other
812
+ // handler claimed it", like the Delete-key handler below) so the shortcut
813
+ // can't fire from an unrelated toolbar button, dialog, or menu.
814
+ const copiedSlideIdRef = useRef<string | null>(null);
815
+ useEffect(() => {
816
+ const handleKeyDown = (e: KeyboardEvent) => {
817
+ if (!deck || !id) return;
818
+ if (!(e.metaKey || e.ctrlKey) || e.altKey) return;
819
+ const key = e.key.toLowerCase();
820
+ if (key !== "c" && key !== "v") return;
821
+ if (pinMode || drawMode) return;
822
+ if (
823
+ document.querySelector(
824
+ "[role='dialog'], [role='menu'], [role='listbox']",
825
+ )
826
+ ) {
827
+ return;
828
+ }
829
+ if (!canEdit) return;
830
+ const focusedThumbnail = document.activeElement?.closest(
831
+ "[data-slide-thumbnail-id]",
832
+ );
833
+ if (!focusedThumbnail) return;
834
+ const focusedSlideId = focusedThumbnail.getAttribute(
835
+ "data-slide-thumbnail-id",
836
+ );
837
+ if (!focusedSlideId) return;
838
+
839
+ if (key === "c") {
840
+ copiedSlideIdRef.current = focusedSlideId;
841
+ return;
842
+ }
843
+ const copiedSlideId = copiedSlideIdRef.current;
844
+ if (!copiedSlideId) return;
845
+ if (!deck.slides.some((s) => s.id === copiedSlideId)) return;
846
+ e.preventDefault();
847
+ const newSlideId = duplicateSlide(id, copiedSlideId);
848
+ if (newSlideId) setActiveSlideId(newSlideId);
849
+ };
850
+ document.addEventListener("keydown", handleKeyDown);
851
+ return () => document.removeEventListener("keydown", handleKeyDown);
852
+ }, [deck, id, duplicateSlide, canEdit, pinMode, drawMode]);
853
+
810
854
  // Resolve the active slide from URL/deck state. Imports replace slide IDs, so
811
855
  // keep this valid after deck contents change instead of only on first load.
812
856
  // Track the last URL ?slide param we processed so we can tell "the URL changed
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-12
4
+ ---
5
+
6
+ Arrow-key navigation in the slide film strip now scrolls slides below the fold into view
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-08-12
4
+ ---
5
+
6
+ Duplicate a slide from the film strip with Cmd/Ctrl+C then Cmd/Ctrl+V
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-12
4
+ ---
5
+
6
+ Presenting a deck now returns you to the slide you were viewing when you exit
@@ -39,6 +39,13 @@ export interface DefaultMcpIntegration {
39
39
  brandAliases?: string[];
40
40
  aliases?: string[];
41
41
  keywords: string[];
42
+ /**
43
+ * Overrides `name` for prose intent matching in `findMcpIntegrationForText`
44
+ * when the display name is a common English word (e.g. "Box") that would
45
+ * otherwise false-positive on unrelated text. Leave unset unless the name
46
+ * itself is the ambiguous term; `brandAliases` still apply.
47
+ */
48
+ promptAliases?: string[];
42
49
  }
43
50
  export interface McpIntegrationFormDefaults {
44
51
  name: string;
@@ -675,6 +675,16 @@ export const DEFAULT_MCP_INTEGRATIONS = [
675
675
  docsUrl: "https://developer.box.com/guides/box-mcp",
676
676
  setupNoteKey: "mcpIntegrations.catalog.box.setupNote",
677
677
  keywords: ["files", "folders", "documents", "enterprise content"],
678
+ // "Box" alone collides with everyday nouns (text box, checkbox, bounding
679
+ // box), so require a qualified phrase before suggesting the connection.
680
+ promptAliases: [
681
+ "Box.com",
682
+ "Box file",
683
+ "Box files",
684
+ "Box folder",
685
+ "Box folders",
686
+ "Box drive",
687
+ ],
678
688
  },
679
689
  {
680
690
  id: "builder-cms",
@@ -947,7 +957,10 @@ export function findMcpIntegrationForText(text, integrations = getDefaultMcpInte
947
957
  isMcpConnectionFailureText(normalizedText);
948
958
  if (!hasResourceIntent)
949
959
  return null;
950
- const matchesCanonicalName = (integration) => [integration.name, ...(integration.brandAliases ?? [])].some((alias) => textContainsTerm(normalizedText, alias));
960
+ const matchesCanonicalName = (integration) => [
961
+ ...(integration.promptAliases ?? [integration.name]),
962
+ ...(integration.brandAliases ?? []),
963
+ ].some((alias) => textContainsTerm(normalizedText, alias));
951
964
  const canonicalMatch = integrations.find(matchesCanonicalName);
952
965
  if (canonicalMatch)
953
966
  return canonicalMatch;
@@ -165,12 +165,20 @@ function AgentAddPopover({ initialName = "", initialUrl = "", initialDescription
165
165
  if (!trimmedName || !trimmedUrl)
166
166
  return;
167
167
  const trimmedDescription = description.trim();
168
- const ok = await onAdd(trimmedName, trimmedUrl, trimmedDescription);
169
- if (ok) {
170
- setAdded({
171
- name: trimmedName,
172
- url: trimmedUrl,
173
- description: trimmedDescription,
168
+ try {
169
+ const ok = await onAdd(trimmedName, trimmedUrl, trimmedDescription);
170
+ if (ok) {
171
+ setAdded({
172
+ name: trimmedName,
173
+ url: trimmedUrl,
174
+ description: trimmedDescription,
175
+ });
176
+ }
177
+ }
178
+ catch (error) {
179
+ setCheck({
180
+ status: "error",
181
+ message: error instanceof Error ? error.message : "Could not add agent",
174
182
  });
175
183
  }
176
184
  };
@@ -236,8 +244,12 @@ export function AgentsSection() {
236
244
  const [showAdd, setShowAdd] = useState(false);
237
245
  const [prefill, setPrefill] = useState(null);
238
246
  const [probeById, setProbeById] = useState(null);
239
- const { data: org } = useOrg();
247
+ const orgQuery = useOrg();
248
+ const { data: org } = orgQuery;
240
249
  const syncSecret = useSyncA2ASecret();
250
+ const canManageSharedAgents = !orgQuery.isLoading &&
251
+ !orgQuery.isError &&
252
+ (!org?.orgId || org.role === "owner" || org.role === "admin");
241
253
  // Landing from a peer's "register back" deep link (see
242
254
  // buildPeerRegisterBackLink): the open route only echoes `f_*` params onto
243
255
  // the redirect URL, so read those here and open the Add popover prefilled.
@@ -343,26 +355,30 @@ export function AgentsSection() {
343
355
  url,
344
356
  color: "#6B7280",
345
357
  }, null, 2);
346
- try {
347
- const res = await fetch(agentNativePath("/_agent-native/resources"), {
348
- method: "POST",
349
- headers: { "Content-Type": "application/json" },
350
- body: JSON.stringify({
351
- path: remoteAgentResourcePath(id),
352
- content: agentJson,
353
- shared: true,
354
- }),
355
- });
356
- // Deliberately don't close the popover here — a successful add shows a
357
- // follow-up state (registration is one-way; the peer doesn't know
358
- // about us yet) that the user dismisses explicitly.
359
- if (res.ok)
360
- fetchAgents();
361
- return res.ok;
362
- }
363
- catch {
364
- return false;
358
+ const res = await fetch(agentNativePath("/_agent-native/resources"), {
359
+ method: "POST",
360
+ headers: { "Content-Type": "application/json" },
361
+ body: JSON.stringify({
362
+ path: remoteAgentResourcePath(id),
363
+ content: agentJson,
364
+ shared: true,
365
+ }),
366
+ });
367
+ if (!res.ok) {
368
+ let body;
369
+ try {
370
+ body = (await res.json());
371
+ }
372
+ catch {
373
+ throw new Error(`Add failed (${res.status})`);
374
+ }
375
+ throw new Error(body?.error ?? body?.message ?? `Add failed (${res.status})`);
365
376
  }
377
+ // Deliberately don't close the popover here — a successful add shows a
378
+ // follow-up state (registration is one-way; the peer doesn't know
379
+ // about us yet) that the user dismisses explicitly.
380
+ fetchAgents();
381
+ return true;
366
382
  };
367
383
  const handleSave = async (agent) => {
368
384
  const agentJson = JSON.stringify({
@@ -398,13 +414,13 @@ export function AgentsSection() {
398
414
  }
399
415
  catch { }
400
416
  };
401
- return (_jsxs("div", { children: [_jsx("div", { className: "mb-3 flex flex-wrap items-center justify-end gap-3", children: _jsxs("div", { className: "relative", children: [_jsxs("button", { onClick: () => {
417
+ return (_jsxs("div", { children: [_jsx("div", { className: "mb-3 flex flex-wrap items-center justify-end gap-3", children: canManageSharedAgents ? (_jsxs("div", { className: "relative", children: [_jsxs("button", { onClick: () => {
402
418
  setShowAdd(!showAdd);
403
419
  setEditingAgent(null);
404
420
  }, className: "inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-1.5 text-xs font-medium text-foreground hover:bg-accent", children: [showAdd ? _jsx(IconX, { size: 13 }) : _jsx(IconPlus, { size: 13 }), showAdd ? "Cancel" : "Connect agent"] }), showAdd && (_jsx(AgentAddPopover, { initialName: prefill?.name, initialUrl: prefill?.url, initialDescription: prefill?.description, secretSet: org?.a2aSecretSet, syncSecret: syncSecret, onAdd: handleAdd, onClose: () => {
405
421
  setShowAdd(false);
406
422
  setPrefill(null);
407
- } }))] }) }), _jsx(A2ASecretStatusRow, { org: org, syncSecret: syncSecret }), loading ? (_jsxs("div", { className: "space-y-1.5", role: "status", "aria-busy": "true", "aria-label": "Loading connected agents", children: [_jsx(Skeleton, { className: "h-6 w-full bg-muted/50" }), _jsx(Skeleton, { className: "h-6 w-3/4 bg-muted/50" })] })) : agents.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center rounded-xl border border-border/70 bg-card px-5 py-8 text-center", children: [_jsx("span", { className: "mb-2 flex size-9 items-center justify-center rounded-full bg-muted text-muted-foreground", children: _jsx(IconTopologyRing2, { size: 17 }) }), _jsx("p", { className: "text-sm font-medium text-foreground", children: "No connected agents yet" }), _jsx("p", { className: "mt-1 max-w-sm text-xs leading-5 text-muted-foreground", children: "Connect an A2A agent to delegate work from chat." }), _jsxs("button", { onClick: () => setShowAdd(true), className: "mt-4 inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-1.5 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconPlus, { size: 13 }), "Connect agent"] })] })) : (_jsx("div", { className: "overflow-hidden rounded-xl border border-border/70 bg-card text-card-foreground", children: _jsx("div", { className: "divide-y divide-border/60 px-4", children: agents.map((agent) => {
423
+ } }))] })) : !orgQuery.isLoading ? (_jsx("span", { className: "text-[10px] text-muted-foreground", children: "Only workspace owners and admins can connect agents." })) : null }), _jsx(A2ASecretStatusRow, { org: org, syncSecret: syncSecret }), loading ? (_jsxs("div", { className: "space-y-1.5", role: "status", "aria-busy": "true", "aria-label": "Loading connected agents", children: [_jsx(Skeleton, { className: "h-6 w-full bg-muted/50" }), _jsx(Skeleton, { className: "h-6 w-3/4 bg-muted/50" })] })) : agents.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center rounded-xl border border-border/70 bg-card px-5 py-8 text-center", children: [_jsx("span", { className: "mb-2 flex size-9 items-center justify-center rounded-full bg-muted text-muted-foreground", children: _jsx(IconTopologyRing2, { size: 17 }) }), _jsx("p", { className: "text-sm font-medium text-foreground", children: "No connected agents yet" }), _jsx("p", { className: "mt-1 max-w-sm text-xs leading-5 text-muted-foreground", children: "Connect an A2A agent to delegate work from chat." }), canManageSharedAgents ? (_jsxs("button", { onClick: () => setShowAdd(true), className: "mt-4 inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-1.5 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconPlus, { size: 13 }), "Connect agent"] })) : !orgQuery.isLoading ? (_jsx("p", { className: "mt-4 text-xs text-muted-foreground", children: "Ask a workspace owner or admin to connect an agent." })) : null] })) : (_jsx("div", { className: "overflow-hidden rounded-xl border border-border/70 bg-card text-card-foreground", children: _jsx("div", { className: "divide-y divide-border/60 px-4", children: agents.map((agent) => {
408
424
  const probe = probeById?.get(getRemoteAgentIdFromPath(agent.path).toLowerCase());
409
425
  const dotState = !probe
410
426
  ? null
@@ -413,9 +429,9 @@ export function AgentsSection() {
413
429
  : "warn";
414
430
  return (_jsxs("div", { className: "group relative", children: [_jsxs("div", { className: "flex w-full items-center gap-3 py-4", children: [_jsx("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-lg border border-border bg-background text-muted-foreground", children: _jsx(IconTopologyRing2, { size: 15 }) }), dotState ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: `h-1.5 w-1.5 shrink-0 rounded-full ${dotState === "ok"
415
431
  ? "bg-primary"
416
- : "bg-destructive"}` }) }), _jsx(TooltipContent, { children: probe && describeProbeTooltip(probe) })] })) : (_jsx("span", { className: "h-1.5 w-1.5 shrink-0 rounded-full bg-transparent" })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate text-sm font-medium text-foreground", children: agent.name }), _jsx("span", { className: "mt-0.5 block truncate text-xs text-muted-foreground", children: agent.url })] }), _jsx("button", { onClick: () => {
432
+ : "bg-destructive"}` }) }), _jsx(TooltipContent, { children: probe && describeProbeTooltip(probe) })] })) : (_jsx("span", { className: "h-1.5 w-1.5 shrink-0 rounded-full bg-transparent" })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate text-sm font-medium text-foreground", children: agent.name }), _jsx("span", { className: "mt-0.5 block truncate text-xs text-muted-foreground", children: agent.url })] }), canManageSharedAgents ? (_jsx("button", { onClick: () => {
417
433
  setEditingAgent(editingAgent === agent.id ? null : agent.id);
418
434
  setShowAdd(false);
419
- }, className: "shrink-0 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium text-foreground hover:bg-accent", children: "Manage" })] }), editingAgent === agent.id && (_jsx(AgentEditPopover, { agent: agent, onSave: handleSave, onDelete: handleDelete, onClose: () => setEditingAgent(null) }))] }, agent.id));
435
+ }, className: "shrink-0 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium text-foreground hover:bg-accent", children: "Manage" })) : null] }), canManageSharedAgents && editingAgent === agent.id && (_jsx(AgentEditPopover, { agent: agent, onSave: handleSave, onDelete: handleDelete, onClose: () => setEditingAgent(null) }))] }, agent.id));
420
436
  }) }) }))] }));
421
437
  }
@@ -37,7 +37,9 @@ export function ShareDialog({ open, onClose, resourceType, resourceId, resourceT
37
37
  });
38
38
  if (!open)
39
39
  return null;
40
- return (_jsxs(DesignSystemDialog, { open: controller.open, onOpenChange: controller.onOpenChange, title: _jsx("span", { className: "truncate !text-base !leading-normal !tracking-normal !text-inherit", title: controller.title, children: controller.title }), closeLabel: controller.labels.close, size: "large", className: "!top-4 !z-[2010] !block !max-h-none !w-[calc(100vw-2rem)] !max-w-lg !translate-y-0 !gap-0 !overflow-visible !rounded-xl !border-border !bg-popover !p-0 !text-popover-foreground !shadow-2xl sm:!top-1/2 sm:!-translate-y-1/2", "aria-label": controller.title, children: [_jsx("div", { className: "px-5 pt-0 pb-3", children: controller.ownerLabel ? (_jsx("div", { className: "truncate text-xs text-muted-foreground", children: controller.ownerLabel })) : null }), controller.tabsEnabled ? (_jsx("div", { role: "tablist", "aria-label": controller.labels.shareOptions, className: "mx-5 mt-1 flex gap-1 border-b border-border", children: controller.tabs.map((tab) => {
40
+ return (_jsxs(DesignSystemDialog, { open: controller.open, onOpenChange: controller.onOpenChange, title: _jsx("span", { className: cn(controller.tabsEnabled
41
+ ? "sr-only"
42
+ : "truncate !text-base !leading-normal !tracking-normal !text-inherit"), title: controller.title, children: controller.title }), closeLabel: controller.labels.close, size: "large", className: "!top-4 !z-[2010] !block !max-h-none !w-[calc(100vw-2rem)] !max-w-lg !translate-y-0 !gap-0 !overflow-visible !rounded-xl !border-border !bg-popover !p-0 !text-popover-foreground !shadow-2xl sm:!top-1/2 sm:!-translate-y-1/2", "aria-label": controller.title, children: [!controller.tabsEnabled && controller.ownerLabel ? (_jsx("div", { className: "px-5 pt-0 pb-3", children: _jsx("div", { className: "truncate text-xs text-muted-foreground", children: controller.ownerLabel }) })) : null, controller.tabsEnabled ? (_jsx("div", { role: "tablist", "aria-label": controller.labels.shareOptions, className: "mx-5 mt-1 flex gap-1 border-b border-border", children: controller.tabs.map((tab) => {
41
43
  const Icon = TAB_ICONS[tab.value];
42
44
  return (_jsx(TabTrigger, { active: controller.activeTab === tab.value, onClick: () => controller.setActiveTab(tab.value), icon: _jsx(Icon, { size: 14, strokeWidth: 1.75 }), label: tab.label }, tab.value));
43
45
  }) })) : null, _jsxs("div", { className: "px-5 py-4", children: [controller.tabsEnabled && controller.activeTab === "link" ? (_jsx(LinkTab, { controller: controller, extras: linkTabExtras })) : null, !controller.tabsEnabled || controller.activeTab === "invite" ? (_jsx(InviteTab, { controller: controller, showVisibility: !controller.tabsEnabled })) : null, controller.tabsEnabled && controller.activeTab === "embed"
@@ -51,7 +53,7 @@ function TabTrigger({ active, onClick, icon, label, }) {
51
53
  }
52
54
  function LinkTab({ controller, extras, }) {
53
55
  const Icon = VIS_ICONS[controller.visibility.value];
54
- return (_jsxs("div", { className: "space-y-3", children: [_jsx(CopyField, { field: "share-link", label: controller.labels.shareLink, value: controller.shareUrl, controller: controller }), _jsxs("div", { children: [_jsx("div", { className: "mb-2 text-sm font-semibold", children: controller.labels.generalAccess }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { "aria-hidden": true, className: "inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground", children: _jsx(Icon, { size: 16, strokeWidth: 1.75 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(VisibilitySelect, { controller: controller }), _jsx("div", { className: "sr-only text-xs text-muted-foreground", children: controller.visibility.description })] })] })] }), extras] }));
56
+ return (_jsxs("div", { className: "space-y-3", children: [_jsx(CopyField, { field: "share-link", label: controller.labels.shareLink, value: controller.shareUrl, controller: controller }), _jsxs("div", { children: [_jsx("div", { className: "mb-2 text-xs font-medium text-muted-foreground", children: controller.labels.generalAccess }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { "aria-hidden": true, className: "inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground", children: _jsx(Icon, { size: 16, strokeWidth: 1.75 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(VisibilitySelect, { controller: controller }), _jsx("div", { className: "sr-only text-xs text-muted-foreground", children: controller.visibility.description })] })] })] }), extras] }));
55
57
  }
56
58
  function InviteTab({ controller, showVisibility, }) {
57
59
  const Icon = VIS_ICONS[controller.visibility.value];
@@ -62,11 +62,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
62
62
  error: string;
63
63
  states?: undefined;
64
64
  } | {
65
+ error?: undefined;
65
66
  states: {
66
67
  clientId: number;
67
68
  state: string;
68
69
  }[];
69
- error?: undefined;
70
70
  }>>;
71
71
  /**
72
72
  * GET /_agent-native/collab/:docId/users
@@ -77,9 +77,9 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
77
77
  error: string;
78
78
  users?: undefined;
79
79
  } | {
80
+ error?: undefined;
80
81
  users: {
81
82
  clientId: number;
82
83
  lastSeen: number;
83
84
  }[];
84
- error?: undefined;
85
85
  }>>;
@@ -41,27 +41,27 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
+ error?: undefined;
45
+ ok?: undefined;
44
46
  summary: import("./types.js").TraceSummary;
45
47
  spans: import("./types.js").TraceSpan[];
46
48
  id?: undefined;
49
+ } | {
47
50
  error?: undefined;
48
51
  ok?: undefined;
49
- } | {
50
52
  summary?: undefined;
51
53
  spans?: undefined;
52
54
  id: string;
53
- error?: undefined;
54
- ok?: undefined;
55
55
  } | {
56
+ ok?: undefined;
56
57
  summary?: undefined;
57
58
  spans?: undefined;
58
59
  id?: undefined;
59
60
  error: any;
60
- ok?: undefined;
61
61
  } | {
62
+ error?: undefined;
62
63
  summary?: undefined;
63
64
  spans?: undefined;
64
65
  id?: undefined;
65
- error?: undefined;
66
66
  ok: boolean;
67
67
  }>>;
@@ -34,37 +34,37 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
34
34
  /** POST /_agent-native/secrets/:key — write a secret. */
35
35
  export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
36
36
  error: string;
37
- status?: undefined;
38
37
  ok?: undefined;
38
+ status?: undefined;
39
39
  } | {
40
+ error?: undefined;
40
41
  ok: boolean;
41
42
  status: string;
42
- error?: undefined;
43
43
  } | {
44
+ ok?: undefined;
44
45
  error: string;
45
46
  removed?: undefined;
46
- ok?: undefined;
47
47
  } | {
48
+ error?: undefined;
48
49
  ok: boolean;
49
50
  removed: boolean;
50
- error?: undefined;
51
51
  }>>;
52
52
  /**
53
53
  * POST /_agent-native/secrets/:key/test — validate an optional candidate value
54
54
  * or the current stored value without changing anything.
55
55
  */
56
56
  export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
57
+ ok?: undefined;
57
58
  error: string;
58
59
  note?: undefined;
59
- ok?: undefined;
60
60
  } | {
61
+ error?: undefined;
61
62
  ok: boolean;
62
63
  note?: undefined;
63
- error?: undefined;
64
64
  } | {
65
+ error?: undefined;
65
66
  ok: boolean;
66
67
  note: string;
67
- error?: undefined;
68
68
  } | {
69
69
  note?: undefined;
70
70
  ok: boolean;
@@ -95,11 +95,11 @@ export interface AdHocSecretPayload {
95
95
  export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
96
96
  error: string;
97
97
  } | {
98
+ error?: undefined;
98
99
  ok: boolean;
99
100
  key: string;
100
- error?: undefined;
101
101
  } | {
102
+ error?: undefined;
102
103
  ok: boolean;
103
104
  removed: boolean;
104
- error?: undefined;
105
105
  }>>;
@@ -2285,6 +2285,7 @@ export function createAgentChatPlugin(options) {
2285
2285
  const leanActionEntries = {
2286
2286
  ...templateScripts,
2287
2287
  ...resourceScripts,
2288
+ ...workspaceFileActions,
2288
2289
  ...refreshScreenTool,
2289
2290
  ...urlTools,
2290
2291
  ...chatScripts,
@@ -27,10 +27,10 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
27
27
  export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
28
28
  error: any;
29
29
  } | {
30
+ error?: undefined;
30
31
  ok: boolean;
31
32
  key: string;
32
33
  baseUrlKey?: string;
33
34
  scope: AgentEngineApiKeyScope;
34
- error?: undefined;
35
35
  }>>;
36
36
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.153.1",
3
+ "version": "0.153.4",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {