@agent-native/core 0.180.0 → 0.180.1-nightly-20260915205111

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 (24) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/calendar/app/hooks/use-events.ts +11 -2
  3. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +14 -20
  4. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +323 -109
  5. package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +48 -18
  6. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +22 -20
  7. package/corpus/templates/design/app/components/design/design-canvas/LocalNetworkAccessPrompt.tsx +92 -0
  8. package/corpus/templates/design/app/components/design/design-canvas/external-preview.ts +41 -0
  9. package/corpus/templates/design/app/pages/DesignEditor.tsx +55 -3
  10. package/corpus/templates/design/changelog/2026-09-15-fixed-padding-indicator-tick-marks-so-they-render-at-the-sam.md +6 -0
  11. package/dist/collab/awareness.d.ts +2 -2
  12. package/dist/collab/routes.d.ts +1 -1
  13. package/dist/collab/struct-routes.d.ts +1 -1
  14. package/dist/file-upload/actions/upload-image.d.ts +3 -3
  15. package/dist/notifications/routes.d.ts +3 -3
  16. package/dist/observability/routes.d.ts +3 -3
  17. package/dist/org/handlers.d.ts +1 -1
  18. package/dist/progress/routes.d.ts +1 -1
  19. package/dist/server/core-routes-plugin.d.ts +1 -1
  20. package/dist/vite/sentry-source-maps.js +12 -20
  21. package/docs/content/template-plan-automations.mdx +30 -30
  22. package/docs/content/template-plan-developers.mdx +10 -10
  23. package/docs/content/template-plan-review-workflow.mdx +2 -2
  24. package/package.json +3 -3
@@ -135,8 +135,50 @@ export interface ResponsiveInteractBarProps {
135
135
  onModeChange: (mode: "edit" | "annotate") => void;
136
136
  /** Annotate is editor-only; commenters get Edit alone. */
137
137
  canAnnotate: boolean;
138
+ onClose: () => void;
139
+ /**
140
+ * The docked (non-floating) bar sits in the canvas column, which is
141
+ * inset by the left rail's width via `paddingLeft`. A wide rail (e.g. the
142
+ * Code panel) plus a narrow window can squeeze that column so far that
143
+ * Close — the one control a stuck user is looking for — gets clipped by
144
+ * the column's `overflow-hidden` instead of just losing the device/zoom
145
+ * controls it sits next to. The caller renders `ResponsiveInteractExitButton`
146
+ * pinned outside that squeeze instead and sets this to `false` for the
147
+ * docked bar. The floating (minimal-UI) bar has no docked rail competing
148
+ * for width, so it keeps Close inline.
149
+ */
150
+ showClose?: boolean;
151
+ className?: string;
152
+ }
153
+
154
+ /**
155
+ * The Close/Exit control on its own, styled to match its home inside
156
+ * ResponsiveInteractBar. Exported so a caller can pin it somewhere the
157
+ * docked bar's own horizontal squeeze can't reach — see `showClose` above.
158
+ */
159
+ export function ResponsiveInteractExitButton({
160
+ onClose,
161
+ className,
162
+ }: {
138
163
  onClose: () => void;
139
164
  className?: string;
165
+ }) {
166
+ const t = useT();
167
+ return (
168
+ <Button
169
+ variant="ghost"
170
+ size="sm"
171
+ onClick={onClose}
172
+ aria-label={t("designEditor.responsiveInteract.exit")}
173
+ className={cn(
174
+ "h-7 shrink-0 cursor-pointer gap-1.5 rounded-md px-2 !text-[12px] text-muted-foreground hover:text-foreground",
175
+ className,
176
+ )}
177
+ >
178
+ <IconX className="size-4" />
179
+ {t("designEditor.responsiveInteract.exit")}
180
+ </Button>
181
+ );
140
182
  }
141
183
 
142
184
  /**
@@ -157,6 +199,7 @@ export function ResponsiveInteractBar({
157
199
  onModeChange,
158
200
  canAnnotate,
159
201
  onClose,
202
+ showClose = true,
160
203
  className,
161
204
  }: ResponsiveInteractBarProps) {
162
205
  const t = useT();
@@ -357,24 +400,11 @@ export function ResponsiveInteractBar({
357
400
  </Popover>
358
401
  </div>
359
402
  </div>
360
- <div className="flex shrink-0 items-center bg-[var(--design-editor-panel-bg)] pl-1">
361
- <Tooltip>
362
- <TooltipTrigger asChild>
363
- <Button
364
- variant="ghost"
365
- size="icon"
366
- onClick={onClose}
367
- aria-label={t("designEditor.responsiveInteract.exit")}
368
- className="size-7 shrink-0 cursor-pointer rounded-md text-muted-foreground hover:text-foreground"
369
- >
370
- <IconX className="size-4" />
371
- </Button>
372
- </TooltipTrigger>
373
- <TooltipContent side="bottom">
374
- {t("designEditor.responsiveInteract.exit")}
375
- </TooltipContent>
376
- </Tooltip>
377
- </div>
403
+ {showClose ? (
404
+ <div className="flex shrink-0 items-center bg-[var(--design-editor-panel-bg)] pl-1">
405
+ <ResponsiveInteractExitButton onClose={onClose} />
406
+ </div>
407
+ ) : null}
378
408
  </div>
379
409
  );
380
410
  }
@@ -6352,11 +6352,14 @@ declare var __INITIAL_SOURCE_HEAD__: string;
6352
6352
  var paddingRight = readPx(cs.paddingRight);
6353
6353
  var paddingBottom = readPx(cs.paddingBottom);
6354
6354
  var paddingLeft = readPx(cs.paddingLeft);
6355
- var sx = chromeScaleX();
6356
- var sy = chromeScaleY();
6357
6355
  var line = chromeLineScale();
6358
- var hLineWidth = Math.max(6, Math.min(18, rect.width * 0.12)) * sx;
6359
- var vLineHeight = Math.max(6, Math.min(18, rect.height * 0.12)) * sy;
6356
+ // Both orientations derive their tick length from the same metric (the
6357
+ // element's smaller dimension) and the same uniform scale factor, so a
6358
+ // horizontal (top/bottom) tick and a vertical (left/right) tick always
6359
+ // render at the same visual length.
6360
+ var tickLength =
6361
+ Math.max(6, Math.min(18, Math.min(rect.width, rect.height) * 0.12)) *
6362
+ line;
6360
6363
  var innerLeft = borderLeft;
6361
6364
  var innerTop = borderTop;
6362
6365
  var innerWidth = Math.max(1, rect.width - borderLeft - borderRight);
@@ -6378,9 +6381,9 @@ declare var __INITIAL_SOURCE_HEAD__: string;
6378
6381
  height: paddingTop,
6379
6382
  },
6380
6383
  line: {
6381
- x: rect.width / 2 - hLineWidth / 2,
6384
+ x: rect.width / 2 - tickLength / 2,
6382
6385
  y: innerTop + paddingTop / 2 - line / 2,
6383
- width: hLineWidth,
6386
+ width: tickLength,
6384
6387
  height: line,
6385
6388
  },
6386
6389
  }),
@@ -6403,9 +6406,9 @@ declare var __INITIAL_SOURCE_HEAD__: string;
6403
6406
  height: paddingBottom,
6404
6407
  },
6405
6408
  line: {
6406
- x: rect.width / 2 - hLineWidth / 2,
6409
+ x: rect.width / 2 - tickLength / 2,
6407
6410
  y: rect.height - borderBottom - paddingBottom / 2 - line / 2,
6408
- width: hLineWidth,
6411
+ width: tickLength,
6409
6412
  height: line,
6410
6413
  },
6411
6414
  }),
@@ -6429,9 +6432,9 @@ declare var __INITIAL_SOURCE_HEAD__: string;
6429
6432
  },
6430
6433
  line: {
6431
6434
  x: innerLeft + paddingLeft / 2 - line / 2,
6432
- y: rect.height / 2 - vLineHeight / 2,
6435
+ y: rect.height / 2 - tickLength / 2,
6433
6436
  width: line,
6434
- height: vLineHeight,
6437
+ height: tickLength,
6435
6438
  },
6436
6439
  }),
6437
6440
  );
@@ -6454,9 +6457,9 @@ declare var __INITIAL_SOURCE_HEAD__: string;
6454
6457
  },
6455
6458
  line: {
6456
6459
  x: rect.width - borderRight - paddingRight / 2 - line / 2,
6457
- y: rect.height / 2 - vLineHeight / 2,
6460
+ y: rect.height / 2 - tickLength / 2,
6458
6461
  width: line,
6459
- height: vLineHeight,
6462
+ height: tickLength,
6460
6463
  },
6461
6464
  }),
6462
6465
  );
@@ -6472,11 +6475,10 @@ declare var __INITIAL_SOURCE_HEAD__: string;
6472
6475
  var children = visibleLayoutChildren(el);
6473
6476
  if (children.length < 2) return [];
6474
6477
  var handles = [];
6475
- var sx = chromeScaleX();
6476
- var sy = chromeScaleY();
6477
6478
  var line = chromeLineScale();
6478
- var hLineWidth = 8 * sx;
6479
- var vLineHeight = 8 * sy;
6479
+ // Use the same uniform scale for both axes so a horizontal gap tick and
6480
+ // a vertical gap tick render at the same visual length.
6481
+ var tickLength = 8 * line;
6480
6482
  var isFlex = cs.display === "flex" || cs.display === "inline-flex";
6481
6483
  var isGrid = cs.display === "grid" || cs.display === "inline-grid";
6482
6484
  if (!isFlex && !isGrid) return handles;
@@ -6516,9 +6518,9 @@ declare var __INITIAL_SOURCE_HEAD__: string;
6516
6518
  region: { x: a.right, y: top, width: gap, height: height },
6517
6519
  line: {
6518
6520
  x: a.right + gap / 2 - line / 2,
6519
- y: top + height / 2 - vLineHeight / 2,
6521
+ y: top + height / 2 - tickLength / 2,
6520
6522
  width: line,
6521
- height: vLineHeight,
6523
+ height: tickLength,
6522
6524
  },
6523
6525
  }),
6524
6526
  );
@@ -6536,9 +6538,9 @@ declare var __INITIAL_SOURCE_HEAD__: string;
6536
6538
  value: cssGap,
6537
6539
  region: { x: left, y: a.bottom, width: width, height: gap },
6538
6540
  line: {
6539
- x: left + width / 2 - hLineWidth / 2,
6541
+ x: left + width / 2 - tickLength / 2,
6540
6542
  y: a.bottom + gap / 2 - line / 2,
6541
- width: hLineWidth,
6543
+ width: tickLength,
6542
6544
  height: line,
6543
6545
  },
6544
6546
  }),
@@ -0,0 +1,92 @@
1
+ import {
2
+ IconPlugConnected,
3
+ IconPlugConnectedX,
4
+ IconX,
5
+ } from "@tabler/icons-react";
6
+
7
+ import { Button } from "@/components/ui/button";
8
+
9
+ import type { BridgeRegistrationFailureKind } from "./external-preview";
10
+
11
+ /**
12
+ * Non-blocking floating card shown over a localhost screen when the live-edit
13
+ * bridge can't be reached. Deliberately NOT a full-cover overlay: the real
14
+ * iframe underneath (see `externalPreviewUrl`'s raw-URL fallback in
15
+ * DesignCanvas.tsx) is still rendering the actual running app, so this stays a
16
+ * small corner card the user can act on or dismiss without losing the view —
17
+ * mirrors the liveEditSameInstanceStalledError banner pattern just above it.
18
+ */
19
+ export function LocalNetworkAccessPrompt({
20
+ kind,
21
+ connecting,
22
+ onConnect,
23
+ onDismiss,
24
+ }: {
25
+ kind: BridgeRegistrationFailureKind;
26
+ connecting: boolean;
27
+ onConnect: () => void;
28
+ onDismiss: () => void;
29
+ }) {
30
+ // "unreachable" is the one confident case (permission is confirmed
31
+ // granted, so it's confirmed NOT the cause) — every other kind is
32
+ // deliberately hedged copy, never a diagnosed permission claim. See
33
+ // classifyBridgeRegistrationFailure's doc comment for why.
34
+ const isConfirmedUnreachable = kind === "unreachable";
35
+ return (
36
+ <div className="pointer-events-none absolute inset-x-0 bottom-4 z-10 flex justify-center px-4">
37
+ <div className="pointer-events-auto relative flex w-full max-w-[22rem] flex-col items-start gap-3 rounded-lg border bg-card p-4 shadow-md">
38
+ <Button
39
+ type="button"
40
+ variant="ghost"
41
+ size="icon"
42
+ className="absolute right-1.5 top-1.5 size-6"
43
+ onClick={onDismiss}
44
+ >
45
+ <IconX className="size-3.5" />
46
+ <span className="sr-only">
47
+ {
48
+ "Dismiss" /* i18n-ignore transient local dev connect card dismiss */
49
+ }
50
+ </span>
51
+ </Button>
52
+ <div className="flex size-8 shrink-0 items-center justify-center rounded-full bg-accent">
53
+ {isConfirmedUnreachable ? (
54
+ <IconPlugConnectedX className="size-4 text-accent-foreground" />
55
+ ) : (
56
+ <IconPlugConnected className="size-4 text-accent-foreground" />
57
+ )}
58
+ </div>
59
+ <div className="flex flex-col gap-0.5 pr-4">
60
+ <div className="text-sm font-medium text-foreground">
61
+ {
62
+ isConfirmedUnreachable
63
+ ? "Local dev server unreachable" /* i18n-ignore local dev connect card title */
64
+ : "Can't reach your local dev server" /* i18n-ignore local dev connect card title */
65
+ }
66
+ </div>
67
+ <div className="text-xs text-muted-foreground">
68
+ {
69
+ isConfirmedUnreachable
70
+ ? "Is it still running?" /* i18n-ignore local dev connect card body */
71
+ : "Your browser may need permission to connect to localhost — or the dev server may be offline." /* i18n-ignore local dev connect card body */
72
+ }
73
+ </div>
74
+ </div>
75
+ <Button
76
+ type="button"
77
+ size="sm"
78
+ onClick={onConnect}
79
+ disabled={connecting}
80
+ >
81
+ {
82
+ connecting
83
+ ? "Connecting…" /* i18n-ignore local dev connect card button, transient */
84
+ : isConfirmedUnreachable
85
+ ? "Retry" /* i18n-ignore local dev connect card button */
86
+ : "Connect" /* i18n-ignore local dev connect card button */
87
+ }
88
+ </Button>
89
+ </div>
90
+ </div>
91
+ );
92
+ }
@@ -45,6 +45,47 @@ export function resolveLiveEditPreviewUrl(args: {
45
45
  });
46
46
  }
47
47
 
48
+ /**
49
+ * A registration `fetch()` to the localhost bridge can fail for two very
50
+ * different reasons that look identical to page JS (both throw a generic
51
+ * `TypeError: Failed to fetch`, with zero visible network activity):
52
+ *
53
+ * - The dev server / bridge process is genuinely unreachable.
54
+ * - Chrome's Local Network Access permission (a same-origin-policy-adjacent
55
+ * browser security feature, distinct from CORS) is blocking the request
56
+ * because this page's origin hasn't been granted permission to reach a
57
+ * loopback address.
58
+ *
59
+ * `navigator.permissions.query({ name: "local-network-access" })` is a signal,
60
+ * not proof: it reports the SITE's standing permission grant, not why THIS
61
+ * particular fetch failed — a `"prompt"` state is also the default on a first
62
+ * visit regardless of whether the dev server happens to be reachable, so it
63
+ * does not establish that permission was the actual cause. Only `"granted"`
64
+ * is unambiguous (permission is definitely fine, so it's definitely not the
65
+ * cause). Everything else — `"prompt"`, an unsupported browser, or the query
66
+ * throwing — stays in the same "maybePermissionBlocked" bucket, which the UI
67
+ * must present as a possibility to try, never as a diagnosed fact.
68
+ */
69
+ export type BridgeRegistrationFailureKind =
70
+ | "maybePermissionBlocked"
71
+ | "unreachable";
72
+
73
+ export async function classifyBridgeRegistrationFailure(): Promise<BridgeRegistrationFailureKind> {
74
+ try {
75
+ if (typeof navigator === "undefined" || !navigator.permissions?.query) {
76
+ return "maybePermissionBlocked";
77
+ }
78
+ const status = await navigator.permissions.query({
79
+ name: "local-network-access" as PermissionName,
80
+ });
81
+ return status.state === "granted"
82
+ ? "unreachable"
83
+ : "maybePermissionBlocked";
84
+ } catch {
85
+ return "maybePermissionBlocked";
86
+ }
87
+ }
88
+
48
89
  export function shouldUseIframeLoadReadyFallback(
49
90
  usesLiveEditEditorBridge: boolean,
50
91
  ): boolean {
@@ -346,7 +346,10 @@ import { isWheelCameraGestureActive } from "@/components/design/multi-screen/whe
346
346
  import { MultiScreenCanvas } from "@/components/design/MultiScreenCanvas";
347
347
  import { QuestionFlow } from "@/components/design/QuestionFlow";
348
348
  import { ReadOnlyDesignBanner } from "@/components/design/ReadOnlyDesignBanner";
349
- import { ResponsiveInteractBar } from "@/components/design/ResponsiveInteractBar";
349
+ import {
350
+ ResponsiveInteractBar,
351
+ ResponsiveInteractExitButton,
352
+ } from "@/components/design/ResponsiveInteractBar";
350
353
  import { type ReviewCommentsPanelProps } from "@/components/design/ReviewCommentsPanel";
351
354
  import type { ReviewPanelProps } from "@/components/design/ReviewPanel";
352
355
  import { TokensPanel } from "@/components/design/TokensPanel";
@@ -15365,6 +15368,24 @@ function DesignEditor() {
15365
15368
  () => enterOverviewFromZoom(),
15366
15369
  [enterOverviewFromZoom],
15367
15370
  );
15371
+ // Escape is the standard "leave this mode" convention users try first, and
15372
+ // Interact had no keyboard path back to Edit at all — only the bar's Close
15373
+ // button. This listens on `window` in the default bubble phase, same as
15374
+ // useDesignHotkeys elsewhere, so a Radix layer (the device Select, zoom
15375
+ // Popover) still gets first refusal: its own document-level Escape
15376
+ // handling stops the event before it reaches here, matching
15377
+ // DesignColorPicker.escape.test.tsx's documented ordering. It intentionally
15378
+ // does not reuse useDesignHotkeys, which stays disabled in Interact so the
15379
+ // running prototype keeps owning every other shortcut.
15380
+ useEffect(() => {
15381
+ if (!responsiveInteractActive) return;
15382
+ const handleKeyDown = (event: KeyboardEvent) => {
15383
+ if (event.key !== "Escape" || event.defaultPrevented) return;
15384
+ handleExitResponsiveInteract();
15385
+ };
15386
+ window.addEventListener("keydown", handleKeyDown);
15387
+ return () => window.removeEventListener("keydown", handleKeyDown);
15388
+ }, [responsiveInteractActive, handleExitResponsiveInteract]);
15368
15389
  // Fit against the actual center canvas, not window.innerWidth: both rails
15369
15390
  // remain mounted in Interact, so window-level math can place a wide device
15370
15391
  // partly behind them. ResizeObserver also refits after either rail moves.
@@ -16196,8 +16217,11 @@ function DesignEditor() {
16196
16217
  onSendToBack: canEditDesign
16197
16218
  ? () => changeSelectedZIndex("back")
16198
16219
  : undefined,
16199
- // Interact owns the running app's keyboard behavior. The editor shell must
16200
- // not consume Escape or use it to change view/selection underneath it.
16220
+ // Interact owns the running app's keyboard behavior. The editor shell's
16221
+ // canvas Escape handling (selection clearing, drawing/pin-mode exit,
16222
+ // breakpoint targeting) must not fire underneath it — the separate
16223
+ // Escape listener next to handleExitResponsiveInteract covers leaving
16224
+ // Interact itself.
16201
16225
  onEscape: responsiveInteractActive ? undefined : handleEscapeHotkey,
16202
16226
  onEnter: handleEnterHotkey,
16203
16227
  onSelectParent: handleSelectParentLayer,
@@ -22898,6 +22922,13 @@ function DesignEditor() {
22898
22922
  onModeChange={handleModeChange}
22899
22923
  canAnnotate={canEditDesign}
22900
22924
  onClose={handleExitResponsiveInteract}
22925
+ // The docked bar sits in the canvas column, inset by the left rail's
22926
+ // width — a wide rail plus a narrow window can squeeze that column
22927
+ // enough to clip Close before anything else in the bar (see the
22928
+ // pinned ResponsiveInteractExitButton rendered alongside the left
22929
+ // rail below). The floating bar has no rail competing for width, so
22930
+ // it keeps Close inline.
22931
+ showClose={floating}
22901
22932
  className={
22902
22933
  floating
22903
22934
  ? "pointer-events-auto w-full max-w-[680px] rounded-lg border shadow-xl"
@@ -23410,6 +23441,27 @@ function DesignEditor() {
23410
23441
  </div>
23411
23442
  ) : null}
23412
23443
 
23444
+ {/* The docked bar's Close used to live inside a canvas column inset
23445
+ by the left rail's width (`leftChromeOverlayInset`). A wide rail
23446
+ (the Code panel is 640px) plus a modest window can squeeze that
23447
+ column until the bar's own `overflow-hidden` clips Close before
23448
+ it clips anything else in the row — the rail sits at z-[70], so a
23449
+ squeeze this severe doesn't just crowd Close, it makes it
23450
+ unreachable. Anchoring it here instead, to the canvas area's own
23451
+ right edge rather than the bar's shrunken one, guarantees a way
23452
+ out no matter how little room the rail has left the bar. Height-
23453
+ and edge-matched to the bar (h-12, pr-3) so it reads as the same
23454
+ row rather than a second floating control. Not needed for the
23455
+ floating (minimal-UI) bar: minimal UI hides this rail entirely. */}
23456
+ {responsiveInteractActive && !minimalUi ? (
23457
+ <div className="pointer-events-none absolute right-0 top-0 z-[80] flex h-12 items-center pr-3">
23458
+ <ResponsiveInteractExitButton
23459
+ onClose={handleExitResponsiveInteract}
23460
+ className="pointer-events-auto"
23461
+ />
23462
+ </div>
23463
+ ) : null}
23464
+
23413
23465
  {/* Interact owns the running app's surface (same reasoning as the
23414
23466
  Escape hotkey gate): its canvas tools and mode tabs belong to the
23415
23467
  infinite canvas, and ResponsiveInteractBar's Close is the way
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-09-15
4
+ ---
5
+
6
+ Fixed padding indicator tick marks so they render at the same length on every edge
@@ -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;
66
65
  states: {
67
66
  clientId: number;
68
67
  state: string;
69
68
  }[];
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;
81
80
  users: {
82
81
  clientId: number;
83
82
  lastSeen: number;
84
83
  }[];
84
+ error?: undefined;
85
85
  }>>;
@@ -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
- error: string;
30
29
  ok?: undefined;
30
+ error: string;
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;
@@ -3,25 +3,25 @@ declare const _default: import("../../action.js").ActionDefinition<{
3
3
  url?: string;
4
4
  filename?: string;
5
5
  }, {
6
+ id?: undefined;
6
7
  error: string;
7
8
  configured?: undefined;
8
9
  connectPath?: undefined;
9
10
  url?: undefined;
10
- id?: undefined;
11
11
  provider?: undefined;
12
12
  } | {
13
+ id?: undefined;
13
14
  error: string;
14
15
  configured: boolean;
15
16
  connectPath: string;
16
17
  url?: undefined;
17
- id?: undefined;
18
18
  provider?: undefined;
19
19
  } | {
20
- error?: undefined;
21
20
  configured?: undefined;
22
21
  connectPath?: undefined;
23
22
  url: string;
24
23
  id: string;
25
24
  provider: string;
25
+ error?: undefined;
26
26
  }>;
27
27
  export default _default;
@@ -11,14 +11,14 @@
11
11
  * DELETE /_agent-native/notifications/:id — delete
12
12
  */
13
13
  export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
14
- error?: undefined;
15
14
  count: number;
16
15
  updated?: undefined;
16
+ error?: undefined;
17
17
  ok?: undefined;
18
18
  } | {
19
- error?: undefined;
20
19
  count?: undefined;
21
20
  updated: number;
21
+ error?: undefined;
22
22
  ok?: undefined;
23
23
  } | {
24
24
  count?: undefined;
@@ -26,8 +26,8 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
26
26
  error: string;
27
27
  ok?: undefined;
28
28
  } | {
29
- error?: undefined;
30
29
  count?: undefined;
31
30
  updated?: undefined;
32
31
  ok: boolean;
32
+ error?: undefined;
33
33
  }>>;
@@ -41,16 +41,16 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
- error?: undefined;
45
44
  summary: import("./types.js").TraceSummary;
46
45
  spans: import("./types.js").TraceSpan[];
47
46
  id?: undefined;
47
+ error?: undefined;
48
48
  ok?: undefined;
49
49
  } | {
50
- error?: undefined;
51
50
  summary?: undefined;
52
51
  spans?: undefined;
53
52
  id: string;
53
+ error?: undefined;
54
54
  ok?: undefined;
55
55
  } | {
56
56
  summary?: undefined;
@@ -59,9 +59,9 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
59
59
  error: any;
60
60
  ok?: undefined;
61
61
  } | {
62
- error?: undefined;
63
62
  summary?: undefined;
64
63
  spans?: undefined;
65
64
  id?: undefined;
65
+ error?: undefined;
66
66
  ok: boolean;
67
67
  }>>;
@@ -52,9 +52,9 @@ export declare const setWorkspaceAppDefaultVisibilityHandler: import("h3").Event
52
52
  /** POST /_agent-native/org — create a new organization */
53
53
  export declare const createOrgHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
54
54
  success: boolean;
55
+ id?: undefined;
55
56
  name?: undefined;
56
57
  role?: undefined;
57
- id?: undefined;
58
58
  } | {
59
59
  success?: undefined;
60
60
  id: string;
@@ -15,6 +15,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
15
15
  error: string;
16
16
  ok?: undefined;
17
17
  } | {
18
- error?: undefined;
19
18
  ok: boolean;
19
+ error?: undefined;
20
20
  }>>;
@@ -396,8 +396,8 @@ export declare function createPublicRemoteAgentsHandler(discover?: PublicAgentDi
396
396
  error: string;
397
397
  agents?: undefined;
398
398
  } | {
399
- error?: undefined;
400
399
  agents: Omit<import("./agent-discovery.js").DiscoveredAgent, "auth">[];
400
+ error?: undefined;
401
401
  }>>;
402
402
  export declare function getBuilderConnectErrorDisposition(error: unknown, connectAttemptId: string | null): "correlated" | "legacy" | null;
403
403
  export declare function getBuilderConnectErrorKey(ownerEmail: string, connectAttemptId?: string | null): string;
@@ -4,7 +4,7 @@
4
4
  * captured events. Both derive it from the same `resolveAgentNativeBuildId()`
5
5
  * identifier so they can't drift apart independently.
6
6
  */
7
- import { readdir, rm } from "node:fs/promises";
7
+ import { rm } from "node:fs/promises";
8
8
  import path from "node:path";
9
9
  import { sentryVitePlugin } from "@sentry/vite-plugin";
10
10
  import { resolveAgentNativeBuildId } from "../shared/build-id.js";
@@ -44,18 +44,6 @@ export function resolveSentrySourceMapUploadConfig(env = process.env) {
44
44
  export function isSentrySourceMapUploadEnabled(env = process.env) {
45
45
  return resolveSentrySourceMapUploadConfig(env) !== null;
46
46
  }
47
- async function removeSourceMaps(directory) {
48
- const entries = await readdir(directory, { withFileTypes: true });
49
- await Promise.all(entries.map(async (entry) => {
50
- const filePath = path.join(directory, entry.name);
51
- if (entry.isDirectory()) {
52
- await removeSourceMaps(filePath);
53
- }
54
- else if (entry.name.endsWith(".map")) {
55
- await rm(filePath, { force: true });
56
- }
57
- }));
58
- }
59
47
  function createUploadedSourceMapCleanupPlugin() {
60
48
  return {
61
49
  name: "agent-native:delete-uploaded-sentry-source-maps",
@@ -63,13 +51,17 @@ function createUploadedSourceMapCleanupPlugin() {
63
51
  writeBundle: {
64
52
  order: "post",
65
53
  sequential: true,
66
- async handler(outputOptions) {
67
- if (outputOptions.dir) {
68
- await removeSourceMaps(outputOptions.dir);
69
- }
70
- else if (outputOptions.file) {
71
- await rm(`${outputOptions.file}.map`, { force: true });
72
- }
54
+ async handler(outputOptions, bundle) {
55
+ const outputDirectory = outputOptions.dir
56
+ ? outputOptions.dir
57
+ : path.dirname(outputOptions.file);
58
+ const sourceMapFileNames = Object.values(bundle).flatMap((output) => {
59
+ if (output.type === "asset") {
60
+ return output.fileName.endsWith(".map") ? [output.fileName] : [];
61
+ }
62
+ return output.map ? [`${output.fileName}.map`] : [];
63
+ });
64
+ await Promise.all(sourceMapFileNames.map((fileName) => rm(path.join(outputDirectory, fileName), { force: true })));
73
65
  },
74
66
  },
75
67
  };