@agent-native/core 0.193.0-nightly-20260926200915 → 0.193.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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: 10192
34
+ - template files: 10195
@@ -27,6 +27,7 @@ time from the command menu (Cmd+K → "What's new") or from Settings.
27
27
 
28
28
  ### Fixed
29
29
 
30
+ - Analytics guides users to connect AI before continuing agent questions.
30
31
  - Archived dashboards no longer appear in public link previews
31
32
  - Human Review previews show same-organization dashboard charts for organization admins.
32
33
  - Show one recent prompt per chat turn.
@@ -13,10 +13,12 @@ time from the command menu (Cmd+K → "What's new") or from Settings.
13
13
 
14
14
  ### Improved
15
15
 
16
+ - Brand-kit and template uploads show how to connect file storage when it is not configured
16
17
  - Public asset library links show their title and description in previews.
17
18
 
18
19
  ### Fixed
19
20
 
21
+ - Reference-image uploads stay disabled until object storage is connected.
20
22
  - Public previews no longer show archived asset library details
21
23
 
22
24
  ## 2026-09-24
@@ -17,11 +17,17 @@ time from the command menu (Cmd+K → "What's new") or from Settings.
17
17
 
18
18
  ### Improved
19
19
 
20
+ - The bookings list shows the latest bookings first and keeps dates and times together.
21
+ - Colleague events use the saved accent color shown in the calendar sidebar.
20
22
  - If Zoom cannot confirm a meeting, Calendar keeps the booking and follows up with meeting details
21
23
  - Public booking links show their title, description, and duration in previews.
22
24
 
23
25
  ### Fixed
24
26
 
27
+ - Bookings with an uncertain Zoom response stay reserved for review without appearing as confirmed calendar events.
28
+ - Canceling a booking now resolves its Zoom meeting first.
29
+ - Public booking pages reject malformed meeting settings before reserving a slot.
30
+ - Shared booking cancellations require editor access, and unresolved Zoom meetings stay protected when meeting settings change.
25
31
  - Calendar rule Undo stays consistent during RSVP updates, and one failed event no longer blocks later activity.
26
32
  - Gong requests keep legacy credentials paired with their saved API endpoint
27
33
  - Reserved bookings reach Google Calendar when Zoom fails, and guests can retry when meeting creation never started.
@@ -5,6 +5,13 @@ from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
6
  ## 2026-09-26
7
7
 
8
+ ### Improved
9
+
10
+ - See the desktop app for your platform at a glance.
11
+ - The comments signup headline now wraps more evenly.
12
+ - The empty comments state now explains how screen recordings help AI agents.
13
+ - The empty comments view has a clearer headline and a focused signup action.
14
+
8
15
  ### Changed
9
16
 
10
17
  - The app entry now opens the shared sign-in and sign-up screen instead of a separate marketing page.
@@ -20,6 +27,7 @@ from the command menu (Cmd+K → "What's new") or from Settings.
20
27
 
21
28
  ### Fixed
22
29
 
30
+ - Clips checks storage before upload and offers Builder.io or your own S3-compatible keys when storage is missing.
23
31
  - Clips desktop sign-in now accepts authenticator codes when two-step verification is enabled.
24
32
  - Keep Builder login state after blocked popups and show feedback while retrying storage connection checks
25
33
  - Clips clears a stale recording overlay after an interrupted save
@@ -943,12 +943,45 @@ export const editorChromeBridgeScript: string = `"use strict";
943
943
  var editorChromeDocumentObserver = null;
944
944
  var editorChromeRootObserver = null;
945
945
  var repairingEditorChromeHost = false;
946
+ function isCanvasFocusTransferSafe() {
947
+ if (activeTextEditEl) return false;
948
+ var active = document.activeElement;
949
+ var visited = /* @__PURE__ */ new Set();
950
+ var focusTargetSelector = 'a[href], area[href], button, input:not([type="hidden"]), select, textarea, summary, iframe, audio[controls], video[controls], [tabindex], [contenteditable]:not([contenteditable="false"]), [role="button"], [role="link"], [role="switch"], [role="checkbox"], [role="radio"], [role="slider"], [role="spinbutton"], [role="menuitem"], [role="textbox"], [role="combobox"], [role="searchbox"]';
951
+ while (active && !visited.has(active)) {
952
+ visited.add(active);
953
+ if (isEditorTypingTarget(active) || active.closest?.(focusTargetSelector)) {
954
+ return false;
955
+ }
956
+ var shadowActive = active.shadowRoot?.activeElement;
957
+ if (shadowActive) {
958
+ active = shadowActive;
959
+ continue;
960
+ }
961
+ if (active !== document.body && active !== document.documentElement && active.matches?.(":focus-within")) {
962
+ return false;
963
+ }
964
+ return true;
965
+ }
966
+ return true;
967
+ }
968
+ function reportCanvasFocusState() {
969
+ if (readOnly || interactionMode) return;
970
+ window.parent.postMessage(
971
+ {
972
+ type: "agent-native:canvas-focus-state",
973
+ focusSafe: isCanvasFocusTransferSafe()
974
+ },
975
+ "*"
976
+ );
977
+ }
946
978
  function sendEditorChromeReady() {
947
979
  window.parent.postMessage(
948
980
  {
949
981
  type: "agent-native:editor-chrome-ready",
950
982
  routePath: window.location.pathname + window.location.search,
951
- documentId: runtimeDocumentId
983
+ documentId: runtimeDocumentId,
984
+ focusSafe: !readOnly && !interactionMode && isCanvasFocusTransferSafe()
952
985
  },
953
986
  "*"
954
987
  );
@@ -8440,7 +8473,7 @@ export const editorChromeBridgeScript: string = `"use strict";
8440
8473
  function isEditorTypingTarget(target) {
8441
8474
  if (!target || !target.closest) return false;
8442
8475
  return !!target.closest(
8443
- 'input, textarea, select, [contenteditable], [role="textbox"], [data-agent-native-text-editing]'
8476
+ 'input, textarea, select, [contenteditable], [role="textbox"], [role="combobox"], [role="searchbox"], [data-agent-native-text-editing]'
8444
8477
  );
8445
8478
  }
8446
8479
  var ALT_CODE_KEYS = {
@@ -17690,6 +17723,21 @@ export const editorChromeBridgeScript: string = `"use strict";
17690
17723
  ].forEach(function(type) {
17691
17724
  document.addEventListener(type, stopBlockedLayerInteraction, true);
17692
17725
  });
17726
+ document.addEventListener("focusin", reportCanvasFocusState, true);
17727
+ document.addEventListener(
17728
+ "focusout",
17729
+ function() {
17730
+ window.setTimeout(reportCanvasFocusState, 0);
17731
+ },
17732
+ true
17733
+ );
17734
+ document.addEventListener(
17735
+ "pointerup",
17736
+ function() {
17737
+ window.setTimeout(reportCanvasFocusState, 0);
17738
+ },
17739
+ true
17740
+ );
17693
17741
  shieldOverlay.addEventListener("click", selectElementAtEvent, true);
17694
17742
  shieldOverlay.addEventListener("contextmenu", openContextMenuAtEvent, true);
17695
17743
  selectionOverlay.addEventListener(
@@ -18805,6 +18853,10 @@ export const editorChromeBridgeScript: string = `"use strict";
18805
18853
  sendEditorChromeReady();
18806
18854
  return;
18807
18855
  }
18856
+ if (e.data.type === "agent-native:canvas-focus-state-probe") {
18857
+ reportCanvasFocusState();
18858
+ return;
18859
+ }
18808
18860
  if (e.data.type === "resume-text-edit") {
18809
18861
  var resumeScreenId = typeof e.data.screenId === "string" ? e.data.screenId : "";
18810
18862
  var resumeSelector = typeof e.data.selector === "string" ? e.data.selector : "";
@@ -18910,6 +18962,7 @@ export const editorChromeBridgeScript: string = `"use strict";
18910
18962
  if (selectedEl?.isConnected)
18911
18963
  positionOverlay(selectionOverlay, selectedEl);
18912
18964
  scheduleRuntimeLayerSnapshot();
18965
+ window.setTimeout(reportCanvasFocusState, 0);
18913
18966
  }
18914
18967
  return;
18915
18968
  }
@@ -5,8 +5,19 @@ from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
6
  ## 2026-09-26
7
7
 
8
+ ### Improved
9
+
10
+ - Human review runs are easier to scan, and expanded details have a clear boundary.
11
+ - Layers dragged out of frames now land at the board level, and copies keep their intended order and selection.
12
+
8
13
  ### Fixed
9
14
 
15
+ - Cmd+D places screen duplicates in the next open slot
16
+ - Dropping a layer beside a sibling keeps that insertion point.
17
+ - Human Review can preview customer designs
18
+ - Keyboard shortcuts stay responsive while live previews preserve focus in app controls
19
+ - Live-frame edits keep canvas keyboard shortcuts available after a drop
20
+ - Opening shared designs no longer fails during client startup
10
21
  - Canvas focus stays on toolbar controls when a live preview finishes loading
11
22
 
12
23
  ### Changed
@@ -22,6 +33,7 @@ from the command menu (Cmd+K → "What's new") or from Settings.
22
33
 
23
34
  ### Improved
24
35
 
36
+ - Design shows how to connect file storage before uploading media or fonts
25
37
  - Attach Figma frames and websites from focused dialogs while keeping prompt drafts and uploaded design.md files intact.
26
38
  - Recent designs now use the same consistent library card layout as templates.
27
39
  - Start designs from a focused prompt with editable suggestions, template previews, and a searchable recent-design library.
@@ -39,6 +51,12 @@ from the command menu (Cmd+K → "What's new") or from Settings.
39
51
 
40
52
  ### Fixed
41
53
 
54
+ - Design guides users to connect AI before continuing generation questions.
55
+ - Escape finishes a Pen path as an open vector; during a pointer gesture, it
56
+ cancels that gesture and keeps previously placed anchors.
57
+ - Pen paths remain available after save failures, and retries keep the active tool
58
+ - Pen retries keep extending the selected vector after a save failure
59
+ - Pressing Enter finishes a new Pen path and selects its vector on Move.
42
60
  - Failed Figma imports no longer leave empty designs behind, and malformed preview links stay safely on the current screen.
43
61
  - Fix live visual-edit recovery, handoff, and interaction workflows.
44
62
  - Human Review previews show the actual design when you have organization admin access.
@@ -1782,6 +1782,10 @@ export function DesignCanvas({
1782
1782
  null,
1783
1783
  );
1784
1784
  const scrollContainerRef = useRef<HTMLDivElement>(null);
1785
+ const focusScrollSurfaceRef = useRef<
1786
+ | ((fromIframeLoad?: boolean, iframeReportedFocusSafe?: boolean) => void)
1787
+ | null
1788
+ >(null);
1785
1789
  const reviewCanvasId = useId();
1786
1790
  const zoomLayerRef = useRef<HTMLDivElement>(null);
1787
1791
  const zoomSizeLayerRef = useRef<HTMLDivElement>(null);
@@ -4282,6 +4286,22 @@ export function DesignCanvas({
4282
4286
  markPreviewFrameReady();
4283
4287
  }
4284
4288
  if (!e.data || !e.data.type) return;
4289
+ if (
4290
+ trustedCurrentFrame &&
4291
+ sourceType === "localhost" &&
4292
+ !readOnly &&
4293
+ editMode &&
4294
+ !interactMode &&
4295
+ ((e.data.type === "agent-native:editor-chrome-ready" &&
4296
+ e.data.focusSafe === true) ||
4297
+ (e.data.type === "agent-native:canvas-focus-state" &&
4298
+ e.data.focusSafe === true))
4299
+ ) {
4300
+ focusScrollSurfaceRef.current?.(
4301
+ e.data.type === "agent-native:editor-chrome-ready",
4302
+ true,
4303
+ );
4304
+ }
4285
4305
  if (
4286
4306
  e.data.type === "agent-native:runtime-layer-snapshot-error" ||
4287
4307
  e.data.type === "agent-native:runtime-layer-snapshot-unchanged"
@@ -5719,6 +5739,9 @@ export function DesignCanvas({
5719
5739
  sourceType,
5720
5740
  bridgeUrl,
5721
5741
  liveEditBridgeKey,
5742
+ readOnly,
5743
+ editMode,
5744
+ interactMode,
5722
5745
  runtimeVerificationRequest,
5723
5746
  runtimeStructureTargetTransactionId,
5724
5747
  fusionUrl,
@@ -7693,7 +7716,7 @@ export function DesignCanvas({
7693
7716
  ? "100%"
7694
7717
  : (iframeHeight ?? undefined);
7695
7718
  const focusScrollSurface = useCallback(
7696
- (fromIframeLoad = false) => {
7719
+ (fromIframeLoad = false, iframeReportedFocusSafe = false) => {
7697
7720
  const surface = scrollContainerRef.current;
7698
7721
  if (
7699
7722
  !surface ||
@@ -7712,13 +7735,16 @@ export function DesignCanvas({
7712
7735
  }
7713
7736
  const focusedElement = document.activeElement;
7714
7737
  if (
7715
- fromIframeLoad &&
7738
+ (iframeReportedFocusSafe || fromIframeLoad) &&
7716
7739
  focusedElement !== document.body &&
7717
7740
  focusedElement !== iframeRef.current
7718
7741
  ) {
7719
7742
  return;
7720
7743
  }
7721
- if (focusedElement instanceof HTMLIFrameElement) {
7744
+ if (
7745
+ focusedElement instanceof HTMLIFrameElement &&
7746
+ !iframeReportedFocusSafe
7747
+ ) {
7722
7748
  try {
7723
7749
  const frameDocument = focusedElement.contentDocument;
7724
7750
  if (!frameDocument) {
@@ -7748,6 +7774,7 @@ export function DesignCanvas({
7748
7774
  },
7749
7775
  [editMode, interactMode],
7750
7776
  );
7777
+ focusScrollSurfaceRef.current = focusScrollSurface;
7751
7778
  const handleCanvasPointerEnter = useCallback(
7752
7779
  () => focusScrollSurface(),
7753
7780
  [focusScrollSurface],
@@ -8018,6 +8045,20 @@ export function DesignCanvas({
8018
8045
  })}
8019
8046
  allow={getDesignCanvasIframeAllow(externalPreviewUrl)}
8020
8047
  data-design-preview-iframe
8048
+ onFocus={(event) => {
8049
+ if (
8050
+ sourceType !== "localhost" ||
8051
+ readOnly ||
8052
+ !editMode ||
8053
+ interactMode
8054
+ ) {
8055
+ return;
8056
+ }
8057
+ event.currentTarget.contentWindow?.postMessage(
8058
+ { type: "agent-native:canvas-focus-state-probe" },
8059
+ "*",
8060
+ );
8061
+ }}
8021
8062
  onLoad={(event) => {
8022
8063
  if (!liveEditFrameRequiresBridge) markPreviewFrameReady();
8023
8064
  sendBridgeToContainer();
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-09-26
4
+ ---
5
+
6
+ Keyboard shortcuts stay responsive while live previews preserve focus in app controls
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-09-26
4
+ ---
5
+
6
+ Live-frame edits keep canvas keyboard shortcuts available after a drop
@@ -5,6 +5,16 @@ time from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
6
  ## 2026-09-26
7
7
 
8
+ ### Improved
9
+
10
+ - AI inbox rules now apply to recent mail, appear as inbox tabs, and can be refined in chat.
11
+
12
+ ### Fixed
13
+
14
+ - Fixed importance actions, label display, and triage loading feedback.
15
+ - Inbox setup now keeps result counts and undo available while rules refresh.
16
+ - Mail cancels stale thread-read cooldown retries after a newer unread action
17
+
8
18
  ### Changed
9
19
 
10
20
  - The app entry now opens the shared sign-in and sign-up screen instead of a separate marketing page.
@@ -429,10 +429,11 @@ export function AiInboxSetup({
429
429
  const visible =
430
430
  connected &&
431
431
  !googleStatus.isLoading &&
432
- !rulesLoading &&
433
432
  !jevAvailability.isLoading &&
434
433
  (forceOpen ||
435
- (settings?.aiSetupCompleted !== true && aiRules.length === 0));
434
+ (!rulesLoading &&
435
+ settings?.aiSetupCompleted !== true &&
436
+ aiRules.length === 0));
436
437
 
437
438
  useEffect(() => {
438
439
  const wasForceOpen = previousForceOpen.current;
@@ -482,7 +483,7 @@ export function AiInboxSetup({
482
483
  setStep((current) => (current + 1) as SetupStep);
483
484
  return;
484
485
  }
485
- if (!jevConfigured) return;
486
+ if (!jevConfigured || rulesLoading) return;
486
487
 
487
488
  setSaving(true);
488
489
  try {
@@ -816,7 +817,9 @@ export function AiInboxSetup({
816
817
  <Button
817
818
  variant="ghost"
818
819
  onClick={() => void skip()}
819
- disabled={saving}
820
+ disabled={
821
+ saving || (step === 2 && jevConfigured && rulesLoading)
822
+ }
820
823
  >
821
824
  {t("mail.sort.aiSetupSkip")}
822
825
  </Button>
@@ -828,11 +831,11 @@ export function AiInboxSetup({
828
831
  disabled={
829
832
  saving ||
830
833
  customTagIncomplete ||
831
- (step === 2 && !jevConfigured)
834
+ (step === 2 && (!jevConfigured || rulesLoading))
832
835
  }
833
- aria-busy={saving}
836
+ aria-busy={saving || (step === 2 && rulesLoading)}
834
837
  >
835
- {saving ? (
838
+ {saving || (step === 2 && rulesLoading) ? (
836
839
  <IconLoader2 className="size-4 animate-spin" />
837
840
  ) : null}
838
841
  {step === 2
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-09-26
4
+ ---
5
+
6
+ Inbox setup now keeps result counts and undo available while rules refresh.
@@ -3,6 +3,12 @@
3
3
  All notable user-facing changes to Agent-Native Plan are documented here. Open it any
4
4
  time from the command menu (Cmd+K → "What's new").
5
5
 
6
+ ## 2026-09-25
7
+
8
+ ### Improved
9
+
10
+ - Plan shows how to connect file storage before uploading images.
11
+
6
12
  ## 2026-09-09
7
13
 
8
14
  ### Improved
@@ -7,12 +7,20 @@ time from the command menu (Cmd+K → "What's new").
7
7
 
8
8
  ### Fixed
9
9
 
10
+ - Double-clicking slide text selects the word under the pointer.
11
+ - Empty decks no longer start exports or presentations or expose presentation links.
12
+ - Invalid or expired upload references stop instead of retrying
13
+ - Slides ask for a file when a prompt refers to an unattached document
10
14
  - Reference file imports now check storage availability before opening the file picker.
11
15
 
12
16
  ### Changed
13
17
 
14
18
  - The app entry now opens the shared sign-in and sign-up screen instead of a separate marketing page.
15
19
 
20
+ ### Removed
21
+
22
+ - Create decks directly from the prompt without a separate New Deck button.
23
+
16
24
  ## 2026-09-25
17
25
 
18
26
  ### Added
@@ -38,6 +46,10 @@ time from the command menu (Cmd+K → "What's new").
38
46
 
39
47
  ### Fixed
40
48
 
49
+ - Pressing Enter in a flex-anchored text box no longer adds extra blank lines when you leave editing, and Arabic text stays joined while you type
50
+ - Slides generation recovers from long pauses and lets you continue from the saved deck
51
+ - Slides guides users to connect AI before continuing deck questions.
52
+ - Slides checks object storage before uploads and offers Builder.io or your own S3-compatible keys when storage is missing.
41
53
  - Human Review previews show same-organization slides for organization admins without changing deck data.
42
54
  - Searching presentations keeps the results panel visible even when your workspace has no owned decks.
43
55
  - Shared-only presentations now open in Recent by default, copied templates wait for deck hydration, and retries remain idempotent.
@@ -186,8 +186,8 @@ export declare function createAutomationCallbackHandler(runtime: AutomationRunti
186
186
  duplicate?: undefined;
187
187
  eventId?: undefined;
188
188
  } | {
189
+ error?: undefined;
189
190
  accepted: boolean;
190
191
  duplicate: boolean;
191
192
  eventId: string;
192
- error?: undefined;
193
193
  }>;
@@ -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;
@@ -18,6 +18,7 @@ import { execFileSync } from "child_process";
18
18
  import fs from "fs";
19
19
  import path from "path";
20
20
  import { AGENT_BACKGROUND_PROCESSOR_A2A, AGENT_BACKGROUND_PROCESSOR_FIELD, AGENT_BACKGROUND_PROCESSOR_INTEGRATION, AGENT_BACKGROUND_PROCESSOR_ROUTE, AGENT_BACKGROUND_PROCESSOR_ROUTE_FIELD, AGENT_CHAT_PROCESS_RUN_PATH, isDurableBackgroundFlagExplicitlyDisabled, } from "../agent/durable-background.js";
21
+ import { getAppConfig } from "../app-config/index.js";
21
22
  import { INTEGRATION_RECOVERY_RUNTIME_MARKER, INTEGRATION_RETRY_SWEEP_PATH, INTEGRATION_RETRY_SWEEP_TOKEN_SUBJECT, isIntegrationDurableDispatchConfigured, } from "../integrations/integration-durable-dispatch-config.js";
22
23
  import { RECURRING_JOBS_SWEEP_PATH, RECURRING_JOBS_SWEEP_TOKEN_SUBJECT, } from "../jobs/scheduler-dispatch.js";
23
24
  import { findWorkspaceRoot } from "../scripts/utils.js";
@@ -69,9 +70,15 @@ const WORKSPACE_APPS_MANIFEST_DIR = ".agent-native";
69
70
  const WORKSPACE_APPS_MANIFEST_FILE = "workspace-apps.json";
70
71
  const WORKSPACE_ROOT_GOOGLE_CALLBACK_PATH = "/_agent-native/google/callback";
71
72
  const VERCEL_OUTPUT_DIR = ".vercel/output";
72
- const WORKSPACE_DIRECTORY_ENV_SNIPPET = `
73
+ function workspaceDirectoryEnvSnippet(workspaceApps) {
74
+ const orgDirectoryUrl = getAppConfig().workspace.orgDirectoryUrl?.trim();
75
+ if (!orgDirectoryUrl && !workspaceApps.some((app) => app.isDispatch)) {
76
+ return "";
77
+ }
78
+ return `
73
79
  const directoryOrigin =
74
80
  processRef.env.AGENT_NATIVE_ORG_DIRECTORY_URL ||
81
+ ${JSON.stringify(orgDirectoryUrl ?? null)} ||
75
82
  processRef.env.WORKSPACE_GATEWAY_URL ||
76
83
  processRef.env.APP_URL ||
77
84
  processRef.env.URL ||
@@ -81,6 +88,7 @@ const WORKSPACE_DIRECTORY_ENV_SNIPPET = `
81
88
  processRef.env.AGENT_NATIVE_ORG_DIRECTORY_URL = directoryOrigin;
82
89
  }
83
90
  `;
91
+ }
84
92
  export async function runWorkspaceDeploy(opts = {}) {
85
93
  const workspaceRoot = opts.workspaceRoot ?? findWorkspaceRoot(process.cwd()) ?? process.cwd();
86
94
  const config = await loadResolvedAgentNativeConfig(workspaceRoot, createAgentNativeConfigContext("build", process.env.CONTEXT ?? "production"));
@@ -162,6 +170,10 @@ function buildOneApp(workspaceRoot, appsDir, app, preset, execFile, workspaceApp
162
170
  const workspaceAppAudience = workspaceAppAudienceForApp(workspaceApps, app);
163
171
  const workspaceAppRouteAccess = workspaceAppRouteAccessForApp(workspaceApps, app);
164
172
  const workspaceGatewayUrl = process.env.VITE_WORKSPACE_GATEWAY_URL || workspaceBaseUrl();
173
+ const orgDirectoryUrl = getAppConfig().workspace.orgDirectoryUrl?.trim() ||
174
+ (workspaceApps.some((entry) => entry.isDispatch)
175
+ ? workspaceGatewayUrl
176
+ : null);
165
177
  const workspaceOAuthUrl = workspaceOAuthOrigin(workspaceGatewayUrl);
166
178
  const env = {
167
179
  ...process.env,
@@ -188,10 +200,8 @@ function buildOneApp(workspaceRoot, appsDir, app, preset, execFile, workspaceApp
188
200
  VITE_AGENT_NATIVE_WORKSPACE_APP_PUBLIC_PATHS: JSON.stringify(workspaceAppRouteAccess.publicPaths),
189
201
  VITE_AGENT_NATIVE_WORKSPACE_APP_PROTECTED_PATHS: JSON.stringify(workspaceAppRouteAccess.protectedPaths),
190
202
  VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON: JSON.stringify(workspaceApps),
191
- ...(workspaceGatewayUrl
192
- ? {
193
- AGENT_NATIVE_ORG_DIRECTORY_URL: process.env.AGENT_NATIVE_ORG_DIRECTORY_URL || workspaceGatewayUrl,
194
- }
203
+ ...(orgDirectoryUrl
204
+ ? { AGENT_NATIVE_ORG_DIRECTORY_URL: orgDirectoryUrl }
195
205
  : {}),
196
206
  ...(workspaceGatewayUrl
197
207
  ? {
@@ -695,7 +705,7 @@ function processorPathFromBody(body) {
695
705
  function setBasePathEnv() {
696
706
  const processRef = globalThis.process ??= { env: {} };
697
707
  processRef.env ??= {};
698
- ${WORKSPACE_DIRECTORY_ENV_SNIPPET}
708
+ ${workspaceDirectoryEnvSnippet(workspaceApps)}
699
709
  Object.assign(processRef.env, {
700
710
  AGENT_NATIVE_WORKSPACE: "1",
701
711
  AGENT_NATIVE_WORKSPACE_AUTH_MODE: ${JSON.stringify(workspaceAuthMode)},
@@ -793,7 +803,7 @@ globalThis.${INTEGRATION_RECOVERY_RUNTIME_MARKER} = true;
793
803
  function setBasePathEnv() {
794
804
  const processRef = globalThis.process ??= { env: {} };
795
805
  processRef.env ??= {};
796
- ${WORKSPACE_DIRECTORY_ENV_SNIPPET}
806
+ ${workspaceDirectoryEnvSnippet(workspaceApps)}
797
807
  Object.assign(processRef.env, {
798
808
  AGENT_NATIVE_WORKSPACE: "1",
799
809
  AGENT_NATIVE_WORKSPACE_AUTH_MODE: ${JSON.stringify(workspaceAuthMode)},
@@ -927,7 +937,7 @@ function normalizeBasePathArgs(args) {
927
937
  function setBasePathEnv() {
928
938
  const processRef = globalThis.process ??= { env: {} };
929
939
  processRef.env ??= {};
930
- ${WORKSPACE_DIRECTORY_ENV_SNIPPET}
940
+ ${workspaceDirectoryEnvSnippet(workspaceApps)}
931
941
  Object.assign(processRef.env, {
932
942
  AGENT_NATIVE_WORKSPACE: "1",
933
943
  AGENT_NATIVE_WORKSPACE_AUTH_MODE: ${JSON.stringify(workspaceAuthMode)},
@@ -990,7 +1000,7 @@ function patchVercelFunctionEntry(functionDir, app, workspaceApps, workspaceAuth
990
1000
  function setBasePathEnv() {
991
1001
  const processRef = globalThis.process ??= { env: {} };
992
1002
  processRef.env ??= {};
993
- ${WORKSPACE_DIRECTORY_ENV_SNIPPET}
1003
+ ${workspaceDirectoryEnvSnippet(workspaceApps)}
994
1004
  Object.assign(processRef.env, {
995
1005
  AGENT_NATIVE_WORKSPACE: "1",
996
1006
  AGENT_NATIVE_WORKSPACE_AUTH_MODE: ${JSON.stringify(workspaceAuthMode)},
@@ -16,6 +16,38 @@ const inFlightWorkspaceAppRegistryReads = new Map();
16
16
  function normalizedEmail(email) {
17
17
  return email.trim().toLowerCase();
18
18
  }
19
+ function workspaceManifestDispatchState(appsJson) {
20
+ if (appsJson === undefined)
21
+ return "missing";
22
+ if (!appsJson.trim()) {
23
+ throw new Error("AGENT_NATIVE_WORKSPACE_APPS_JSON must not be empty.");
24
+ }
25
+ let parsed;
26
+ try {
27
+ parsed = JSON.parse(appsJson);
28
+ }
29
+ catch (error) {
30
+ throw new Error("AGENT_NATIVE_WORKSPACE_APPS_JSON must contain valid JSON.", { cause: error });
31
+ }
32
+ const apps = Array.isArray(parsed)
33
+ ? parsed
34
+ : parsed && typeof parsed === "object" && "apps" in parsed
35
+ ? parsed.apps
36
+ : null;
37
+ if (!Array.isArray(apps) ||
38
+ apps.length === 0 ||
39
+ apps.some((app) => !app ||
40
+ typeof app !== "object" ||
41
+ typeof app.id !== "string" ||
42
+ !app.id.trim())) {
43
+ throw new Error("AGENT_NATIVE_WORKSPACE_APPS_JSON must contain apps with non-empty string ids.");
44
+ }
45
+ const hasDispatch = apps.some((app) => {
46
+ const entry = app;
47
+ return (entry.id.trim().toLowerCase() === "dispatch" || entry.isDispatch === true);
48
+ });
49
+ return hasDispatch ? "dispatch" : "no-dispatch";
50
+ }
19
51
  export function isStandaloneDispatchRuntime() {
20
52
  const app = getAppConfig().app;
21
53
  const isDispatch = [
@@ -32,6 +64,9 @@ function configuredWorkspaceDirectory() {
32
64
  const orgDirectoryUrl = workspace.orgDirectoryUrl?.trim();
33
65
  if (orgDirectoryUrl)
34
66
  return orgDirectoryUrl;
67
+ if (workspaceManifestDispatchState(workspace.appsJson) === "no-dispatch") {
68
+ return null;
69
+ }
35
70
  const gatewayUrl = workspace.gatewayUrl?.trim();
36
71
  if (!gatewayUrl)
37
72
  return null;
@@ -48,8 +48,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
48
48
  }>;
49
49
  /** DELETE /_agent-native/resources/:id — delete a resource */
50
50
  export declare function handleDeleteResource(event: any): Promise<{
51
- ok?: undefined;
52
51
  error: string;
52
+ ok?: undefined;
53
53
  } | {
54
54
  error?: undefined;
55
55
  ok: boolean;
@@ -57,16 +57,16 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
57
57
  /** POST /_agent-native/secrets/:key — write a secret. */
58
58
  export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
59
59
  error: string;
60
- ok?: undefined;
61
60
  status?: undefined;
61
+ ok?: undefined;
62
62
  } | {
63
63
  ok: boolean;
64
64
  status: string;
65
65
  error?: undefined;
66
66
  } | {
67
- ok?: undefined;
68
67
  error: string;
69
68
  removed?: undefined;
69
+ ok?: undefined;
70
70
  } | {
71
71
  ok: boolean;
72
72
  removed: boolean;
@@ -77,9 +77,9 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
77
77
  * or the current stored value without changing anything.
78
78
  */
79
79
  export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
80
- ok?: undefined;
81
80
  error: string;
82
81
  note?: undefined;
82
+ ok?: undefined;
83
83
  } | {
84
84
  ok: boolean;
85
85
  note?: undefined;
@@ -5,11 +5,11 @@
5
5
  * static suggestion list in `model-config.ts`.
6
6
  */
7
7
  export declare function createAgentEngineOllamaModelsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
8
- ok?: undefined;
9
8
  error: string;
9
+ ok?: undefined;
10
10
  models?: undefined;
11
11
  } | {
12
+ error?: undefined;
12
13
  ok: boolean;
13
14
  models: string[];
14
- error?: undefined;
15
15
  }>>;
@@ -419,8 +419,8 @@ export declare function createPublicRemoteAgentsHandler(discover?: PublicAgentDi
419
419
  error: string;
420
420
  agents?: undefined;
421
421
  } | {
422
- error?: undefined;
423
422
  agents: Omit<import("./agent-discovery.js").DiscoveredAgent, "auth" | "kind">[];
423
+ error?: undefined;
424
424
  }>>;
425
425
  export declare function getBuilderConnectErrorDisposition(error: unknown, connectAttemptId: string | null): "correlated" | "legacy" | null;
426
426
  export declare function getBuilderConnectErrorKey(ownerEmail: string, connectAttemptId?: string | null): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.193.0-nightly-20260926200915",
3
+ "version": "0.193.0",
4
4
  "description": "The agentic application framework for building autonomous agents with intuitive UIs",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -512,9 +512,9 @@
512
512
  "yaml": "^2.9.0",
513
513
  "yjs": "^13.6.32",
514
514
  "zod": "^4.3.6",
515
- "@agent-native/agentkit": "^0.3.1-nightly-20260926200915",
516
- "@agent-native/toolkit": "^0.22.1-nightly-20260926200915",
517
- "@agent-native/recap-cli": "0.5.44"
515
+ "@agent-native/agentkit": "^0.3.1",
516
+ "@agent-native/recap-cli": "0.5.45",
517
+ "@agent-native/toolkit": "^0.22.1"
518
518
  },
519
519
  "devDependencies": {
520
520
  "@ai-sdk/anthropic": "^3.0.71",