@agent-native/core 0.0.0-beta-20260820231735 → 0.0.0-beta-20260820233158

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 (35) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/clips/desktop/src/app.tsx +11 -10
  3. package/corpus/templates/clips/desktop/src/lib/desktop-oauth-window.ts +23 -0
  4. package/dist/client/AboutAgentNativeDialog.d.ts +5 -0
  5. package/dist/client/AboutAgentNativeDialog.js +56 -0
  6. package/dist/client/CommandMenu.d.ts +6 -1
  7. package/dist/client/CommandMenu.js +46 -3
  8. package/dist/client/EnvironmentBadge.js +4 -1
  9. package/dist/client/agent-native-version.d.ts +12 -0
  10. package/dist/client/agent-native-version.js +36 -0
  11. package/dist/collab/routes.d.ts +1 -1
  12. package/dist/collab/struct-routes.d.ts +1 -1
  13. package/dist/localization/core-messages/ar-SA.js +6 -0
  14. package/dist/localization/core-messages/de-DE.js +6 -0
  15. package/dist/localization/core-messages/en-US.d.ts +6 -0
  16. package/dist/localization/core-messages/en-US.js +6 -0
  17. package/dist/localization/core-messages/es-ES.js +6 -0
  18. package/dist/localization/core-messages/fr-FR.js +6 -0
  19. package/dist/localization/core-messages/hi-IN.js +6 -0
  20. package/dist/localization/core-messages/ja-JP.js +6 -0
  21. package/dist/localization/core-messages/ko-KR.js +6 -0
  22. package/dist/localization/core-messages/pt-BR.js +6 -0
  23. package/dist/localization/core-messages/zh-CN.js +6 -0
  24. package/dist/localization/core-messages/zh-TW.js +6 -0
  25. package/dist/localization/core-messages.d.ts +6 -0
  26. package/dist/observability/routes.d.ts +3 -3
  27. package/dist/progress/routes.d.ts +1 -1
  28. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  29. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  30. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  31. package/dist/resources/handlers.d.ts +2 -2
  32. package/dist/vite/client.js +3 -0
  33. package/dist/vite/package-versions.d.ts +1 -0
  34. package/dist/vite/package-versions.js +97 -0
  35. package/package.json +1 -1
package/corpus/README.md CHANGED
@@ -31,4 +31,4 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
31
31
 
32
32
  ## Generated Counts
33
33
 
34
- - template files: 8490
34
+ - template files: 8491
@@ -67,6 +67,7 @@ import {
67
67
  startBubbleWebrtc,
68
68
  type BubbleWebrtcHandle,
69
69
  } from "./lib/bubble-webrtc";
70
+ import { openBoundOAuthWindow } from "./lib/desktop-oauth-window";
70
71
  import {
71
72
  getCameraStreamWithFallback,
72
73
  isMediaConstraintFailure,
@@ -2126,15 +2127,17 @@ export function App() {
2126
2127
  void tick();
2127
2128
  }
2128
2129
 
2129
- // Google verification stays in the bound Tauri WebView so the callback sees
2130
- // the same browser-binding cookie. Magic-link verification still completes
2131
- // in the system browser through its own exchange flow.
2130
+ // Google verification stays in a child of the bound Tauri WebView so the
2131
+ // callback sees the same browser-binding cookie. Magic-link verification
2132
+ // still completes in the system browser through its own exchange flow.
2132
2133
  async function signInExternal() {
2133
2134
  if (signInInflightRef.current) return;
2134
2135
  signInInflightRef.current = true;
2136
+ let oauthWindow: ReturnType<typeof openBoundOAuthWindow> | null = null;
2135
2137
 
2136
2138
  try {
2137
2139
  setSignInError(null);
2140
+ oauthWindow = openBoundOAuthWindow();
2138
2141
  const flowId = crypto.randomUUID?.() ?? null;
2139
2142
  const verifier = (() => {
2140
2143
  const randomUuid = crypto.randomUUID;
@@ -2163,7 +2166,6 @@ export function App() {
2163
2166
  const authParams = new URLSearchParams({
2164
2167
  desktop: "1",
2165
2168
  flow_id: flowId,
2166
- webview: "1",
2167
2169
  });
2168
2170
  const authResponse = await fetch(
2169
2171
  `${base}/_agent-native/google/auth-url?${authParams.toString()}`,
@@ -2194,13 +2196,12 @@ export function App() {
2194
2196
  : "Could not start Google sign-in.";
2195
2197
  throw new Error(message);
2196
2198
  }
2199
+ oauthWindow.location.href = authPayload.url;
2197
2200
  setSignInPending("google");
2198
- // Stay in this exact WebView: the auth bootstrap set the HttpOnly
2199
- // browser-binding cookie here, and the callback returns this page with
2200
- // the staged session cookie after Google completes.
2201
- window.location.href = authPayload.url;
2201
+ startDesktopAuthExchange(flowId, "google", verifier);
2202
2202
  } catch (err) {
2203
2203
  console.error("[clips-tray] signInExternal failed:", err);
2204
+ oauthWindow?.close();
2204
2205
  signInInflightRef.current = false;
2205
2206
  setSignInPending(null);
2206
2207
  setSignInError(
@@ -3962,8 +3963,8 @@ export function App() {
3962
3963
  // (not a separate Tauri window). This avoids Tauri 2's separate-WebKit-
3963
3964
  // data-store-per-WebviewWindow cookie-jar issue — the cookie is set in
3964
3965
  // the same webview that reads it on the next /auth/session poll.
3965
- // Google verification uses the bound WebView, while magic-link verification
3966
- // uses the system browser and password stays inline here.
3966
+ // Google verification uses a popup in the bound WebView, while magic-link
3967
+ // verification uses the system browser and password stays inline here.
3967
3968
  if (authStatus === "anon") {
3968
3969
  return (
3969
3970
  <div className="app" ref={appRef}>
@@ -0,0 +1,23 @@
1
+ type OAuthWindow = Pick<Window, "close"> & {
2
+ location: Pick<Location, "href">;
3
+ };
4
+
5
+ type OpenOAuthWindow = (url: string, target: string) => OAuthWindow | null;
6
+
7
+ /**
8
+ * Open a same-WebView OAuth child before awaiting the auth URL.
9
+ *
10
+ * The parent keeps polling the exchange while the child completes Google
11
+ * OAuth. Using window.open keeps both pages in the Tauri WebView cookie
12
+ * partition; the system-browser shell opener would lose the binding cookie.
13
+ */
14
+ export function openBoundOAuthWindow(
15
+ openWindow: OpenOAuthWindow = (url, target) =>
16
+ window.open(url, target) as OAuthWindow | null,
17
+ ): OAuthWindow {
18
+ const oauthWindow = openWindow("about:blank", "_blank");
19
+ if (!oauthWindow) {
20
+ throw new Error("Could not open the Google sign-in window.");
21
+ }
22
+ return oauthWindow;
23
+ }
@@ -0,0 +1,5 @@
1
+ export interface AboutAgentNativeDialogProps {
2
+ open: boolean;
3
+ onOpenChange: (open: boolean) => void;
4
+ }
5
+ export declare function AboutAgentNativeDialog({ open, onOpenChange, }: AboutAgentNativeDialogProps): import("react").JSX.Element;
@@ -0,0 +1,56 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from "@agent-native/toolkit/ui/button";
3
+ import { IconCheck, IconCode, IconCopy, IconX } from "@tabler/icons-react";
4
+ import { useEffect, useMemo, useRef, useState } from "react";
5
+ import { formatAgentNativeDiagnostics, getAgentNativeDiagnostics, getAgentNativePackageVersions, } from "./agent-native-version.js";
6
+ import { writeClipboardText } from "./clipboard.js";
7
+ import { Dialog, DialogContent, DialogTitle } from "./components/ui/dialog.js";
8
+ import { useT } from "./i18n.js";
9
+ export function AboutAgentNativeDialog({ open, onOpenChange, }) {
10
+ const t = useT();
11
+ const [copyState, setCopyState] = useState("idle");
12
+ const copyResetTimer = useRef(null);
13
+ const packageVersions = getAgentNativePackageVersions();
14
+ const diagnostics = useMemo(() => formatAgentNativeDiagnostics(), []);
15
+ const { buildId, environment } = getAgentNativeDiagnostics();
16
+ useEffect(() => {
17
+ if (!open) {
18
+ setCopyState("idle");
19
+ }
20
+ }, [open]);
21
+ useEffect(() => () => {
22
+ if (copyResetTimer.current !== null) {
23
+ window.clearTimeout(copyResetTimer.current);
24
+ }
25
+ }, []);
26
+ const handleCopy = async () => {
27
+ const didCopy = await writeClipboardText(diagnostics);
28
+ setCopyState(didCopy ? "copied" : "failed");
29
+ if (copyResetTimer.current !== null) {
30
+ window.clearTimeout(copyResetTimer.current);
31
+ }
32
+ copyResetTimer.current = window.setTimeout(() => {
33
+ setCopyState("idle");
34
+ copyResetTimer.current = null;
35
+ }, 1600);
36
+ };
37
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { "aria-describedby": undefined, className: "max-w-md gap-5", children: [_jsxs(DialogTitle, { className: "flex items-center gap-2 text-base", children: [_jsx(IconCode, { className: "size-4 text-muted-foreground" }), t("agentChat.aboutAgentNative.title", {
38
+ defaultValue: "About Agent Native",
39
+ })] }), _jsx("div", { className: "overflow-hidden rounded-md border border-border", children: packageVersions.length > 0 ? (packageVersions.map(({ name, version }) => (_jsxs("div", { className: "flex items-center justify-between gap-4 border-b border-border px-3 py-2 last:border-b-0", children: [_jsx("span", { className: "min-w-0 truncate font-mono text-xs text-foreground", children: name }), _jsxs("span", { className: "shrink-0 font-mono text-xs text-muted-foreground", children: [_jsx("span", { className: "sr-only", children: t("agentChat.aboutAgentNative.version", {
40
+ defaultValue: "Version",
41
+ }) }), version] })] }, name)))) : (_jsxs("div", { className: "px-3 py-2 font-mono text-xs text-muted-foreground", children: ["@agent-native/core -", " ", t("agentChat.aboutAgentNative.unknown", {
42
+ defaultValue: "Unknown",
43
+ })] })) }), _jsxs("dl", { className: "grid gap-2 text-xs", children: [_jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsx("dt", { className: "text-muted-foreground", children: t("agentChat.aboutAgentNative.environment", {
44
+ defaultValue: "Environment",
45
+ }) }), _jsx("dd", { className: "font-mono text-foreground", children: environment })] }), _jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsx("dt", { className: "text-muted-foreground", children: t("agentChat.aboutAgentNative.build", {
46
+ defaultValue: "Build",
47
+ }) }), _jsx("dd", { className: "max-w-[16rem] truncate font-mono text-foreground", children: buildId })] })] }), _jsxs(Button, { className: "w-full", onClick: () => void handleCopy(), type: "button", variant: "outline", children: [copyState === "copied" ? (_jsx(IconCheck, {})) : copyState === "failed" ? (_jsx(IconX, {})) : (_jsx(IconCopy, {})), copyState === "copied"
48
+ ? t("agentChat.common.copied", { defaultValue: "Copied" })
49
+ : copyState === "failed"
50
+ ? t("agentChat.recovery.copyFailed", {
51
+ defaultValue: "Copy failed",
52
+ })
53
+ : t("agentChat.aboutAgentNative.copyDiagnostics", {
54
+ defaultValue: "Copy diagnostics",
55
+ })] })] }) }));
56
+ }
@@ -89,8 +89,13 @@ export interface CommandMenuProps {
89
89
  * multiple apps share an origin.
90
90
  */
91
91
  changelogKey?: string;
92
+ /**
93
+ * Whether to show the built-in "About Agent Native" entry. Defaults to true
94
+ * for app-shell menus that provide a changelog; set false for local menus.
95
+ */
96
+ showAbout?: boolean;
92
97
  }
93
- export declare function CommandMenu({ open, onOpenChange, children, renderResults, placeholder, emptyText: _emptyText, showAgentFallback, className, changelog, changelogLabel, changelogKey, }: CommandMenuProps): React.JSX.Element;
98
+ export declare function CommandMenu({ open, onOpenChange, children, renderResults, placeholder, emptyText: _emptyText, showAgentFallback, className, changelog, changelogLabel, changelogKey, showAbout: showAboutProp, }: CommandMenuProps): React.JSX.Element;
94
99
  export declare namespace CommandMenu {
95
100
  export { CommandGroup as Group };
96
101
  export { CommandItem as Item };
@@ -16,12 +16,14 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
16
16
  * </CommandMenu>
17
17
  */
18
18
  import { Command as CommandPrimitive, CommandGroup as CommandGroupPrimitive, CommandInput as CommandInputPrimitive, CommandItem as CommandItemPrimitive, CommandList as CommandListPrimitive, CommandSeparator as CommandSeparatorPrimitive, CommandShortcut as CommandShortcutPrimitive, } from "@agent-native/toolkit/ui/command";
19
- import { IconBook2, IconExternalLink, IconMessage, IconHistory, } from "@tabler/icons-react";
19
+ import { IconBook2, IconExternalLink, IconInfoCircle, IconMessage, IconHistory, } from "@tabler/icons-react";
20
20
  import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
21
21
  import { parseChangelog } from "../changelog/parse.js";
22
+ import { AboutAgentNativeDialog } from "./AboutAgentNativeDialog.js";
22
23
  import { sendToAgentChat } from "./agent-chat.js";
23
24
  import { ChangelogDialog, useChangelogSeen } from "./changelog/Changelog.js";
24
25
  import { Dialog, DialogContent, DialogTitle } from "./components/ui/dialog.js";
26
+ import { useT } from "./i18n.js";
25
27
  import { cn } from "./utils.js";
26
28
  const CommandMenuContext = createContext(null);
27
29
  function useCommandMenuContext() {
@@ -122,15 +124,18 @@ function CommandDocsGroup({ docs, heading = "Docs" }) {
122
124
  return null;
123
125
  return (_jsx(CommandGroup, { heading: heading, children: docs.map((doc) => (_jsxs(CommandItem, { onSelect: () => openDocsHref(doc.href), keywords: [doc.title, doc.description ?? "", ...(doc.keywords ?? [])], deferSelect: false, className: "items-start py-2", children: [_jsx(IconBook2, { className: "mt-0.5 h-4 w-4 shrink-0 text-muted-foreground" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate font-medium", children: doc.title }), doc.description ? (_jsx("span", { className: "mt-0.5 block line-clamp-2 text-xs leading-snug text-muted-foreground", children: doc.description })) : null] }), _jsx(IconExternalLink, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" })] }, doc.href))) }));
124
126
  }
125
- export function CommandMenu({ open, onOpenChange, children, renderResults, placeholder = "Type a command or ask AI...", emptyText: _emptyText = "No commands found.", showAgentFallback = true, className, changelog, changelogLabel = "What's new", changelogKey, }) {
127
+ export function CommandMenu({ open, onOpenChange, children, renderResults, placeholder = "Type a command or ask AI...", emptyText: _emptyText = "No commands found.", showAgentFallback = true, className, changelog, changelogLabel = "What's new", changelogKey, showAbout: showAboutProp, }) {
126
128
  const [search, setSearch] = useState("");
127
129
  const inputRef = useRef(null);
128
130
  const containerRef = useRef(null);
131
+ const t = useT();
129
132
  // Built-in "What's new" changelog surface (only active when `changelog` is
130
133
  // passed). The dialog is rendered alongside the menu so it survives the menu
131
134
  // closing; the unseen dot persists per browser via localStorage.
132
135
  const [changelogOpen, setChangelogOpen] = useState(false);
136
+ const [aboutOpen, setAboutOpen] = useState(false);
133
137
  const hasChangelog = typeof changelog === "string" && changelog.trim().length > 0;
138
+ const showAbout = showAboutProp ?? hasChangelog;
134
139
  const changelogEntries = useMemo(() => (hasChangelog ? parseChangelog(changelog) : []), [hasChangelog, changelog]);
135
140
  const latestChangelogId = changelogEntries[0]?.id;
136
141
  const { unseen: changelogUnseen, markSeen: markChangelogSeen } = useChangelogSeen(changelogKey ?? "app", latestChangelogId);
@@ -140,6 +145,11 @@ export function CommandMenu({ open, onOpenChange, children, renderResults, place
140
145
  // Let the menu close before the dialog opens (avoids overlay flicker).
141
146
  setTimeout(() => setChangelogOpen(true), 50);
142
147
  }, [onOpenChange, markChangelogSeen]);
148
+ const openAbout = useCallback(() => {
149
+ onOpenChange(false);
150
+ // Let the menu close before the dialog opens (avoids overlay flicker).
151
+ setTimeout(() => setAboutOpen(true), 50);
152
+ }, [onOpenChange]);
143
153
  // Focus input when opening; clear search while closed so reopen never renders
144
154
  // dynamic results for the previous query.
145
155
  useEffect(() => {
@@ -178,6 +188,36 @@ export function CommandMenu({ open, onOpenChange, children, renderResults, place
178
188
  .toLowerCase()
179
189
  .includes(search.toLowerCase());
180
190
  const showChangelogRow = hasChangelog && changelogRowMatches;
191
+ const aboutLabel = t("agentChat.aboutAgentNative.title", {
192
+ defaultValue: "About Agent Native",
193
+ });
194
+ const aboutVersionLabel = t("agentChat.aboutAgentNative.version", {
195
+ defaultValue: "Version",
196
+ });
197
+ const aboutEnvironmentLabel = t("agentChat.aboutAgentNative.environment", {
198
+ defaultValue: "Environment",
199
+ });
200
+ const aboutBuildLabel = t("agentChat.aboutAgentNative.build", {
201
+ defaultValue: "Build",
202
+ });
203
+ const aboutDiagnosticsLabel = t("agentChat.aboutAgentNative.copyDiagnostics", {
204
+ defaultValue: "Copy diagnostics",
205
+ });
206
+ const aboutRowMatches = !search ||
207
+ [
208
+ aboutLabel,
209
+ "agent native",
210
+ aboutVersionLabel,
211
+ "versions",
212
+ "package",
213
+ aboutEnvironmentLabel,
214
+ aboutBuildLabel,
215
+ aboutDiagnosticsLabel,
216
+ ]
217
+ .join(" ")
218
+ .toLowerCase()
219
+ .includes(search.toLowerCase());
220
+ const showAboutRow = showAbout && aboutRowMatches;
181
221
  // Filter children based on search
182
222
  const filterChildren = (nodes) => {
183
223
  return React.Children.map(nodes, (child) => {
@@ -242,7 +282,10 @@ export function CommandMenu({ open, onOpenChange, children, renderResults, place
242
282
  }, className: cn("fixed left-1/2 top-[15vh] !z-50 !max-h-none -translate-x-1/2 !translate-y-0 !gap-0 w-full max-w-lg", "rounded-lg border border-border bg-popover p-0 text-popover-foreground shadow-lg", className), style: {
243
283
  animation: "none",
244
284
  transition: "none",
245
- }, children: [_jsx(DialogTitle, { className: "sr-only", children: placeholder }), _jsx(CommandPrimitive, { loop: true, shouldFilter: false, className: "h-auto rounded-lg", children: _jsxs(CommandMenuContext.Provider, { value: { search, onOpenChange }, children: [_jsx(CommandInputPrimitive, { ref: inputRef, value: search, onValueChange: setSearch, placeholder: placeholder }), _jsxs(CommandListPrimitive, { children: [dynamicResults, hasResults && filteredChildren, showChangelogRow && (_jsxs(_Fragment, { children: [hasResults && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: openChangelog, children: [_jsx(IconHistory, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: changelogLabel }), changelogUnseen && (_jsx("span", { className: "ms-auto h-2 w-2 rounded-full bg-primary", "aria-label": "New updates available" }))] }) })] })), showAgentFallback && (_jsxs(_Fragment, { children: [(hasResults || showChangelogRow || hasDynamicResults) && (_jsx(CommandSeparator, {})), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: handleSubmitToAgent, children: [_jsx(IconMessage, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: search.trim() ? (_jsxs(_Fragment, { children: ["Ask AI:", " ", _jsxs("span", { className: "text-muted-foreground", children: ["\"", search, "\""] })] })) : (_jsx("span", { className: "text-muted-foreground", children: "Ask AI anything..." })) }), search.trim() && (_jsx("span", { className: "ms-auto text-xs text-muted-foreground", children: "\u21B5" }))] }) })] }))] })] }) })] }) }), hasChangelog && (_jsx(ChangelogDialog, { open: changelogOpen, onOpenChange: setChangelogOpen, markdown: changelog, title: changelogLabel }))] }));
285
+ }, children: [_jsx(DialogTitle, { className: "sr-only", children: placeholder }), _jsx(CommandPrimitive, { loop: true, shouldFilter: false, className: "h-auto rounded-lg", children: _jsxs(CommandMenuContext.Provider, { value: { search, onOpenChange }, children: [_jsx(CommandInputPrimitive, { ref: inputRef, value: search, onValueChange: setSearch, placeholder: placeholder }), _jsxs(CommandListPrimitive, { children: [dynamicResults, hasResults && filteredChildren, showChangelogRow && (_jsxs(_Fragment, { children: [hasResults && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: openChangelog, children: [_jsx(IconHistory, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: changelogLabel }), changelogUnseen && (_jsx("span", { className: "ms-auto h-2 w-2 rounded-full bg-primary", "aria-label": "New updates available" }))] }) })] })), showAboutRow && (_jsxs(_Fragment, { children: [(hasResults || showChangelogRow) && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: openAbout, children: [_jsx(IconInfoCircle, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: aboutLabel })] }) })] })), showAgentFallback && (_jsxs(_Fragment, { children: [(hasResults ||
286
+ showChangelogRow ||
287
+ showAboutRow ||
288
+ hasDynamicResults) && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: handleSubmitToAgent, children: [_jsx(IconMessage, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: search.trim() ? (_jsxs(_Fragment, { children: ["Ask AI:", " ", _jsxs("span", { className: "text-muted-foreground", children: ["\"", search, "\""] })] })) : (_jsx("span", { className: "text-muted-foreground", children: "Ask AI anything..." })) }), search.trim() && (_jsx("span", { className: "ms-auto text-xs text-muted-foreground", children: "\u21B5" }))] }) })] }))] })] }) })] }) }), hasChangelog && (_jsx(ChangelogDialog, { open: changelogOpen, onOpenChange: setChangelogOpen, markdown: changelog, title: changelogLabel })), showAbout && (_jsx(AboutAgentNativeDialog, { open: aboutOpen, onOpenChange: setAboutOpen }))] }));
246
289
  }
247
290
  // Helper to extract text content from React children
248
291
  function getTextContent(children) {
@@ -6,6 +6,7 @@ import { BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOpt
6
6
  import { trackEvent } from "./analytics.js";
7
7
  import { injectedAgentNativeConfig } from "./app-config.js";
8
8
  import { useSession } from "./use-session.js";
9
+ import { cn } from "./utils.js";
9
10
  export { BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
10
11
  export function isBuilderIoEmployee(email) {
11
12
  return email?.trim().toLowerCase().endsWith("@builder.io") ?? false;
@@ -88,7 +89,9 @@ function EnvironmentBadgeContent({ environment, targets, }) {
88
89
  const title = environment === "beta"
89
90
  ? "You're on Agent Native Beta"
90
91
  : "You're on Agent Native Production";
91
- return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { "aria-label": `Open ${title.toLowerCase()} switcher`, className: "fixed bottom-3 right-3 z-[100] h-6 min-w-0 rounded-xl border-border/80 bg-background/95 px-2 text-[11px] font-semibold uppercase tracking-[0.5px] shadow-sm backdrop-blur-sm", size: "sm", variant: environment === "beta" ? "default" : "outline", children: label }) }), _jsxs(PopoverContent, { align: "center", className: "w-[280px] p-5", side: "top", sideOffset: 8, children: [_jsx("div", { className: "mb-1 text-sm font-semibold leading-5", children: title }), _jsx("div", { className: "mb-4 text-sm text-muted-foreground", children: "Choose where you want to continue." }), _jsx("div", { className: "grid gap-2", children: environment === "beta" ? (_jsx(EnvironmentLink, { href: productionHref, label: "Switch to production" })) : (_jsx(EnvironmentLink, { href: betaHref, label: "Go to beta" })) })] })] }));
92
+ return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { "aria-label": `Open ${title.toLowerCase()} switcher`, className: cn("fixed bottom-3 right-3 z-[100] h-6 min-w-0 rounded-xl px-2 text-[11px] font-semibold uppercase tracking-[0.5px] shadow-sm backdrop-blur-sm", environment === "beta"
93
+ ? "border-primary/80"
94
+ : "border-border/80 bg-background/95 text-foreground"), size: "sm", variant: environment === "beta" ? "default" : "outline", children: label }) }), _jsxs(PopoverContent, { align: "center", className: "w-[280px] p-5", side: "top", sideOffset: 8, children: [_jsx("div", { className: "mb-1 text-sm font-semibold leading-5", children: title }), _jsx("div", { className: "mb-4 text-sm text-muted-foreground", children: "Choose where you want to continue." }), _jsx("div", { className: "grid gap-2", children: environment === "beta" ? (_jsx(EnvironmentLink, { href: productionHref, label: "Switch to production" })) : (_jsx(EnvironmentLink, { href: betaHref, label: "Go to beta" })) })] })] }));
92
95
  }
93
96
  function ProductionEnvironmentBadge({ targets, }) {
94
97
  const { session, status } = useSession();
@@ -0,0 +1,12 @@
1
+ export interface AgentNativePackageVersion {
2
+ name: string;
3
+ version: string;
4
+ }
5
+ export interface AgentNativeDiagnostics {
6
+ buildId: string;
7
+ environment: string;
8
+ packages: Record<string, string>;
9
+ }
10
+ export declare function getAgentNativePackageVersions(): AgentNativePackageVersion[];
11
+ export declare function getAgentNativeDiagnostics(): AgentNativeDiagnostics;
12
+ export declare function formatAgentNativeDiagnostics(): string;
@@ -0,0 +1,36 @@
1
+ import { injectedAgentNativeConfig } from "./app-config.js";
2
+ import { clientBuildId } from "./build-compatibility.js";
3
+ function readPackageVersions(value) {
4
+ if (!value || typeof value !== "object") {
5
+ return {};
6
+ }
7
+ return Object.fromEntries(Object.entries(value)
8
+ .filter(([name, version]) => name.startsWith("@agent-native/") &&
9
+ typeof version === "string" &&
10
+ version.trim().length > 0)
11
+ .map(([name, version]) => [name, version.trim()]));
12
+ }
13
+ function injectedPackageVersions() {
14
+ if (typeof __AGENT_NATIVE_PACKAGE_VERSIONS__ !== "undefined") {
15
+ return readPackageVersions(__AGENT_NATIVE_PACKAGE_VERSIONS__);
16
+ }
17
+ return readPackageVersions(globalThis.__AGENT_NATIVE_PACKAGE_VERSIONS__);
18
+ }
19
+ export function getAgentNativePackageVersions() {
20
+ return Object.entries(injectedPackageVersions())
21
+ .sort(([left], [right]) => left.localeCompare(right))
22
+ .map(([name, version]) => ({ name, version }));
23
+ }
24
+ export function getAgentNativeDiagnostics() {
25
+ return {
26
+ buildId: clientBuildId() || "development",
27
+ environment: injectedAgentNativeConfig().deployment?.environment ?? "unknown",
28
+ packages: Object.fromEntries(getAgentNativePackageVersions().map(({ name, version }) => [
29
+ name,
30
+ version,
31
+ ])),
32
+ };
33
+ }
34
+ export function formatAgentNativeDiagnostics() {
35
+ return JSON.stringify(getAgentNativeDiagnostics(), null, 2);
36
+ }
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- ok?: undefined;
30
29
  error: string;
30
+ ok?: undefined;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- ok?: undefined;
17
16
  error: string;
17
+ ok?: undefined;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "الإشارة إلى ملفات أو وكلاء أو موارد",
25
25
  "commands.new": "مثل /clear",
26
26
  "commands.plan": "التبديل إلى التخطيط للقراءة فقط",
27
+ "aboutAgentNative.title": "حول Agent Native",
28
+ "aboutAgentNative.version": "الإصدار",
29
+ "aboutAgentNative.environment": "البيئة",
30
+ "aboutAgentNative.build": "البنية",
31
+ "aboutAgentNative.copyDiagnostics": "نسخ بيانات التشخيص",
32
+ "aboutAgentNative.unknown": "غير معروف",
27
33
  "common.agent": "الوكيل",
28
34
  "common.cancel": "إلغاء",
29
35
  "common.collapse": "طي",
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "Dateien, Agenten oder Ressourcen erwähnen",
25
25
  "commands.new": "Entspricht /clear",
26
26
  "commands.plan": "Zum schreibgeschützten Planungsmodus wechseln",
27
+ "aboutAgentNative.title": "Über Agent Native",
28
+ "aboutAgentNative.version": "Version",
29
+ "aboutAgentNative.environment": "Umgebung",
30
+ "aboutAgentNative.build": "Build",
31
+ "aboutAgentNative.copyDiagnostics": "Diagnosedaten kopieren",
32
+ "aboutAgentNative.unknown": "Unbekannt",
27
33
  "common.agent": "Agent",
28
34
  "common.cancel": "Abbrechen",
29
35
  "common.collapse": "Einklappen",
@@ -24,6 +24,12 @@ declare const messages: {
24
24
  readonly "commands.mention": "Mention files, agents, or resources";
25
25
  readonly "commands.new": "Same as /clear";
26
26
  readonly "commands.plan": "Switch to read-only planning";
27
+ readonly "aboutAgentNative.title": "About Agent Native";
28
+ readonly "aboutAgentNative.version": "Version";
29
+ readonly "aboutAgentNative.environment": "Environment";
30
+ readonly "aboutAgentNative.build": "Build";
31
+ readonly "aboutAgentNative.copyDiagnostics": "Copy diagnostics";
32
+ readonly "aboutAgentNative.unknown": "Unknown";
27
33
  readonly "common.agent": "Agent";
28
34
  readonly "common.cancel": "Cancel";
29
35
  readonly "common.collapse": "Collapse";
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "Mention files, agents, or resources",
25
25
  "commands.new": "Same as /clear",
26
26
  "commands.plan": "Switch to read-only planning",
27
+ "aboutAgentNative.title": "About Agent Native",
28
+ "aboutAgentNative.version": "Version",
29
+ "aboutAgentNative.environment": "Environment",
30
+ "aboutAgentNative.build": "Build",
31
+ "aboutAgentNative.copyDiagnostics": "Copy diagnostics",
32
+ "aboutAgentNative.unknown": "Unknown",
27
33
  "common.agent": "Agent",
28
34
  "common.cancel": "Cancel",
29
35
  "common.collapse": "Collapse",
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "Mencionar archivos, agentes o recursos",
25
25
  "commands.new": "Igual que /clear",
26
26
  "commands.plan": "Cambiar a la planificación de solo lectura",
27
+ "aboutAgentNative.title": "Acerca de Agent Native",
28
+ "aboutAgentNative.version": "Versión",
29
+ "aboutAgentNative.environment": "Entorno",
30
+ "aboutAgentNative.build": "Compilación",
31
+ "aboutAgentNative.copyDiagnostics": "Copiar diagnóstico",
32
+ "aboutAgentNative.unknown": "Desconocida",
27
33
  "common.agent": "Agente",
28
34
  "common.cancel": "Cancelar",
29
35
  "common.collapse": "Contraer",
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "Mentionner des fichiers, des agents ou des ressources",
25
25
  "commands.new": "Identique à /clear",
26
26
  "commands.plan": "Passer à la planification en lecture seule",
27
+ "aboutAgentNative.title": "À propos d’Agent Native",
28
+ "aboutAgentNative.version": "Version",
29
+ "aboutAgentNative.environment": "Environnement",
30
+ "aboutAgentNative.build": "Build",
31
+ "aboutAgentNative.copyDiagnostics": "Copier les diagnostics",
32
+ "aboutAgentNative.unknown": "Inconnue",
27
33
  "common.agent": "Agent",
28
34
  "common.cancel": "Annuler",
29
35
  "common.collapse": "Réduire",
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "फ़ाइलों, एजेंटों या संसाधनों का उल्लेख करें",
25
25
  "commands.new": "/clear के समान",
26
26
  "commands.plan": "केवल-पढ़ने योग्य योजना मोड पर जाएँ",
27
+ "aboutAgentNative.title": "Agent Native के बारे में",
28
+ "aboutAgentNative.version": "संस्करण",
29
+ "aboutAgentNative.environment": "पर्यावरण",
30
+ "aboutAgentNative.build": "बिल्ड",
31
+ "aboutAgentNative.copyDiagnostics": "डायग्नोस्टिक कॉपी करें",
32
+ "aboutAgentNative.unknown": "अज्ञात",
27
33
  "common.agent": "एजेंट",
28
34
  "common.cancel": "रद्द करें",
29
35
  "common.collapse": "समेटें",
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "ファイル、エージェント、リソースをメンション",
25
25
  "commands.new": "/clear と同じ",
26
26
  "commands.plan": "読み取り専用の計画モードに切り替え",
27
+ "aboutAgentNative.title": "Agent Native について",
28
+ "aboutAgentNative.version": "バージョン",
29
+ "aboutAgentNative.environment": "環境",
30
+ "aboutAgentNative.build": "ビルド",
31
+ "aboutAgentNative.copyDiagnostics": "診断情報をコピー",
32
+ "aboutAgentNative.unknown": "不明",
27
33
  "common.agent": "エージェント",
28
34
  "common.cancel": "キャンセル",
29
35
  "common.collapse": "折りたたむ",
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "파일, 에이전트 또는 리소스 멘션",
25
25
  "commands.new": "/clear와 동일",
26
26
  "commands.plan": "읽기 전용 계획 모드로 전환",
27
+ "aboutAgentNative.title": "Agent Native 정보",
28
+ "aboutAgentNative.version": "버전",
29
+ "aboutAgentNative.environment": "환경",
30
+ "aboutAgentNative.build": "빌드",
31
+ "aboutAgentNative.copyDiagnostics": "진단 정보 복사",
32
+ "aboutAgentNative.unknown": "알 수 없음",
27
33
  "common.agent": "에이전트",
28
34
  "common.cancel": "취소",
29
35
  "common.collapse": "접기",
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "Mencionar arquivos, agentes ou recursos",
25
25
  "commands.new": "O mesmo que /clear",
26
26
  "commands.plan": "Mudar para o planejamento somente leitura",
27
+ "aboutAgentNative.title": "Sobre o Agent Native",
28
+ "aboutAgentNative.version": "Versão",
29
+ "aboutAgentNative.environment": "Ambiente",
30
+ "aboutAgentNative.build": "Build",
31
+ "aboutAgentNative.copyDiagnostics": "Copiar diagnósticos",
32
+ "aboutAgentNative.unknown": "Desconhecida",
27
33
  "common.agent": "Agente",
28
34
  "common.cancel": "Cancelar",
29
35
  "common.collapse": "Recolher",
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "提及文件、智能体或资源",
25
25
  "commands.new": "与 /clear 相同",
26
26
  "commands.plan": "切换到只读规划模式",
27
+ "aboutAgentNative.title": "关于 Agent Native",
28
+ "aboutAgentNative.version": "版本",
29
+ "aboutAgentNative.environment": "环境",
30
+ "aboutAgentNative.build": "构建",
31
+ "aboutAgentNative.copyDiagnostics": "复制诊断信息",
32
+ "aboutAgentNative.unknown": "未知",
27
33
  "common.agent": "智能体",
28
34
  "common.cancel": "取消",
29
35
  "common.collapse": "收起",
@@ -24,6 +24,12 @@ const messages = {
24
24
  "commands.mention": "提及檔案、代理或資源",
25
25
  "commands.new": "與 /clear 相同",
26
26
  "commands.plan": "切換到唯讀規劃模式",
27
+ "aboutAgentNative.title": "關於 Agent Native",
28
+ "aboutAgentNative.version": "版本",
29
+ "aboutAgentNative.environment": "環境",
30
+ "aboutAgentNative.build": "建置",
31
+ "aboutAgentNative.copyDiagnostics": "複製診斷資訊",
32
+ "aboutAgentNative.unknown": "未知",
27
33
  "common.agent": "代理",
28
34
  "common.cancel": "取消",
29
35
  "common.collapse": "收合",
@@ -26,6 +26,12 @@ export declare const englishAgentChatMessages: {
26
26
  readonly "commands.mention": "Mention files, agents, or resources";
27
27
  readonly "commands.new": "Same as /clear";
28
28
  readonly "commands.plan": "Switch to read-only planning";
29
+ readonly "aboutAgentNative.title": "About Agent Native";
30
+ readonly "aboutAgentNative.version": "Version";
31
+ readonly "aboutAgentNative.environment": "Environment";
32
+ readonly "aboutAgentNative.build": "Build";
33
+ readonly "aboutAgentNative.copyDiagnostics": "Copy diagnostics";
34
+ readonly "aboutAgentNative.unknown": "Unknown";
29
35
  readonly "common.agent": "Agent";
30
36
  readonly "common.cancel": "Cancel";
31
37
  readonly "common.collapse": "Collapse";
@@ -42,22 +42,22 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
42
42
  avgEvalScore: number;
43
43
  } | {
44
44
  error?: undefined;
45
+ ok?: undefined;
45
46
  summary: import("./types.js").TraceSummary;
46
47
  spans: import("./types.js").TraceSpan[];
47
48
  id?: undefined;
48
- ok?: undefined;
49
49
  } | {
50
50
  error?: undefined;
51
+ ok?: undefined;
51
52
  summary?: undefined;
52
53
  spans?: undefined;
53
54
  id: string;
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
62
  error?: undefined;
63
63
  summary?: undefined;
@@ -15,6 +15,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
15
15
  error: string;
16
16
  ok?: undefined;
17
17
  } | {
18
- ok: boolean;
19
18
  error?: undefined;
19
+ ok: boolean;
20
20
  }>>;
@@ -93,29 +93,29 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
93
93
  label?: undefined;
94
94
  message?: undefined;
95
95
  } | {
96
+ count?: undefined;
96
97
  id?: undefined;
97
98
  deleted?: undefined;
98
99
  providers?: undefined;
99
- count?: undefined;
100
100
  found: boolean;
101
101
  provider: import("../custom-registry.js").CustomProviderConfig;
102
102
  registered?: undefined;
103
103
  label?: undefined;
104
104
  message?: undefined;
105
105
  } | {
106
+ count?: undefined;
106
107
  provider?: undefined;
107
108
  deleted?: undefined;
108
109
  providers?: undefined;
109
- count?: undefined;
110
110
  found: boolean;
111
111
  id: string;
112
112
  registered?: undefined;
113
113
  label?: undefined;
114
114
  message?: undefined;
115
115
  } | {
116
+ count?: undefined;
116
117
  provider?: undefined;
117
118
  providers?: undefined;
118
- count?: undefined;
119
119
  found?: undefined;
120
120
  deleted: boolean;
121
121
  id: string;
@@ -123,10 +123,10 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
123
123
  label?: undefined;
124
124
  message?: undefined;
125
125
  } | {
126
+ count?: undefined;
126
127
  provider?: undefined;
127
128
  deleted?: undefined;
128
129
  providers?: undefined;
129
- count?: undefined;
130
130
  found?: undefined;
131
131
  registered: boolean;
132
132
  id: string;
@@ -313,7 +313,6 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
313
313
  }, {
314
314
  id?: undefined;
315
315
  provider?: undefined;
316
- deleted?: undefined;
317
316
  providers: {
318
317
  id: string;
319
318
  label: string;
@@ -325,33 +324,34 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
325
324
  }[];
326
325
  count: number;
327
326
  found?: undefined;
327
+ deleted?: undefined;
328
328
  registered?: undefined;
329
329
  label?: undefined;
330
330
  message?: undefined;
331
331
  } | {
332
- count?: undefined;
333
332
  id?: undefined;
334
- deleted?: undefined;
335
333
  providers?: undefined;
334
+ count?: undefined;
336
335
  found: boolean;
337
336
  provider: import("../custom-registry.js").CustomProviderConfig;
337
+ deleted?: undefined;
338
338
  registered?: undefined;
339
339
  label?: undefined;
340
340
  message?: undefined;
341
341
  } | {
342
- count?: undefined;
343
342
  provider?: undefined;
344
- deleted?: undefined;
345
343
  providers?: undefined;
344
+ count?: undefined;
346
345
  found: boolean;
347
346
  id: string;
347
+ deleted?: undefined;
348
348
  registered?: undefined;
349
349
  label?: undefined;
350
350
  message?: undefined;
351
351
  } | {
352
- count?: undefined;
353
352
  provider?: undefined;
354
353
  providers?: undefined;
354
+ count?: undefined;
355
355
  found?: undefined;
356
356
  deleted: boolean;
357
357
  id: string;
@@ -359,11 +359,11 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
359
359
  label?: undefined;
360
360
  message?: undefined;
361
361
  } | {
362
- count?: undefined;
363
362
  provider?: undefined;
364
- deleted?: undefined;
365
363
  providers?: undefined;
364
+ count?: undefined;
366
365
  found?: undefined;
366
+ deleted?: undefined;
367
367
  registered: boolean;
368
368
  id: string;
369
369
  label: string;
@@ -73,6 +73,7 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
73
73
  offset?: unknown;
74
74
  limit?: unknown;
75
75
  }, {
76
+ deleted?: undefined;
76
77
  jobs: {
77
78
  id: string;
78
79
  name: string;
@@ -83,7 +84,6 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
83
84
  updatedAt: string;
84
85
  }[];
85
86
  total: number;
86
- deleted?: undefined;
87
87
  jobId?: undefined;
88
88
  } | {
89
89
  jobs?: undefined;
@@ -91,9 +91,9 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
91
91
  deleted: boolean;
92
92
  jobId: string;
93
93
  } | {
94
+ deleted?: undefined;
94
95
  jobs?: undefined;
95
96
  total?: undefined;
96
- deleted?: undefined;
97
97
  jobId?: undefined;
98
98
  hits: Record<string, unknown>[];
99
99
  offset: number;
@@ -51,8 +51,8 @@ export declare function handleDeleteResource(event: any): Promise<{
51
51
  error: string;
52
52
  ok?: undefined;
53
53
  } | {
54
- error?: undefined;
55
54
  ok: boolean;
55
+ error?: undefined;
56
56
  }>;
57
57
  /** POST /_agent-native/resources/upload — upload a file as a resource */
58
58
  export declare function handleUploadResource(event: any): Promise<import("./store.js").Resource | {
@@ -73,10 +73,10 @@ export declare function handleUploadResource(event: any): Promise<import("./stor
73
73
  runId: string | null;
74
74
  expiresAt: number | null;
75
75
  metadata: string | null;
76
- error?: undefined;
77
76
  url: string;
78
77
  provider: string;
79
78
  storageSetupRequired?: undefined;
79
+ error?: undefined;
80
80
  } | {
81
81
  error: string;
82
82
  storageSetupRequired: boolean;
@@ -20,6 +20,7 @@ import { formatRuntimeConfigReport, getRuntimeConfigReport, isTruthyRuntimeValue
20
20
  import { actionTypesPlugin } from "./action-types-plugin.js";
21
21
  import { createAgentNativeConfigContext, loadAgentNativeConfigFile, loadWorkspaceAgentNativeConfigFile, readAgentNativeJsonConfig, } from "./agent-native-config-loader.js";
22
22
  import { agentsBundlePlugin } from "./agents-bundle-plugin.js";
23
+ import { resolveAgentNativePackageVersions } from "./package-versions.js";
23
24
  const require = createRequire(import.meta.url);
24
25
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
25
26
  let nitroFsWatchGuardInstalled = false;
@@ -2842,6 +2843,7 @@ function createAgentNativeConfig(options = {}, command, userConfig = {}, mode =
2842
2843
  process.env.CF_PAGES_COMMIT_SHA?.trim() ||
2843
2844
  process.env.AGENT_NATIVE_BUILD_SHA?.trim() ||
2844
2845
  "development";
2846
+ const packageVersions = resolveAgentNativePackageVersions(cwd);
2845
2847
  // Preload workspace-root .env into process.env so Nitro server code sees
2846
2848
  // shared keys during dev (Nitro reads process.env, not vite's envDir).
2847
2849
  if (workspaceRoot && workspaceRoot !== cwd) {
@@ -2912,6 +2914,7 @@ function createAgentNativeConfig(options = {}, command, userConfig = {}, mode =
2912
2914
  ...(userConfig.define ?? {}),
2913
2915
  ...(options.define ?? {}),
2914
2916
  __AGENT_NATIVE_BUILD_ID__: JSON.stringify(buildId),
2917
+ __AGENT_NATIVE_PACKAGE_VERSIONS__: JSON.stringify(packageVersions),
2915
2918
  __AGENT_NATIVE_CLIENT_COMPATIBILITY_VERSION__: JSON.stringify(options.clientCompatibilityVersion?.trim() || ""),
2916
2919
  __AGENT_NATIVE_APP_CONFIG__: JSON.stringify(resolvedAppConfig),
2917
2920
  __AGENT_NATIVE_BUILD_GA_MEASUREMENT_ID__: JSON.stringify(process.env.GA_MEASUREMENT_ID?.trim() || ""),
@@ -0,0 +1 @@
1
+ export declare function resolveAgentNativePackageVersions(cwd: string): Record<string, string>;
@@ -0,0 +1,97 @@
1
+ import fs from "fs";
2
+ import { createRequire } from "module";
3
+ import path from "path";
4
+ import { fileURLToPath } from "url";
5
+ const AGENT_NATIVE_PACKAGE_PREFIX = "@agent-native/";
6
+ function readPackageManifest(manifestPath) {
7
+ try {
8
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
9
+ return manifest && typeof manifest === "object"
10
+ ? manifest
11
+ : null;
12
+ }
13
+ catch {
14
+ // coercion-ok: missing or malformed manifests are typed absence from the optional version inventory.
15
+ return null;
16
+ }
17
+ }
18
+ function dependencyNames(manifest, includeDevDependencies = false) {
19
+ if (!manifest) {
20
+ return [];
21
+ }
22
+ return [
23
+ ...Object.keys(manifest.dependencies ?? {}),
24
+ ...Object.keys(manifest.optionalDependencies ?? {}),
25
+ ...Object.keys(manifest.peerDependencies ?? {}),
26
+ ...(includeDevDependencies
27
+ ? Object.keys(manifest.devDependencies ?? {})
28
+ : []),
29
+ ];
30
+ }
31
+ function resolvePackageManifest(packageName, resolutionBase) {
32
+ let entryPath;
33
+ const packageRequire = createRequire(path.join(resolutionBase, "package.json"));
34
+ try {
35
+ entryPath = packageRequire.resolve(packageName);
36
+ }
37
+ catch {
38
+ if (packageName !== "@agent-native/core") {
39
+ return null;
40
+ }
41
+ const coreManifestPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../package.json");
42
+ const coreManifest = readPackageManifest(coreManifestPath);
43
+ return coreManifest?.name === packageName
44
+ ? { manifest: coreManifest, manifestPath: coreManifestPath }
45
+ : null;
46
+ }
47
+ let directory = path.dirname(entryPath);
48
+ for (let depth = 0; depth < 20; depth += 1) {
49
+ const manifestPath = path.join(directory, "package.json");
50
+ const manifest = readPackageManifest(manifestPath);
51
+ if (manifest?.name === packageName) {
52
+ return { manifest, manifestPath };
53
+ }
54
+ const parent = path.dirname(directory);
55
+ if (parent === directory) {
56
+ break;
57
+ }
58
+ directory = parent;
59
+ }
60
+ return null;
61
+ }
62
+ export function resolveAgentNativePackageVersions(cwd) {
63
+ const appManifest = readPackageManifest(path.join(cwd, "package.json"));
64
+ const packageNames = new Set([
65
+ "@agent-native/core",
66
+ ...dependencyNames(appManifest, true).filter((name) => name.startsWith(AGENT_NATIVE_PACKAGE_PREFIX)),
67
+ ]);
68
+ const resolvedVersions = new Map();
69
+ const queuedPackages = [...packageNames].map((packageName) => ({
70
+ packageName,
71
+ resolutionBase: cwd,
72
+ }));
73
+ while (queuedPackages.length > 0) {
74
+ const queuedPackage = queuedPackages.shift();
75
+ if (!queuedPackage)
76
+ continue;
77
+ const resolvedPackage = resolvePackageManifest(queuedPackage.packageName, queuedPackage.resolutionBase);
78
+ if (!resolvedPackage) {
79
+ continue;
80
+ }
81
+ const { manifest } = resolvedPackage;
82
+ if (typeof manifest.version === "string" && manifest.version.trim()) {
83
+ resolvedVersions.set(queuedPackage.packageName, manifest.version.trim());
84
+ }
85
+ for (const dependencyName of dependencyNames(manifest)) {
86
+ if (dependencyName.startsWith(AGENT_NATIVE_PACKAGE_PREFIX) &&
87
+ !packageNames.has(dependencyName)) {
88
+ packageNames.add(dependencyName);
89
+ queuedPackages.push({
90
+ packageName: dependencyName,
91
+ resolutionBase: path.dirname(resolvedPackage.manifestPath),
92
+ });
93
+ }
94
+ }
95
+ }
96
+ return Object.fromEntries([...resolvedVersions.entries()].sort(([left], [right]) => left.localeCompare(right)));
97
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.0.0-beta-20260820231735",
3
+ "version": "0.0.0-beta-20260820233158",
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": {