@agent-native/core 0.0.0-beta-20260820220930 → 0.0.0-beta-20260820222620
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/templates/analytics/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/assets/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/brain/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/clips/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/clips/app/routes/download.tsx +78 -131
- package/corpus/templates/content/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/design/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/dispatch/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/factory/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/forms/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/macros/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/mail/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/plan/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/slides/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/client/blocks/library/diagram.config.d.ts +4 -1
- package/dist/client/blocks/library/diagram.js +1 -1
- package/dist/client/chat/run-recovery.js +15 -7
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/server/attribution.d.ts +29 -0
- package/dist/server/attribution.js +68 -0
- package/dist/server/auth.js +58 -15
- package/dist/server/better-auth-instance.js +16 -4
- package/dist/server/identity-sso.js +14 -2
- package/dist/server/request-context.d.ts +8 -0
- package/dist/server/request-context.js +4 -0
- package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/docs/content/deployment.mdx +3 -1
- package/package.json +2 -2
- package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +11 -0
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -4,20 +4,12 @@ import {
|
|
|
4
4
|
IconBrandChrome,
|
|
5
5
|
IconBrandApple,
|
|
6
6
|
IconBrandWindows,
|
|
7
|
-
IconChevronDown,
|
|
8
|
-
IconDeviceDesktop,
|
|
9
7
|
IconExternalLink,
|
|
8
|
+
IconTerminal2,
|
|
10
9
|
} from "@tabler/icons-react";
|
|
11
10
|
import { useEffect, useState } from "react";
|
|
12
11
|
|
|
13
12
|
import { Button } from "@/components/ui/button";
|
|
14
|
-
import {
|
|
15
|
-
DropdownMenu,
|
|
16
|
-
DropdownMenuContent,
|
|
17
|
-
DropdownMenuRadioGroup,
|
|
18
|
-
DropdownMenuRadioItem,
|
|
19
|
-
DropdownMenuTrigger,
|
|
20
|
-
} from "@/components/ui/dropdown-menu";
|
|
21
13
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
22
14
|
import enMessages from "@/i18n/en-US";
|
|
23
15
|
import {
|
|
@@ -45,7 +37,6 @@ type PlatformId = "mac" | "windows" | "linux";
|
|
|
45
37
|
interface PlatformVariant {
|
|
46
38
|
id: PlatformId;
|
|
47
39
|
label: string;
|
|
48
|
-
sublabel: string;
|
|
49
40
|
assetKinds: readonly (
|
|
50
41
|
| "mac-universal"
|
|
51
42
|
| "mac-arm64"
|
|
@@ -64,23 +55,20 @@ const VARIANTS: PlatformVariant[] = [
|
|
|
64
55
|
{
|
|
65
56
|
id: "mac",
|
|
66
57
|
label: "macOS",
|
|
67
|
-
sublabel: "Universal (Apple Silicon + Intel)",
|
|
68
58
|
assetKinds: ["mac-universal", "mac-arm64", "mac-x64"],
|
|
69
59
|
icon: IconBrandApple,
|
|
70
60
|
},
|
|
71
61
|
{
|
|
72
62
|
id: "windows",
|
|
73
63
|
label: "Windows",
|
|
74
|
-
sublabel: "64-bit MSI installer",
|
|
75
64
|
assetKinds: ["windows-msi"],
|
|
76
65
|
icon: IconBrandWindows,
|
|
77
66
|
},
|
|
78
67
|
{
|
|
79
68
|
id: "linux",
|
|
80
69
|
label: "Linux",
|
|
81
|
-
sublabel: "AppImage, Debian, and RPM packages",
|
|
82
70
|
assetKinds: ["linux-appimage", "linux-deb", "linux-rpm"],
|
|
83
|
-
icon:
|
|
71
|
+
icon: IconTerminal2,
|
|
84
72
|
},
|
|
85
73
|
];
|
|
86
74
|
|
|
@@ -171,47 +159,6 @@ function primaryDownloadButton(
|
|
|
171
159
|
);
|
|
172
160
|
}
|
|
173
161
|
|
|
174
|
-
function secondaryDownloadButton(
|
|
175
|
-
variant: PlatformVariant,
|
|
176
|
-
manifest: Manifest | null,
|
|
177
|
-
manifestError: boolean,
|
|
178
|
-
downloadLabel: string,
|
|
179
|
-
retryLabel: string,
|
|
180
|
-
onRetry: () => void,
|
|
181
|
-
) {
|
|
182
|
-
const asset = pickAsset(manifest, variant);
|
|
183
|
-
const Icon = variant.icon;
|
|
184
|
-
const className =
|
|
185
|
-
"h-auto gap-1.5 px-2 py-1 text-sm font-normal text-muted-foreground hover:bg-transparent hover:text-foreground";
|
|
186
|
-
if (asset) {
|
|
187
|
-
return (
|
|
188
|
-
<Button asChild variant="ghost" className={className}>
|
|
189
|
-
<a href={asset.url} download onClick={markDesktopAppDownloaded}>
|
|
190
|
-
<Icon className="h-4 w-4" />
|
|
191
|
-
{downloadLabel}
|
|
192
|
-
</a>
|
|
193
|
-
</Button>
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
if (manifest === null && !manifestError) {
|
|
197
|
-
return <Skeleton className="h-7 w-[208px] rounded-md" />;
|
|
198
|
-
}
|
|
199
|
-
if (manifestError) {
|
|
200
|
-
return (
|
|
201
|
-
<Button variant="ghost" className={className} onClick={onRetry}>
|
|
202
|
-
<Icon className="h-4 w-4" />
|
|
203
|
-
{retryLabel}
|
|
204
|
-
</Button>
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
return (
|
|
208
|
-
<Button variant="ghost" className={className} disabled>
|
|
209
|
-
<Icon className="h-4 w-4" />
|
|
210
|
-
{downloadLabel}
|
|
211
|
-
</Button>
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
162
|
export default function DownloadPage() {
|
|
216
163
|
const chromeExtensionEnabled = useClipsChromeExtensionEnabled();
|
|
217
164
|
const t = useT();
|
|
@@ -267,7 +214,11 @@ export default function DownloadPage() {
|
|
|
267
214
|
};
|
|
268
215
|
|
|
269
216
|
const primary = VARIANTS.find((v) => v.id === detected) ?? VARIANTS[0];
|
|
270
|
-
|
|
217
|
+
|
|
218
|
+
const handlePlatformChange = (nextPlatform: PlatformId) => {
|
|
219
|
+
if (nextPlatform === detected) return;
|
|
220
|
+
setDetected(nextPlatform);
|
|
221
|
+
};
|
|
271
222
|
|
|
272
223
|
return (
|
|
273
224
|
<div className="min-h-screen bg-background text-foreground">
|
|
@@ -317,87 +268,83 @@ export default function DownloadPage() {
|
|
|
317
268
|
{t("downloadRoute.heroDescription")}
|
|
318
269
|
</p>
|
|
319
270
|
|
|
320
|
-
<div className="mt-10 flex flex-col items-center
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
{manifest ? (
|
|
343
|
-
<>
|
|
344
|
-
{manifest.pub_date
|
|
345
|
-
? t("downloadRoute.versionReleased", {
|
|
346
|
-
version: manifest.version,
|
|
347
|
-
date: new Date(manifest.pub_date).toLocaleDateString(),
|
|
348
|
-
})
|
|
349
|
-
: t("downloadRoute.version", {
|
|
350
|
-
version: manifest.version,
|
|
351
|
-
})}
|
|
352
|
-
</>
|
|
353
|
-
) : manifestError ? (
|
|
354
|
-
<>{t("downloadRoute.manifestError")}</>
|
|
355
|
-
) : (
|
|
356
|
-
<>{t("downloadRoute.loadingRelease")}</>
|
|
357
|
-
)}
|
|
271
|
+
<div className="mt-10 flex flex-col items-center">
|
|
272
|
+
<div className="mb-2 flex justify-center gap-2">
|
|
273
|
+
{VARIANTS.map((variant) => {
|
|
274
|
+
const Icon = variant.icon;
|
|
275
|
+
const active = primary.id === variant.id;
|
|
276
|
+
return (
|
|
277
|
+
<button
|
|
278
|
+
key={variant.id}
|
|
279
|
+
type="button"
|
|
280
|
+
aria-label={variant.label}
|
|
281
|
+
aria-pressed={active}
|
|
282
|
+
onClick={() => handlePlatformChange(variant.id)}
|
|
283
|
+
className={`group flex items-center justify-center rounded-lg p-4 transition-opacity focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${
|
|
284
|
+
active
|
|
285
|
+
? "text-foreground"
|
|
286
|
+
: "text-muted-foreground opacity-40 hover:opacity-65"
|
|
287
|
+
}`}
|
|
288
|
+
>
|
|
289
|
+
<Icon className="size-6" aria-hidden="true" />
|
|
290
|
+
</button>
|
|
291
|
+
);
|
|
292
|
+
})}
|
|
358
293
|
</div>
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
294
|
+
|
|
295
|
+
<div className="mx-auto mt-8 max-w-2xl text-center">
|
|
296
|
+
{primaryDownloadButton(
|
|
297
|
+
primary,
|
|
298
|
+
manifest,
|
|
299
|
+
manifestError,
|
|
300
|
+
t("downloadRoute.downloadFor", { platform: primary.label }),
|
|
301
|
+
t("downloadRoute.retry"),
|
|
302
|
+
retryManifest,
|
|
303
|
+
)}
|
|
304
|
+
|
|
305
|
+
<div className="mt-5 flex justify-center">
|
|
306
|
+
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
|
307
|
+
<span>{t("downloadRoute.stable")}</span>
|
|
308
|
+
<button
|
|
363
309
|
type="button"
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
310
|
+
role="switch"
|
|
311
|
+
aria-checked={channel === "nightly"}
|
|
312
|
+
aria-label={t(
|
|
313
|
+
channel === "nightly"
|
|
314
|
+
? "downloadRoute.switchToStable"
|
|
315
|
+
: "downloadRoute.switchToNightly",
|
|
316
|
+
)}
|
|
317
|
+
onClick={() =>
|
|
318
|
+
handleChannelChange(
|
|
319
|
+
channel === "nightly" ? "production" : "nightly",
|
|
320
|
+
)
|
|
321
|
+
}
|
|
322
|
+
className={`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-border transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${
|
|
323
|
+
channel === "nightly"
|
|
324
|
+
? "bg-foreground"
|
|
325
|
+
: "bg-muted-foreground/20"
|
|
326
|
+
}`}
|
|
368
327
|
>
|
|
369
328
|
<span
|
|
370
|
-
|
|
329
|
+
aria-hidden="true"
|
|
330
|
+
className={`block size-3.5 rounded-full bg-primary-foreground shadow-sm transition-transform ${
|
|
371
331
|
channel === "nightly"
|
|
372
|
-
? "
|
|
373
|
-
:
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
<DropdownMenuContent align="center" className="w-44">
|
|
384
|
-
<DropdownMenuRadioGroup
|
|
385
|
-
value={channel}
|
|
386
|
-
onValueChange={(value) => {
|
|
387
|
-
if (value === "production" || value === "nightly") {
|
|
388
|
-
handleChannelChange(value);
|
|
389
|
-
}
|
|
390
|
-
}}
|
|
332
|
+
? "translate-x-[18px]"
|
|
333
|
+
: "translate-x-[2px]"
|
|
334
|
+
}`}
|
|
335
|
+
/>
|
|
336
|
+
</button>
|
|
337
|
+
<span
|
|
338
|
+
className={
|
|
339
|
+
channel === "nightly"
|
|
340
|
+
? "font-medium text-foreground"
|
|
341
|
+
: "text-muted-foreground"
|
|
342
|
+
}
|
|
391
343
|
>
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
{t("downloadRoute.nightly")}
|
|
397
|
-
</DropdownMenuRadioItem>
|
|
398
|
-
</DropdownMenuRadioGroup>
|
|
399
|
-
</DropdownMenuContent>
|
|
400
|
-
</DropdownMenu>
|
|
344
|
+
{t("downloadRoute.nightly")}
|
|
345
|
+
</span>
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
401
348
|
</div>
|
|
402
349
|
</div>
|
|
403
350
|
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -37,7 +37,10 @@ export interface DiagramData {
|
|
|
37
37
|
*/
|
|
38
38
|
html?: string;
|
|
39
39
|
css?: string;
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* `design` forces clean HTML/CSS rendering without the sketch overlay. Use it
|
|
42
|
+
* for UI-like blocks such as cards, logo walls, tables, and controls.
|
|
43
|
+
*/
|
|
41
44
|
renderMode?: "wireframe" | "design";
|
|
42
45
|
caption?: string;
|
|
43
46
|
/** Outer surface frame. `auto` lets the host choose the right default. */
|
|
@@ -393,7 +393,7 @@ export const diagramBlock = defineBlock({
|
|
|
393
393
|
// edit from a corner button + panel rather than inline.
|
|
394
394
|
editSurface: "panel",
|
|
395
395
|
label: "Diagram",
|
|
396
|
-
description: "A flexible inline architecture/code diagram. Prefer html/css with SVG or semantic HTML for polished two-dimensional layouts; use renderMode design for
|
|
396
|
+
description: "A flexible inline architecture/code diagram. Prefer html/css with SVG or semantic HTML for polished two-dimensional layouts; use renderMode design for UI-like blocks such as cards, logo walls, tables, and controls, or .diagram-* primitives and --wf-* tokens for actual diagrams that need theme/sketch compatibility. Legacy nodes/edges are only for simple previews.",
|
|
397
397
|
// Seed the legacy fallback shape so a fresh block validates while agents can
|
|
398
398
|
// replace it with html/css when layout quality matters.
|
|
399
399
|
empty: () => ({ nodes: [{ id: "n1", label: "Module" }], edges: [] }),
|
|
@@ -298,17 +298,25 @@ export function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDism
|
|
|
298
298
|
return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] p-3 text-sm", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-700 dark:text-amber-300", children: _jsx(IconAlertTriangle, { size: 14 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-foreground", children: runErrorHeadline(info, {
|
|
299
299
|
recoverable: t("agentChat.error.stopped"),
|
|
300
300
|
terminal: t("agentChat.error.failed"),
|
|
301
|
-
}) }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: localizeKnownChatErrorText(info.message, t) }), isProviderAuthError && (_jsx("div", { className: "mt-3 rounded-md border border-border/70 bg-background/60 p-2.5", children: _jsx(BuilderSetupContent, { layout: "sidebar", onConnected: handleProviderConnected }) })), shouldShowBuilderReconnect && !builderReconnectResolved && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: t("agentChat.recovery.credentialRejected") })), isConnectionRecoveryError && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: t("agentChat.recovery.newChatHint") })), (info.runId || info.errorCode || info.details) && (_jsxs("button", { type: "button", onClick: () => setDetailsOpen((v) => !v), className: "mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", detailsOpen && "rotate-180") }), t("agentChat.common.details")] })), detailsOpen && (_jsxs("div", { className: "mt-2 rounded-md border border-border/60 bg-background/70 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: [info.runId && _jsxs("div", { children: ["run: ", info.runId] }), info.errorCode && _jsxs("div", { children: ["code: ", info.errorCode] }), info.details && (_jsx("pre", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details }))] }))] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": t("agentChat.common.dismiss"), className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-background/80 hover:text-foreground", children: _jsx(IconX, { size: 14 }) })] }), _jsxs("div", { className: "mt-3 flex
|
|
301
|
+
}) }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: localizeKnownChatErrorText(info.message, t) }), isProviderAuthError && (_jsx("div", { className: "mt-3 rounded-md border border-border/70 bg-background/60 p-2.5", children: _jsx(BuilderSetupContent, { layout: "sidebar", onConnected: handleProviderConnected }) })), shouldShowBuilderReconnect && !builderReconnectResolved && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: t("agentChat.recovery.credentialRejected") })), isConnectionRecoveryError && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: t("agentChat.recovery.newChatHint") })), (info.runId || info.errorCode || info.details) && (_jsxs("button", { type: "button", onClick: () => setDetailsOpen((v) => !v), className: "mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", detailsOpen && "rotate-180") }), t("agentChat.common.details")] })), detailsOpen && (_jsxs("div", { className: "mt-2 rounded-md border border-border/60 bg-background/70 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: [info.runId && _jsxs("div", { children: ["run: ", info.runId] }), info.errorCode && _jsxs("div", { children: ["code: ", info.errorCode] }), info.details && (_jsx("pre", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details }))] }))] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": t("agentChat.common.dismiss"), className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-background/80 hover:text-foreground", children: _jsx(IconX, { size: 14 }) })] }), _jsxs("div", { className: "mt-3 flex min-w-0 items-center gap-2", children: [shouldShowBuilderReconnect && !builderReconnectResolved && (_jsxs("button", { type: "button", onClick: () => builderReconnect.start(), disabled: builderReconnect.connecting, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90 disabled:cursor-wait disabled:opacity-70", children: [builderReconnect.connecting ? (_jsx(IconLoader2, { size: 13, className: "animate-spin" })) : null, builderReconnect.connecting
|
|
302
302
|
? t("agentChat.recovery.connectingBuilder")
|
|
303
|
-
: t("agentChat.recovery.reconnectBuilder")] })), canRecover && (
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
303
|
+
: t("agentChat.recovery.reconnectBuilder")] })), canRecover && (_jsxs("button", { type: "button", onClick: onContinue, className: "inline-flex min-w-0 flex-1 items-center justify-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconPlayerPlay, { size: 13 }), _jsx("span", { className: "truncate", children: t("agentChat.common.continue") })] })), _jsxs("div", { className: "flex shrink-0 items-center gap-0.5 rounded-md border border-border/70 bg-background/60 p-0.5", children: [canRetry && (_jsx("button", { type: "button", onClick: onRetry, title: isQueryError
|
|
304
|
+
? t("agentChat.recovery.diagnoseRetry")
|
|
305
|
+
: t("agentChat.common.retry"), "aria-label": isQueryError
|
|
306
|
+
? t("agentChat.recovery.diagnoseRetry")
|
|
307
|
+
: t("agentChat.common.retry"), className: "inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground", children: _jsx(IconRefresh, { size: 14 }) })), canRecover && isConnectionRecoveryError && (_jsx("button", { type: "button", onClick: startNewChat, title: t("agentChat.tabs.newChat"), "aria-label": t("agentChat.tabs.newChat"), className: "inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground", children: _jsx(IconPlus, { size: 14 }) })), canRecover && onFork && !isConnectionRecoveryError && (_jsx("button", { type: "button", onClick: handleFork, disabled: forking, title: t("agentChat.recovery.forkDescription"), "aria-label": t("agentChat.recovery.forkDescription"), className: "inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground disabled:cursor-wait disabled:opacity-70", children: forking ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : (_jsx(IconGitFork, { size: 14 })) })), _jsxs("button", { type: "button", onClick: copyDetails, title: copyState === "copied"
|
|
308
308
|
? t("agentChat.common.copied")
|
|
309
309
|
: copyState === "failed"
|
|
310
310
|
? t("agentChat.recovery.copyFailed")
|
|
311
|
-
: copyLabel
|
|
311
|
+
: copyLabel, "aria-label": copyState === "copied"
|
|
312
|
+
? t("agentChat.common.copied")
|
|
313
|
+
: copyState === "failed"
|
|
314
|
+
? t("agentChat.recovery.copyFailed")
|
|
315
|
+
: copyLabel, className: "inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground", children: [copyState === "copied" ? (_jsx(IconCheck, { size: 14 })) : copyState === "failed" ? (_jsx(IconX, { size: 14 })) : (_jsx(IconCopy, { size: 14 })), _jsx("span", { className: "sr-only", "aria-live": "polite", children: copyState === "copied"
|
|
316
|
+
? t("agentChat.common.copied")
|
|
317
|
+
: copyState === "failed"
|
|
318
|
+
? t("agentChat.recovery.copyFailed")
|
|
319
|
+
: copyLabel })] })] })] }), shouldShowBuilderReconnect && builderReconnect.error && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-red-500", children: builderReconnect.error })), forkError && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-red-500", children: forkError }))] }));
|
|
312
320
|
}
|
|
313
321
|
// ─── LoopLimitContinueCard ────────────────────────────────────────────────────
|
|
314
322
|
export function LoopLimitContinueCard({ info, onContinue, }) {
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
|
|
14
14
|
count: number;
|
|
15
15
|
updated?: undefined;
|
|
16
|
-
ok?: undefined;
|
|
17
16
|
error?: undefined;
|
|
17
|
+
ok?: undefined;
|
|
18
18
|
} | {
|
|
19
19
|
count?: undefined;
|
|
20
20
|
updated: number;
|
|
21
|
-
ok?: undefined;
|
|
22
21
|
error?: undefined;
|
|
22
|
+
ok?: undefined;
|
|
23
23
|
} | {
|
|
24
24
|
count?: undefined;
|
|
25
25
|
updated?: undefined;
|
|
@@ -28,6 +28,6 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
|
|
|
28
28
|
} | {
|
|
29
29
|
count?: undefined;
|
|
30
30
|
updated?: undefined;
|
|
31
|
-
ok: boolean;
|
|
32
31
|
error?: undefined;
|
|
32
|
+
ok: boolean;
|
|
33
33
|
}>>;
|
|
@@ -35,6 +35,18 @@ export interface FirstTouchAttribution {
|
|
|
35
35
|
/** ISO timestamp of when the visitor first landed. */
|
|
36
36
|
landed_at?: string;
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Request-scoped browser attribution captured at the signup boundary.
|
|
40
|
+
* Better Auth may create the user in a later async callback where the
|
|
41
|
+
* original request headers are no longer available, so the values must be
|
|
42
|
+
* carried explicitly through that boundary.
|
|
43
|
+
*/
|
|
44
|
+
export interface SignupAttributionContext {
|
|
45
|
+
attribution: Record<string, string>;
|
|
46
|
+
anonymousId?: string;
|
|
47
|
+
}
|
|
48
|
+
/** Internal Better Auth handoff header; attribution is analytics-only. */
|
|
49
|
+
export declare const SIGNUP_ATTRIBUTION_HEADER_NAME = "x-agent-native-signup-attribution";
|
|
38
50
|
/** Cookie name written by the client (non-HttpOnly; non-sensitive). */
|
|
39
51
|
export declare const FIRST_TOUCH_COOKIE_NAME = "an_ft";
|
|
40
52
|
/**
|
|
@@ -87,3 +99,20 @@ export declare function deriveSignupAttribution(ft: FirstTouchAttribution | null
|
|
|
87
99
|
* error.
|
|
88
100
|
*/
|
|
89
101
|
export declare function signupAttributionFromCookieHeader(cookieHeader: string | null | undefined): Record<string, string>;
|
|
102
|
+
/**
|
|
103
|
+
* Capture all browser attribution needed by the server-side signup event.
|
|
104
|
+
* Keep this as one boundary helper so every signup entry point carries the
|
|
105
|
+
* same values into Better Auth's user-create hook.
|
|
106
|
+
*/
|
|
107
|
+
export declare function signupAttributionContextFromCookieHeader(cookieHeader: string | null | undefined): SignupAttributionContext;
|
|
108
|
+
/** Serialize the bounded attribution handoff for a Better Auth request. */
|
|
109
|
+
export declare function encodeSignupAttributionContext(context: SignupAttributionContext): string;
|
|
110
|
+
/**
|
|
111
|
+
* Decode the internal handoff header. Invalid input is absent, not a direct
|
|
112
|
+
* attribution, so the caller can safely fall back to the request cookie.
|
|
113
|
+
*/
|
|
114
|
+
export declare function decodeSignupAttributionContext(value: string | null | undefined): SignupAttributionContext | undefined;
|
|
115
|
+
/** Add the explicit handoff to a Better Auth request/API header set. */
|
|
116
|
+
export declare function addSignupAttributionHeader(headers: HeadersInit | undefined, context: SignupAttributionContext): Headers;
|
|
117
|
+
/** Read the explicit handoff from Better Auth's request context headers. */
|
|
118
|
+
export declare function signupAttributionContextFromHeaders(headers: Headers | null | undefined): SignupAttributionContext | undefined;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { ANALYTICS_ANONYMOUS_ID_COOKIE_NAME, normalizeAnalyticsAnonymousId, } from "../shared/analytics-anonymous-id.js";
|
|
2
|
+
/** Internal Better Auth handoff header; attribution is analytics-only. */
|
|
3
|
+
export const SIGNUP_ATTRIBUTION_HEADER_NAME = "x-agent-native-signup-attribution";
|
|
4
|
+
const SIGNUP_ATTRIBUTION_HEADER_MAX_LENGTH = 4096;
|
|
2
5
|
/** Cookie name written by the client (non-HttpOnly; non-sensitive). */
|
|
3
6
|
export const FIRST_TOUCH_COOKIE_NAME = "an_ft";
|
|
4
7
|
const STRING_FIELDS = [
|
|
@@ -178,3 +181,68 @@ export function signupAttributionFromCookieHeader(cookieHeader) {
|
|
|
178
181
|
return { referral_source: "direct" };
|
|
179
182
|
}
|
|
180
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Capture all browser attribution needed by the server-side signup event.
|
|
186
|
+
* Keep this as one boundary helper so every signup entry point carries the
|
|
187
|
+
* same values into Better Auth's user-create hook.
|
|
188
|
+
*/
|
|
189
|
+
export function signupAttributionContextFromCookieHeader(cookieHeader) {
|
|
190
|
+
const anonymousId = readAnalyticsAnonymousId(cookieHeader);
|
|
191
|
+
return {
|
|
192
|
+
attribution: signupAttributionFromCookieHeader(cookieHeader),
|
|
193
|
+
...(anonymousId ? { anonymousId } : {}),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/** Serialize the bounded attribution handoff for a Better Auth request. */
|
|
197
|
+
export function encodeSignupAttributionContext(context) {
|
|
198
|
+
return encodeURIComponent(JSON.stringify(context));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Decode the internal handoff header. Invalid input is absent, not a direct
|
|
202
|
+
* attribution, so the caller can safely fall back to the request cookie.
|
|
203
|
+
*/
|
|
204
|
+
export function decodeSignupAttributionContext(value) {
|
|
205
|
+
if (!value || value.length > SIGNUP_ATTRIBUTION_HEADER_MAX_LENGTH) {
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
try {
|
|
209
|
+
const parsed = JSON.parse(decodeURIComponent(value));
|
|
210
|
+
const rawAttribution = parsed?.attribution;
|
|
211
|
+
if (!rawAttribution ||
|
|
212
|
+
typeof rawAttribution !== "object" ||
|
|
213
|
+
Array.isArray(rawAttribution)) {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
const attribution = {};
|
|
217
|
+
for (const [key, rawValue] of Object.entries(rawAttribution)) {
|
|
218
|
+
if (/^[A-Za-z0-9_]+$/.test(key) &&
|
|
219
|
+
key.length <= 64 &&
|
|
220
|
+
typeof rawValue === "string" &&
|
|
221
|
+
rawValue.length > 0) {
|
|
222
|
+
attribution[key] = rawValue.slice(0, 120);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (Object.keys(attribution).length === 0)
|
|
226
|
+
return undefined;
|
|
227
|
+
const anonymousId = normalizeAnalyticsAnonymousId(parsed?.anonymousId);
|
|
228
|
+
return {
|
|
229
|
+
attribution,
|
|
230
|
+
...(anonymousId ? { anonymousId } : {}),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
// `undefined` distinguishes an unreadable handoff from direct attribution.
|
|
235
|
+
void error;
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/** Add the explicit handoff to a Better Auth request/API header set. */
|
|
240
|
+
export function addSignupAttributionHeader(headers, context) {
|
|
241
|
+
const result = new Headers(headers);
|
|
242
|
+
result.set(SIGNUP_ATTRIBUTION_HEADER_NAME, encodeSignupAttributionContext(context));
|
|
243
|
+
return result;
|
|
244
|
+
}
|
|
245
|
+
/** Read the explicit handoff from Better Auth's request context headers. */
|
|
246
|
+
export function signupAttributionContextFromHeaders(headers) {
|
|
247
|
+
return decodeSignupAttributionContext(headers?.get(SIGNUP_ATTRIBUTION_HEADER_NAME));
|
|
248
|
+
}
|
package/dist/server/auth.js
CHANGED
|
@@ -58,7 +58,7 @@ import { isValidWorkspaceAppIdFormat } from "../shared/workspace-app-id.js";
|
|
|
58
58
|
import { injectAnalyticsIntoHtml } from "./analytics.js";
|
|
59
59
|
import { getConfiguredAppBasePath } from "./app-base-path.js";
|
|
60
60
|
import { getAppProductionUrl } from "./app-url.js";
|
|
61
|
-
import { readAnalyticsAnonymousId, readFirstTouchAttribution, signupAttributionFromCookieHeader, } from "./attribution.js";
|
|
61
|
+
import { addSignupAttributionHeader, readAnalyticsAnonymousId, readFirstTouchAttribution, signupAttributionContextFromCookieHeader, signupAttributionFromCookieHeader, } from "./attribution.js";
|
|
62
62
|
import { getAuthLoginMode } from "./auth-login-mode.js";
|
|
63
63
|
import { injectBetaOptOutPersistence } from "./beta-opt-out-html.js";
|
|
64
64
|
import { createBetterAuthSessionForEmail, ensureGoogleAuthIdentity, getAuthSecret, getBetterAuth, getBetterAuthSync, isDeployPreview, } from "./better-auth-instance.js";
|
|
@@ -73,6 +73,7 @@ import { ensureCanonicalUserForLegacySession } from "./legacy-auth-migration.js"
|
|
|
73
73
|
import { encodeMagicLinkSignupAttribution, MAGIC_LINK_ATTRIBUTION_PARAM, } from "./magic-link-attribution.js";
|
|
74
74
|
import { safeOAuthReturnUrl } from "./oauth-return-url.js";
|
|
75
75
|
import { getOnboardingHtml, getResetPasswordHtml, } from "./onboarding-html.js";
|
|
76
|
+
import { getRequestContext, hasContinuationLocalRequestContext, runWithRequestContext, } from "./request-context.js";
|
|
76
77
|
import { captureAuthError } from "./sentry.js";
|
|
77
78
|
import { forgetCachedSessionEmail, getCachedSessionEmail, invalidateSessionEmailCache, setCachedSessionEmail, } from "./session-email-cache.js";
|
|
78
79
|
import { isWorkspaceOAuthCallbackRelayEnabled } from "./workspace-oauth.js";
|
|
@@ -83,6 +84,23 @@ import { isWorkspaceOAuthCallbackRelayEnabled } from "./workspace-oauth.js";
|
|
|
83
84
|
export function getSessionMaxAge() {
|
|
84
85
|
return sessionMaxAge;
|
|
85
86
|
}
|
|
87
|
+
function withSignupAttributionContext(cookieHeader, fn) {
|
|
88
|
+
const signupAttribution = signupAttributionContextFromCookieHeader(cookieHeader);
|
|
89
|
+
if (!hasContinuationLocalRequestContext())
|
|
90
|
+
return fn();
|
|
91
|
+
return runWithRequestContext({
|
|
92
|
+
...(getRequestContext() ?? {}),
|
|
93
|
+
signupAttribution,
|
|
94
|
+
}, fn);
|
|
95
|
+
}
|
|
96
|
+
function requestWithSignupAttribution(request, signupAttribution) {
|
|
97
|
+
return new Request(request, {
|
|
98
|
+
headers: addSignupAttributionHeader(request.headers, signupAttribution),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function headersWithSignupAttribution(headers, cookieHeader) {
|
|
102
|
+
return addSignupAttributionHeader(headers, signupAttributionContextFromCookieHeader(cookieHeader));
|
|
103
|
+
}
|
|
86
104
|
// ---------------------------------------------------------------------------
|
|
87
105
|
// Constants
|
|
88
106
|
// ---------------------------------------------------------------------------
|
|
@@ -416,6 +434,9 @@ async function readDesktopSsoSafely(event) {
|
|
|
416
434
|
return null;
|
|
417
435
|
return await readDesktopSso();
|
|
418
436
|
}
|
|
437
|
+
function isDesktopSessionCookieOnlyCheck(event) {
|
|
438
|
+
return getHeader(event, "x-agent-native-session-check") === "cookie-only";
|
|
439
|
+
}
|
|
419
440
|
/**
|
|
420
441
|
* Extract the framework session token from a Better Auth response's
|
|
421
442
|
* Set-Cookie headers, if any. Used by the password-reset path to skip
|
|
@@ -2688,6 +2709,7 @@ export async function getSession(event) {
|
|
|
2688
2709
|
})());
|
|
2689
2710
|
}
|
|
2690
2711
|
async function resolveSessionUncached(event) {
|
|
2712
|
+
const cookieOnlyDesktopCheck = isDesktopSessionCookieOnlyCheck(event);
|
|
2691
2713
|
// 1. MCP App embed session. This is a short-lived browser session minted
|
|
2692
2714
|
// from a one-time ticket that was scoped to the authenticated MCP caller.
|
|
2693
2715
|
// It lets an inline MCP App iframe load the real app without reusing the
|
|
@@ -2724,9 +2746,11 @@ async function resolveSessionUncached(event) {
|
|
|
2724
2746
|
// templates too. Gated on `readDesktopSsoSafely` so a non-loopback
|
|
2725
2747
|
// request that spoofs `User-Agent: ... Electron/...` cannot read the
|
|
2726
2748
|
// home-dir broker file (and so production builds never consult it).
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2749
|
+
if (!cookieOnlyDesktopCheck) {
|
|
2750
|
+
const sso = await readDesktopSsoSafely(event);
|
|
2751
|
+
if (sso?.email)
|
|
2752
|
+
return { email: sso.email, token: sso.token };
|
|
2753
|
+
}
|
|
2730
2754
|
// Fall through to mobile _session check
|
|
2731
2755
|
}
|
|
2732
2756
|
else {
|
|
@@ -2765,9 +2789,11 @@ async function resolveSessionUncached(event) {
|
|
|
2765
2789
|
// a loopback (127.0.0.1 / ::1) source IP, and a non-production NODE_ENV
|
|
2766
2790
|
// — anything else is rejected so a hostile network request cannot
|
|
2767
2791
|
// impersonate whichever email last signed into the desktop app.
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2792
|
+
if (!cookieOnlyDesktopCheck) {
|
|
2793
|
+
const sso = await readDesktopSsoSafely(event);
|
|
2794
|
+
if (sso?.email) {
|
|
2795
|
+
return { email: sso.email, token: sso.token };
|
|
2796
|
+
}
|
|
2771
2797
|
}
|
|
2772
2798
|
}
|
|
2773
2799
|
// 8. Mobile WebView bridge — _session query param
|
|
@@ -3699,11 +3725,18 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
3699
3725
|
getMethod(event) === "POST";
|
|
3700
3726
|
const isMagicLinkRequest = reqPath.includes("/sign-in/magic-link") && getMethod(event) === "POST";
|
|
3701
3727
|
const isMagicLinkVerification = reqPath.includes("/magic-link/verify") && getMethod(event) === "GET";
|
|
3728
|
+
const isEmailSignup = reqPath.includes("/sign-up/email") && getMethod(event) === "POST";
|
|
3702
3729
|
const isSignOut = reqPath.includes("sign-out") && getMethod(event) === "POST";
|
|
3703
3730
|
if (isSignOut)
|
|
3704
3731
|
optOutOfAuthDisabledSession(event);
|
|
3705
3732
|
const authRequest = toWebRequest(event);
|
|
3706
3733
|
let requestForAuth = authRequest;
|
|
3734
|
+
const signupCookieHeader = isEmailSignup
|
|
3735
|
+
? authRequest.headers.get("cookie")
|
|
3736
|
+
: undefined;
|
|
3737
|
+
const signupAttribution = isEmailSignup
|
|
3738
|
+
? signupAttributionContextFromCookieHeader(signupCookieHeader)
|
|
3739
|
+
: undefined;
|
|
3707
3740
|
let magicLinkPreConsume;
|
|
3708
3741
|
if (isMagicLinkVerification) {
|
|
3709
3742
|
const verificationURL = new URL(authRequest.url);
|
|
@@ -3820,9 +3853,14 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
3820
3853
|
// validation error.
|
|
3821
3854
|
}
|
|
3822
3855
|
}
|
|
3856
|
+
if (signupAttribution) {
|
|
3857
|
+
requestForAuth = requestWithSignupAttribution(requestForAuth, signupAttribution);
|
|
3858
|
+
}
|
|
3823
3859
|
let response;
|
|
3824
3860
|
try {
|
|
3825
|
-
response = await
|
|
3861
|
+
response = await (isEmailSignup
|
|
3862
|
+
? withSignupAttributionContext(signupCookieHeader, () => auth.handler(requestForAuth))
|
|
3863
|
+
: auth.handler(requestForAuth));
|
|
3826
3864
|
}
|
|
3827
3865
|
catch (error) {
|
|
3828
3866
|
if (isMagicLinkVerification) {
|
|
@@ -4127,10 +4165,15 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
4127
4165
|
return { error: GOOGLE_AUTH_REQUIRED_MESSAGE };
|
|
4128
4166
|
}
|
|
4129
4167
|
try {
|
|
4130
|
-
await auth.api.signUpEmail({
|
|
4131
|
-
body: {
|
|
4132
|
-
|
|
4133
|
-
|
|
4168
|
+
await withSignupAttributionContext(getHeader(event, "cookie") ?? null, () => auth.api.signUpEmail({
|
|
4169
|
+
body: {
|
|
4170
|
+
email,
|
|
4171
|
+
password,
|
|
4172
|
+
name: email.split("@")[0],
|
|
4173
|
+
callbackURL,
|
|
4174
|
+
},
|
|
4175
|
+
headers: headersWithSignupAttribution(event.headers, getHeader(event, "cookie") ?? null),
|
|
4176
|
+
}));
|
|
4134
4177
|
setFirstRunOnboardingCookie(event);
|
|
4135
4178
|
return { ok: true };
|
|
4136
4179
|
}
|
|
@@ -4384,10 +4427,10 @@ function mountAuthFallbackRoutes(app) {
|
|
|
4384
4427
|
}
|
|
4385
4428
|
try {
|
|
4386
4429
|
const auth = await getBetterAuth();
|
|
4387
|
-
await auth.api.signUpEmail({
|
|
4430
|
+
await withSignupAttributionContext(getHeader(event, "cookie") ?? null, () => auth.api.signUpEmail({
|
|
4388
4431
|
body: { email, password, name: email.split("@")[0] },
|
|
4389
|
-
headers: event.headers,
|
|
4390
|
-
});
|
|
4432
|
+
headers: headersWithSignupAttribution(event.headers, getHeader(event, "cookie") ?? null),
|
|
4433
|
+
}));
|
|
4391
4434
|
setFirstRunOnboardingCookie(event);
|
|
4392
4435
|
return { ok: true };
|
|
4393
4436
|
}
|
|
@@ -26,13 +26,14 @@ import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, } from "../shared/password-po
|
|
|
26
26
|
import { formatRuntimeConfigReport, getRuntimeConfigReport, } from "../shared/runtime-config.js";
|
|
27
27
|
import { flushTracking, identify, track } from "../tracking/index.js";
|
|
28
28
|
import { getAppProductionUrl } from "./app-url.js";
|
|
29
|
-
import {
|
|
29
|
+
import { signupAttributionContextFromCookieHeader, signupAttributionContextFromHeaders, } from "./attribution.js";
|
|
30
30
|
import { resolveAuthCookieNamespace } from "./cookie-namespace.js";
|
|
31
31
|
import { getWorkspaceA2ADerivedSecret } from "./derived-secret.js";
|
|
32
32
|
import { renderMagicLinkEmail, renderResetPasswordEmail, renderVerifySignupEmail, } from "./email-templates.js";
|
|
33
33
|
import { getEmailReadiness, sendEmail } from "./email.js";
|
|
34
34
|
import { resolveGoogleSignInCredentials } from "./google-oauth-credentials.js";
|
|
35
35
|
import { readMagicLinkSignupAttribution } from "./magic-link-attribution.js";
|
|
36
|
+
import { getRequestContext, hasContinuationLocalRequestContext, } from "./request-context.js";
|
|
36
37
|
export { getAuthLoginMode, resolveAuthLoginMode, resolveAuthLoginModeFromReadiness, } from "./auth-login-mode.js";
|
|
37
38
|
async function flushSignupTracking() {
|
|
38
39
|
try {
|
|
@@ -1045,14 +1046,25 @@ async function createBetterAuthInstance(config) {
|
|
|
1045
1046
|
const cookieHeader = context?.headers?.get("cookie") ??
|
|
1046
1047
|
context?.request?.headers?.get("cookie") ??
|
|
1047
1048
|
null;
|
|
1049
|
+
const scopedSignupAttribution = hasContinuationLocalRequestContext()
|
|
1050
|
+
? getRequestContext()?.signupAttribution
|
|
1051
|
+
: undefined;
|
|
1052
|
+
const requestSignupAttribution = signupAttributionContextFromCookieHeader(cookieHeader);
|
|
1053
|
+
const headerSignupAttribution = signupAttributionContextFromHeaders(context?.headers) ??
|
|
1054
|
+
signupAttributionContextFromHeaders(context?.request?.headers);
|
|
1048
1055
|
const magicLinkAttribution = context?.request?.url?.includes("newUserCallbackURL")
|
|
1049
1056
|
? readMagicLinkSignupAttribution(context.request.url, getAuthSecret())
|
|
1050
1057
|
: undefined;
|
|
1051
|
-
attribution =
|
|
1052
|
-
|
|
1058
|
+
attribution =
|
|
1059
|
+
magicLinkAttribution?.attribution ??
|
|
1060
|
+
scopedSignupAttribution?.attribution ??
|
|
1061
|
+
headerSignupAttribution?.attribution ??
|
|
1062
|
+
requestSignupAttribution.attribution;
|
|
1053
1063
|
anonymousId =
|
|
1054
1064
|
magicLinkAttribution?.anonymousId ??
|
|
1055
|
-
|
|
1065
|
+
scopedSignupAttribution?.anonymousId ??
|
|
1066
|
+
headerSignupAttribution?.anonymousId ??
|
|
1067
|
+
requestSignupAttribution.anonymousId;
|
|
1056
1068
|
}
|
|
1057
1069
|
catch (err) {
|
|
1058
1070
|
console.error("[auth] failed to derive signup attribution", err);
|
|
@@ -19,10 +19,12 @@ import { getAppConfig } from "../app-config/index.js";
|
|
|
19
19
|
import { GOOGLE_AUTH_REQUIRED_MESSAGE, isGoogleSignInRequiredForEmail, } from "../org/auth-policy.js";
|
|
20
20
|
import { SIGN_IN_ENTRY_PATH } from "../shared/sign-in-journey.js";
|
|
21
21
|
import { getAppName } from "./app-name.js";
|
|
22
|
+
import { addSignupAttributionHeader, signupAttributionContextFromCookieHeader, } from "./attribution.js";
|
|
22
23
|
import { getSession, isExpectedAuthFailure, safeReturnPath } from "./auth.js";
|
|
23
24
|
import { getBetterAuth, getBetterAuthInternalAdapter, } from "./better-auth-instance.js";
|
|
24
25
|
import { createOAuthSession, getOrigin } from "./google-oauth.js";
|
|
25
26
|
import { consumeSsoState, createSsoState, CANONICAL_IDENTITY_SSO_HUB_URL, getIdentityHubUrl, identitySsoLoginButtonHtml, isCanonicalIdentitySsoClientRequest, isDesktopSsoUserAgent, isIdentitySsoExplicitlyEnabled, isIdentitySsoEnabled, isJtiReplayed, SSO_STATE_TTL_MS, } from "./identity-sso-store.js";
|
|
27
|
+
import { getRequestContext, hasContinuationLocalRequestContext, runWithRequestContext, } from "./request-context.js";
|
|
26
28
|
export { getIdentityHubUrl, identitySsoLoginButtonHtml, isIdentitySsoEnabled };
|
|
27
29
|
export const IDENTITY_SSO_PROVIDER_ID = "agent-native";
|
|
28
30
|
export const IDENTITY_SSO_SCOPE = "identity";
|
|
@@ -269,7 +271,7 @@ async function exchangeIdentityCode(hub, binding, input) {
|
|
|
269
271
|
return null;
|
|
270
272
|
}
|
|
271
273
|
}
|
|
272
|
-
async function jitLinkIdentity(identity) {
|
|
274
|
+
async function jitLinkIdentity(identity, signupHeaders) {
|
|
273
275
|
const adapter = await getBetterAuthInternalAdapter();
|
|
274
276
|
let existing = adapter
|
|
275
277
|
? await adapter
|
|
@@ -288,6 +290,7 @@ async function jitLinkIdentity(identity) {
|
|
|
288
290
|
password: createUnusableSsoCredential(),
|
|
289
291
|
name: identity.name || identity.email.split("@")[0] || "User",
|
|
290
292
|
},
|
|
293
|
+
...(signupHeaders ? { headers: signupHeaders } : {}),
|
|
291
294
|
});
|
|
292
295
|
}
|
|
293
296
|
catch (error) {
|
|
@@ -463,7 +466,16 @@ export async function handleIdentitySso(event, subpath) {
|
|
|
463
466
|
return errorPage(GOOGLE_AUTH_REQUIRED_MESSAGE, loginPath);
|
|
464
467
|
}
|
|
465
468
|
try {
|
|
466
|
-
|
|
469
|
+
const signupCookieHeader = getHeader(event, "cookie") ?? null;
|
|
470
|
+
const signupAttribution = signupAttributionContextFromCookieHeader(signupCookieHeader);
|
|
471
|
+
const signupHeaders = addSignupAttributionHeader(event.headers, signupAttribution);
|
|
472
|
+
const linkIdentity = () => jitLinkIdentity(identity, signupHeaders);
|
|
473
|
+
await (hasContinuationLocalRequestContext()
|
|
474
|
+
? runWithRequestContext({
|
|
475
|
+
...(getRequestContext() ?? {}),
|
|
476
|
+
signupAttribution,
|
|
477
|
+
}, linkIdentity)
|
|
478
|
+
: linkIdentity());
|
|
467
479
|
}
|
|
468
480
|
catch {
|
|
469
481
|
return errorPage("Could not finish linking your account. Please try again.", loginPath);
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* process.env so existing `AGENT_USER_EMAIL=x pnpm action foo` invocations
|
|
16
16
|
* continue to work.
|
|
17
17
|
*/
|
|
18
|
+
import type { SignupAttributionContext } from "./attribution.js";
|
|
18
19
|
/**
|
|
19
20
|
* Per-request agent-run state. Lives on `RequestContext.run` so the
|
|
20
21
|
* agent-chat plugin can populate fields as the run progresses (owner,
|
|
@@ -109,6 +110,11 @@ export interface RequestContext {
|
|
|
109
110
|
* replay; never used for authorization.
|
|
110
111
|
*/
|
|
111
112
|
browserSessionId?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Browser attribution captured before a Better Auth signup crosses into its
|
|
115
|
+
* async user-create hook. Analytics-only; never used for authorization.
|
|
116
|
+
*/
|
|
117
|
+
signupAttribution?: SignupAttributionContext;
|
|
112
118
|
/** Canonical client surface for analytics attribution. */
|
|
113
119
|
clientPlatform?: import("../shared/analytics-platform.js").AnalyticsClientPlatform;
|
|
114
120
|
/**
|
|
@@ -188,6 +194,8 @@ type RequestContextObserver = (ctx: RequestContext) => void;
|
|
|
188
194
|
* overlapping async requests are only isolated by native AsyncLocalStorage.
|
|
189
195
|
*/
|
|
190
196
|
export declare function assertRequestActionSurfaceIsolation(): void;
|
|
197
|
+
/** Whether request context values are isolated across overlapping promises. */
|
|
198
|
+
export declare function hasContinuationLocalRequestContext(): boolean;
|
|
191
199
|
/**
|
|
192
200
|
* Register a callback fired every time `runWithRequestContext` enters a new
|
|
193
201
|
* scope. The hook runs INSIDE the AsyncLocalStorage scope, so observability
|
|
@@ -80,6 +80,10 @@ export function assertRequestActionSurfaceIsolation() {
|
|
|
80
80
|
throw new Error("Request-scoped action surfaces require continuation-local request context storage; " +
|
|
81
81
|
"this runtime only provides the non-isolated fallback.");
|
|
82
82
|
}
|
|
83
|
+
/** Whether request context values are isolated across overlapping promises. */
|
|
84
|
+
export function hasContinuationLocalRequestContext() {
|
|
85
|
+
return globalRef[CONTINUATION_LOCAL_KEY] === true;
|
|
86
|
+
}
|
|
83
87
|
/**
|
|
84
88
|
* Register a callback fired every time `runWithRequestContext` enters a new
|
|
85
89
|
* scope. The hook runs INSIDE the AsyncLocalStorage scope, so observability
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -65,7 +65,9 @@ In a workspace, every app inherits the root `DATABASE_URL` by default. Set
|
|
|
65
65
|
Set a Nitro preset for the target you choose. The app code and database
|
|
66
66
|
contract stay the same.
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
<!-- i18n-copy-ignore: renderer-only Diagram attributes keep this shared UI block in clean mode. -->
|
|
69
|
+
|
|
70
|
+
<Diagram id="doc-block-deployment-targets" title="Supported deployment targets" summary="Agent-Native apps can deploy to Node.js, Docker, Vercel, Netlify, Cloudflare Pages, Cloudflare Workers, AWS Lambda, Deno Deploy, Azure Static Web Apps, Koyeb, and Render." frame="hide" renderMode="design">
|
|
69
71
|
|
|
70
72
|
```html
|
|
71
73
|
<!-- i18n-copy-ignore: deployment target logo markup is visual-only; labels are unchanged. -->
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.0.0-beta-
|
|
3
|
+
"version": "0.0.0-beta-20260820222620",
|
|
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": {
|
|
@@ -427,7 +427,7 @@
|
|
|
427
427
|
"y-protocols": "^1.0.7",
|
|
428
428
|
"yjs": "^13.6.32",
|
|
429
429
|
"zod": "^4.3.6",
|
|
430
|
-
"@agent-native/recap-cli": "0.
|
|
430
|
+
"@agent-native/recap-cli": "0.5.7",
|
|
431
431
|
"@agent-native/toolkit": "^0.16.9"
|
|
432
432
|
},
|
|
433
433
|
"devDependencies": {
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|