@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.
- package/corpus/README.md +1 -1
- package/corpus/templates/calendar/app/hooks/use-events.ts +11 -2
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +14 -20
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +323 -109
- package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +48 -18
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +22 -20
- package/corpus/templates/design/app/components/design/design-canvas/LocalNetworkAccessPrompt.tsx +92 -0
- package/corpus/templates/design/app/components/design/design-canvas/external-preview.ts +41 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +55 -3
- package/corpus/templates/design/changelog/2026-09-15-fixed-padding-indicator-tick-marks-so-they-render-at-the-sam.md +6 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +3 -3
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +3 -3
- package/dist/org/handlers.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts +1 -1
- package/dist/vite/sentry-source-maps.js +12 -20
- package/docs/content/template-plan-automations.mdx +30 -30
- package/docs/content/template-plan-developers.mdx +10 -10
- package/docs/content/template-plan-review-workflow.mdx +2 -2
- 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
|
-
|
|
361
|
-
<
|
|
362
|
-
<
|
|
363
|
-
|
|
364
|
-
|
|
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
|
-
|
|
6359
|
-
|
|
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 -
|
|
6384
|
+
x: rect.width / 2 - tickLength / 2,
|
|
6382
6385
|
y: innerTop + paddingTop / 2 - line / 2,
|
|
6383
|
-
width:
|
|
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 -
|
|
6409
|
+
x: rect.width / 2 - tickLength / 2,
|
|
6407
6410
|
y: rect.height - borderBottom - paddingBottom / 2 - line / 2,
|
|
6408
|
-
width:
|
|
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 -
|
|
6435
|
+
y: rect.height / 2 - tickLength / 2,
|
|
6433
6436
|
width: line,
|
|
6434
|
-
height:
|
|
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 -
|
|
6460
|
+
y: rect.height / 2 - tickLength / 2,
|
|
6458
6461
|
width: line,
|
|
6459
|
-
height:
|
|
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
|
-
|
|
6479
|
-
|
|
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 -
|
|
6521
|
+
y: top + height / 2 - tickLength / 2,
|
|
6520
6522
|
width: line,
|
|
6521
|
-
height:
|
|
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 -
|
|
6541
|
+
x: left + width / 2 - tickLength / 2,
|
|
6540
6542
|
y: a.bottom + gap / 2 - line / 2,
|
|
6541
|
-
width:
|
|
6543
|
+
width: tickLength,
|
|
6542
6544
|
height: line,
|
|
6543
6545
|
},
|
|
6544
6546
|
}),
|
package/corpus/templates/design/app/components/design/design-canvas/LocalNetworkAccessPrompt.tsx
ADDED
|
@@ -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 {
|
|
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
|
|
16200
|
-
//
|
|
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
|
|
@@ -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
|
}>>;
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -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
|
}>>;
|
package/dist/org/handlers.d.ts
CHANGED
|
@@ -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;
|
|
@@ -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 {
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
};
|