@agent-native/core 0.163.2 → 0.163.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/corpus/templates/clips/actions/add-comment.ts +11 -2
  2. package/corpus/templates/clips/actions/delete-comment.ts +14 -1
  3. package/corpus/templates/clips/actions/get-recording-player-data.ts +5 -1
  4. package/corpus/templates/clips/actions/react-to-comment.ts +4 -1
  5. package/corpus/templates/clips/actions/react-to-recording.ts +4 -1
  6. package/corpus/templates/clips/actions/reply-to-comment.ts +15 -2
  7. package/corpus/templates/clips/actions/resolve-comment.ts +29 -3
  8. package/corpus/templates/clips/actions/update-comment.ts +13 -1
  9. package/corpus/templates/clips/app/components/player/player-controls.tsx +43 -1
  10. package/corpus/templates/clips/app/components/player/timestamped-comment-button.tsx +12 -3
  11. package/corpus/templates/clips/app/components/player/video-player.tsx +43 -0
  12. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +81 -18
  13. package/corpus/templates/clips/app/routes/share.$shareId.tsx +164 -53
  14. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +5 -1
  15. package/dist/client/EnvironmentBadge.d.ts +5 -0
  16. package/dist/client/EnvironmentBadge.js +125 -13
  17. package/dist/collab/awareness.d.ts +2 -2
  18. package/dist/collab/routes.d.ts +1 -1
  19. package/dist/collab/struct-routes.d.ts +1 -1
  20. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  21. package/dist/notifications/routes.d.ts +3 -3
  22. package/dist/observability/routes.d.ts +1 -1
  23. package/dist/progress/routes.d.ts +1 -1
  24. package/dist/resources/handlers.d.ts +1 -1
  25. package/dist/secrets/routes.d.ts +9 -9
  26. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  27. package/dist/server/realtime-token.d.ts +1 -1
  28. package/dist/server/transcribe-voice.d.ts +1 -1
  29. package/dist/vite/client.js +35 -37
  30. package/package.json +1 -1
@@ -34,6 +34,7 @@ import {
34
34
  type FormEvent,
35
35
  type ReactNode,
36
36
  } from "react";
37
+ import { createPortal } from "react-dom";
37
38
  import {
38
39
  type HeadersArgs,
39
40
  type LoaderFunctionArgs,
@@ -59,7 +60,10 @@ import { RequestAccessDialog } from "@/components/player/request-access-dialog";
59
60
  import { ShareRecordingPopover } from "@/components/player/share-dialog";
60
61
  import { SignInPromptDialog } from "@/components/player/sign-in-prompt-dialog";
61
62
  import { SignedOutShareActions } from "@/components/player/signed-out-share-actions";
62
- import { TimestampedCommentButton } from "@/components/player/timestamped-comment-button";
63
+ import {
64
+ TimestampedCommentBar,
65
+ TimestampedCommentButton,
66
+ } from "@/components/player/timestamped-comment-button";
63
67
  import { TranscriptPanel } from "@/components/player/transcript-panel";
64
68
  import {
65
69
  VideoPlayer,
@@ -446,6 +450,10 @@ export default function ShareRoute() {
446
450
  });
447
451
  const [pwError, setPwError] = useState<string | null>(null);
448
452
  const [currentMs, setCurrentMs] = useState(0);
453
+ const [commentOpen, setCommentOpen] = useState(false);
454
+ const [commentAtMs, setCommentAtMs] = useState(0);
455
+ const [commentDraft, setCommentDraft] = useState("");
456
+ const [isPlayerFullscreen, setIsPlayerFullscreen] = useState(false);
449
457
  const { session, isLoading: sessionLoading } = useSession();
450
458
  const requestAccess = useActionMutation<
451
459
  {
@@ -664,7 +672,10 @@ export default function ShareRoute() {
664
672
  viewerRole === "owner" ||
665
673
  viewerRole === "admin" ||
666
674
  viewerRole === "editor";
667
- const viewerCanComment = Boolean(dataQ.data?.data?.viewer?.canComment);
675
+ // Any signed-in viewer with access to the recording may comment or react —
676
+ // an anonymous viewer sees the same controls but triggers the sign-in
677
+ // prompt instead (see `requireSignIn` below).
678
+ const viewerCanComment = Boolean(session) && viewerRole != null;
668
679
  const viewerIsOwner = Boolean(dataQ.data?.data?.viewer?.isOwner);
669
680
  const canReshareLink =
670
681
  (viewerRole === "viewer" || viewerRole === "commenter") &&
@@ -1214,7 +1225,7 @@ export default function ShareRoute() {
1214
1225
  </header>
1215
1226
 
1216
1227
  <div className="flex flex-col gap-4 overflow-hidden p-0 sm:p-4 lg:min-h-0 lg:flex-1">
1217
- <div className="aspect-video w-full lg:min-h-0 lg:flex-1 lg:aspect-auto">
1228
+ <div className="relative aspect-video w-full lg:min-h-0 lg:flex-1 lg:aspect-auto">
1218
1229
  <VideoPlayer
1219
1230
  ref={playerRef}
1220
1231
  onVideoElementChange={setTrackedVideoEl}
@@ -1239,8 +1250,88 @@ export default function ShareRoute() {
1239
1250
  onCtaClick={() => tracking.reportCtaClick()}
1240
1251
  onTimeUpdate={(ms) => setCurrentMs(ms)}
1241
1252
  onCommentClick={() => setPanel("comments")}
1253
+ onFullscreenChange={setIsPlayerFullscreen}
1254
+ enableComments={recording.enableComments}
1255
+ onAddComment={() => {
1256
+ if (!session) {
1257
+ requireSignIn("comment");
1258
+ return;
1259
+ }
1260
+ const liveCt = isLoomEmbedBacked
1261
+ ? null
1262
+ : playerRef.current?.video?.currentTime;
1263
+ const liveMs =
1264
+ typeof liveCt === "number" &&
1265
+ Number.isFinite(liveCt) &&
1266
+ liveCt >= 0 &&
1267
+ liveCt < 1e7
1268
+ ? Math.floor(liveCt * 1000)
1269
+ : currentMs;
1270
+ setCommentAtMs(liveMs);
1271
+ setCommentOpen(true);
1272
+ }}
1273
+ enableReactions={recording.enableReactions}
1274
+ onReact={(emoji) => {
1275
+ if (!session) {
1276
+ requireSignIn("react");
1277
+ return;
1278
+ }
1279
+ tracking.reportReaction(emoji);
1280
+ const liveCt = isLoomEmbedBacked
1281
+ ? null
1282
+ : playerRef.current?.video?.currentTime;
1283
+ const liveMs =
1284
+ typeof liveCt === "number" &&
1285
+ Number.isFinite(liveCt) &&
1286
+ liveCt >= 0 &&
1287
+ liveCt < 1e7
1288
+ ? Math.floor(liveCt * 1000)
1289
+ : currentMs;
1290
+ fetch(
1291
+ agentNativePath("/_agent-native/actions/react-to-recording"),
1292
+ {
1293
+ method: "POST",
1294
+ headers: { "Content-Type": "application/json" },
1295
+ body: JSON.stringify({
1296
+ recordingId: recording.id,
1297
+ emoji,
1298
+ videoTimestampMs: liveMs,
1299
+ }),
1300
+ },
1301
+ )
1302
+ .then((res) => {
1303
+ if (!res.ok) throw new Error(`react failed: ${res.status}`);
1304
+ return dataQ.refetch();
1305
+ })
1306
+ .catch((err) => console.warn("[clips] react failed", err));
1307
+ }}
1242
1308
  className="h-full w-full rounded-none sm:rounded-xl"
1243
1309
  />
1310
+ {commentOpen && viewerCanComment
1311
+ ? (() => {
1312
+ const composer = (
1313
+ <TimestampedCommentBar
1314
+ recordingId={recording.id}
1315
+ atMs={commentAtMs}
1316
+ draft={commentDraft}
1317
+ onDraftChange={setCommentDraft}
1318
+ onClose={() => setCommentOpen(false)}
1319
+ onAdded={() => {
1320
+ setPanel("comments");
1321
+ void dataQ.refetch();
1322
+ }}
1323
+ />
1324
+ );
1325
+ // The Fullscreen API only paints the player's own element,
1326
+ // so portal the composer there instead of exiting
1327
+ // fullscreen when it's open.
1328
+ const fullscreenContainer =
1329
+ isPlayerFullscreen && playerRef.current?.container;
1330
+ return fullscreenContainer
1331
+ ? createPortal(composer, fullscreenContainer)
1332
+ : composer;
1333
+ })()
1334
+ : null}
1244
1335
  </div>
1245
1336
 
1246
1337
  <div className="flex shrink-0 flex-col gap-3 px-4 pb-4 sm:flex-row sm:items-start sm:px-0 sm:pb-0">
@@ -1252,56 +1343,76 @@ export default function ShareRoute() {
1252
1343
  ) : null}
1253
1344
  </div>
1254
1345
  <div className="flex max-w-full flex-col items-stretch gap-2 sm:items-end">
1255
- <TimestampedCommentButton
1256
- enableComments={recording.enableComments}
1257
- canComment={!session || viewerCanComment}
1258
- className="shrink-0"
1259
- onOpen={() => {
1260
- if (!session) {
1261
- requireSignIn("comment");
1262
- return;
1263
- }
1264
- if (viewerCanComment) setPanel("comments");
1265
- }}
1266
- />
1267
- {recording.enableReactions ? (
1268
- <ReactionsTray
1269
- disabled={!viewerCanComment}
1270
- onReact={(emoji) => {
1271
- if (!session) {
1272
- requireSignIn("react");
1273
- return;
1274
- }
1275
- tracking.reportReaction(emoji);
1276
- const liveCt = isLoomEmbedBacked
1277
- ? null
1278
- : playerRef.current?.video?.currentTime;
1279
- const liveMs =
1280
- typeof liveCt === "number" &&
1281
- Number.isFinite(liveCt) &&
1282
- liveCt >= 0 &&
1283
- liveCt < 1e7
1284
- ? Math.floor(liveCt * 1000)
1285
- : currentMs;
1286
- fetch(
1287
- agentNativePath(
1288
- "/_agent-native/actions/react-to-recording",
1289
- ),
1290
- {
1291
- method: "POST",
1292
- headers: { "Content-Type": "application/json" },
1293
- body: JSON.stringify({
1294
- recordingId: recording.id,
1295
- emoji,
1296
- videoTimestampMs: liveMs,
1297
- }),
1298
- },
1299
- )
1300
- .then(() => dataQ.refetch())
1301
- .catch(() => {});
1302
- }}
1303
- />
1304
- ) : null}
1346
+ <div className="flex flex-wrap items-center gap-2 sm:justify-end">
1347
+ {recording.enableComments ? (
1348
+ <TimestampedCommentButton
1349
+ enableComments={recording.enableComments}
1350
+ canComment
1351
+ className="shrink-0"
1352
+ onOpen={() => {
1353
+ if (!session) {
1354
+ requireSignIn("comment");
1355
+ return;
1356
+ }
1357
+ const liveCt = isLoomEmbedBacked
1358
+ ? null
1359
+ : playerRef.current?.video?.currentTime;
1360
+ const liveMs =
1361
+ typeof liveCt === "number" &&
1362
+ Number.isFinite(liveCt) &&
1363
+ liveCt >= 0 &&
1364
+ liveCt < 1e7
1365
+ ? Math.floor(liveCt * 1000)
1366
+ : currentMs;
1367
+ setCommentAtMs(liveMs);
1368
+ setCommentOpen(true);
1369
+ }}
1370
+ />
1371
+ ) : null}
1372
+ {recording.enableReactions ? (
1373
+ <ReactionsTray
1374
+ onReact={(emoji) => {
1375
+ if (!session) {
1376
+ requireSignIn("react");
1377
+ return;
1378
+ }
1379
+ tracking.reportReaction(emoji);
1380
+ const liveCt = isLoomEmbedBacked
1381
+ ? null
1382
+ : playerRef.current?.video?.currentTime;
1383
+ const liveMs =
1384
+ typeof liveCt === "number" &&
1385
+ Number.isFinite(liveCt) &&
1386
+ liveCt >= 0 &&
1387
+ liveCt < 1e7
1388
+ ? Math.floor(liveCt * 1000)
1389
+ : currentMs;
1390
+ fetch(
1391
+ agentNativePath(
1392
+ "/_agent-native/actions/react-to-recording",
1393
+ ),
1394
+ {
1395
+ method: "POST",
1396
+ headers: { "Content-Type": "application/json" },
1397
+ body: JSON.stringify({
1398
+ recordingId: recording.id,
1399
+ emoji,
1400
+ videoTimestampMs: liveMs,
1401
+ }),
1402
+ },
1403
+ )
1404
+ .then((res) => {
1405
+ if (!res.ok)
1406
+ throw new Error(`react failed: ${res.status}`);
1407
+ return dataQ.refetch();
1408
+ })
1409
+ .catch((err) =>
1410
+ console.warn("[clips] react failed", err),
1411
+ );
1412
+ }}
1413
+ />
1414
+ ) : null}
1415
+ </div>
1305
1416
  {viewerCanEdit && canDownloadRecording ? (
1306
1417
  <Button
1307
1418
  variant="outline"
@@ -268,9 +268,13 @@ export default defineEventHandler(async (event) => {
268
268
  return { error: "Not found" };
269
269
  }
270
270
 
271
+ // Any signed-in viewer with access to the recording may comment or react —
272
+ // this covers an explicit share at any role (not just "commenter"), org
273
+ // membership, and a public link, which grants a viewer role that
274
+ // `resolveAccess` may not surface without an explicit share row.
271
275
  const viewerCanComment = Boolean(
272
276
  session?.email &&
273
- (rec.visibility === "public" || viewerIsOwner || viewerIsOrgMember),
277
+ (rec.visibility === "public" || viewerAccess || viewerIsOrgMember),
274
278
  );
275
279
 
276
280
  // Expiry check
@@ -1,4 +1,7 @@
1
1
  import type { AgentNativeDeploymentEnvironment, AgentNativeConfig } from "../config.js";
2
+ export declare const BETA_OPT_OUT_QUERY_PARAM = "agentNativeBetaOptOut";
3
+ export declare const BETA_OPT_OUT_STORAGE_KEY = "agent-native:beta-opt-out-until";
4
+ export declare const BETA_OPT_OUT_DURATION_MS: number;
2
5
  export interface EnvironmentBadgeTargets {
3
6
  betaHost: string;
4
7
  productionHost: string;
@@ -7,6 +10,8 @@ export declare function isBuilderIoEmployee(email: string | null | undefined): b
7
10
  export declare function resolveEnvironmentTargets(hostname: string | undefined): EnvironmentBadgeTargets | null;
8
11
  export declare function resolveEnvironmentChannel(config: AgentNativeConfig, hostname: string | undefined): Extract<AgentNativeDeploymentEnvironment, "beta" | "production"> | null;
9
12
  export declare function buildEnvironmentUrl(sourceHref: string, targetHost: string): string | null;
13
+ export declare function isBetaOptOutActive(value: string | number | null | undefined, now?: number): boolean;
14
+ export declare function buildEnvironmentOptOutUrl(sourceHref: string, targetHost: string, now?: number): string | null;
10
15
  /**
11
16
  * Small internal-only lane switcher for first-party hosted Agent-Native apps.
12
17
  * It is mounted inside the authenticated AppProviders shell so public pages,
@@ -2,9 +2,32 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Button } from "@agent-native/toolkit/ui/button";
3
3
  import { Popover, PopoverContent, PopoverTrigger, } from "@agent-native/toolkit/ui/popover";
4
4
  import { IconExternalLink, IconGitBranch } from "@tabler/icons-react";
5
- import { useMemo } from "react";
5
+ import { useEffect, useMemo, useRef } from "react";
6
+ import { trackEvent } from "./analytics.js";
6
7
  import { injectedAgentNativeConfig } from "./app-config.js";
7
8
  import { useSession } from "./use-session.js";
9
+ export const BETA_OPT_OUT_QUERY_PARAM = "agentNativeBetaOptOut";
10
+ export const BETA_OPT_OUT_STORAGE_KEY = "agent-native:beta-opt-out-until";
11
+ export const BETA_OPT_OUT_DURATION_MS = 24 * 60 * 60 * 1000;
12
+ const ENVIRONMENT_BETA_HOSTS = {
13
+ "agent-workspace.builder.io": "beta.agent-workspace.builder.io",
14
+ "analytics.agent-native.com": "beta.analytics.agent-native.com",
15
+ "assets.agent-native.com": "beta.assets.agent-native.com",
16
+ "brain.agent-native.com": "beta.brain.agent-native.com",
17
+ "calendar.agent-native.com": "beta.calendar.agent-native.com",
18
+ "chat.agent-native.com": "beta.chat.agent-native.com",
19
+ "clips.agent-native.com": "beta.clips.agent-native.com",
20
+ "content.agent-native.com": "beta.content.agent-native.com",
21
+ "crm.agent-native.com": "beta.crm.agent-native.com",
22
+ "design.agent-native.com": "beta.design.agent-native.com",
23
+ "dispatch.agent-native.com": "beta.dispatch.agent-native.com",
24
+ "factory.agent-native.com": "beta.factory.agent-native.com",
25
+ "forms.agent-native.com": "beta.forms.agent-native.com",
26
+ "macros.agent-native.com": "beta.macros.agent-native.com",
27
+ "mail.agent-native.com": "beta.mail.agent-native.com",
28
+ "plan.agent-native.com": "beta.plan.agent-native.com",
29
+ "slides.agent-native.com": "beta.slides.agent-native.com",
30
+ };
8
31
  export function isBuilderIoEmployee(email) {
9
32
  return email?.trim().toLowerCase().endsWith("@builder.io") ?? false;
10
33
  }
@@ -13,12 +36,11 @@ export function resolveEnvironmentTargets(hostname) {
13
36
  if (!normalized)
14
37
  return null;
15
38
  const productionHost = normalized.replace(/^beta\./, "");
16
- const isFirstPartyHost = productionHost.endsWith(".agent-native.com") ||
17
- productionHost === "agent-workspace.builder.io";
18
- if (!isFirstPartyHost)
39
+ const betaHost = ENVIRONMENT_BETA_HOSTS[productionHost];
40
+ if (!betaHost)
19
41
  return null;
20
42
  return {
21
- betaHost: `beta.${productionHost}`,
43
+ betaHost,
22
44
  productionHost,
23
45
  };
24
46
  }
@@ -47,6 +69,68 @@ export function buildEnvironmentUrl(sourceHref, targetHost) {
47
69
  return null;
48
70
  }
49
71
  }
72
+ export function isBetaOptOutActive(value, now = Date.now()) {
73
+ const expiry = typeof value === "number" ? value : Number(value);
74
+ return Number.isFinite(expiry) && expiry > now;
75
+ }
76
+ export function buildEnvironmentOptOutUrl(sourceHref, targetHost, now = Date.now()) {
77
+ const targetHref = buildEnvironmentUrl(sourceHref, targetHost);
78
+ if (!targetHref)
79
+ return null;
80
+ try {
81
+ const target = new URL(targetHref);
82
+ target.searchParams.set(BETA_OPT_OUT_QUERY_PARAM, String(now + BETA_OPT_OUT_DURATION_MS));
83
+ return target.toString();
84
+ }
85
+ catch {
86
+ // coercion-ok: buildEnvironmentUrl already validated the URL.
87
+ return null;
88
+ }
89
+ }
90
+ function readBetaOptOutUntil(now = Date.now()) {
91
+ if (typeof window === "undefined")
92
+ return null;
93
+ try {
94
+ const value = window.localStorage.getItem(BETA_OPT_OUT_STORAGE_KEY);
95
+ if (isBetaOptOutActive(value, now))
96
+ return Number(value);
97
+ if (value !== null) {
98
+ window.localStorage.removeItem(BETA_OPT_OUT_STORAGE_KEY);
99
+ }
100
+ }
101
+ catch {
102
+ // coercion-ok: browser storage access is optional; the current URL remains authoritative.
103
+ // Private browsing can deny storage access. The switcher still works;
104
+ // the current navigation remains the explicit source of truth.
105
+ }
106
+ return null;
107
+ }
108
+ function consumeBetaOptOutQueryParam(sourceHref, now = Date.now()) {
109
+ let target;
110
+ try {
111
+ target = new URL(sourceHref);
112
+ }
113
+ catch {
114
+ // coercion-ok: the browser supplied an invalid location.
115
+ return false;
116
+ }
117
+ const rawExpiry = target.searchParams.get(BETA_OPT_OUT_QUERY_PARAM);
118
+ if (rawExpiry === null)
119
+ return false;
120
+ const active = isBetaOptOutActive(rawExpiry, now);
121
+ target.searchParams.delete(BETA_OPT_OUT_QUERY_PARAM);
122
+ try {
123
+ if (active) {
124
+ window.localStorage.setItem(BETA_OPT_OUT_STORAGE_KEY, String(Number(rawExpiry)));
125
+ }
126
+ window.history.replaceState(null, "", target.toString());
127
+ }
128
+ catch {
129
+ // coercion-ok: browser history/storage access is optional; the page must still load.
130
+ // A browser that denies storage/history access must not block the page.
131
+ }
132
+ return active;
133
+ }
50
134
  function EnvironmentLink({ label, href }) {
51
135
  return (_jsx(Button, { asChild: true, className: "w-full justify-start px-2", size: "sm", variant: "ghost", children: _jsxs("a", { href: href, children: [_jsx(IconExternalLink, { "aria-hidden": "true" }), label] }) }));
52
136
  }
@@ -58,19 +142,47 @@ function EnvironmentLink({ label, href }) {
58
142
  export function EnvironmentBadge() {
59
143
  const { session, status } = useSession();
60
144
  const config = useMemo(injectedAgentNativeConfig, []);
61
- const environment = resolveEnvironmentChannel(config, typeof window === "undefined" ? undefined : window.location.hostname);
62
- const targets = resolveEnvironmentTargets(typeof window === "undefined" ? undefined : window.location.hostname);
63
- if (typeof window === "undefined" ||
64
- window.parent !== window ||
65
- status !== "authenticated" ||
66
- !isBuilderIoEmployee(session?.email) ||
145
+ const didAutoRedirect = useRef(false);
146
+ const hostname = typeof window === "undefined" ? undefined : window.location.hostname;
147
+ const environment = resolveEnvironmentChannel(config, hostname);
148
+ const targets = resolveEnvironmentTargets(hostname);
149
+ const isEligible = typeof window !== "undefined" &&
150
+ window.parent === window &&
151
+ status === "authenticated" &&
152
+ isBuilderIoEmployee(session?.email) &&
153
+ !!environment &&
154
+ !!targets;
155
+ useEffect(() => {
156
+ if (!isEligible ||
157
+ environment !== "production" ||
158
+ !targets ||
159
+ didAutoRedirect.current) {
160
+ return;
161
+ }
162
+ didAutoRedirect.current = true;
163
+ if (readBetaOptOutUntil() !== null)
164
+ return;
165
+ if (consumeBetaOptOutQueryParam(window.location.href))
166
+ return;
167
+ const betaHref = buildEnvironmentUrl(window.location.href, targets.betaHost);
168
+ if (!betaHref || typeof window.location.replace !== "function")
169
+ return;
170
+ trackEvent("environment switched", {
171
+ from_environment: "production",
172
+ to_environment: "beta",
173
+ trigger: "automatic_redirect",
174
+ });
175
+ window.location.replace(betaHref);
176
+ }, [environment, isEligible, session?.email, status, targets?.betaHost]);
177
+ if (!isEligible ||
67
178
  !environment ||
68
- !targets) {
179
+ !targets ||
180
+ typeof window === "undefined") {
69
181
  return null;
70
182
  }
71
183
  const currentHref = window.location.href;
72
184
  const betaHref = buildEnvironmentUrl(currentHref, targets.betaHost);
73
- const productionHref = buildEnvironmentUrl(currentHref, targets.productionHost);
185
+ const productionHref = buildEnvironmentOptOutUrl(currentHref, targets.productionHost);
74
186
  if (!betaHref || !productionHref)
75
187
  return null;
76
188
  const label = environment === "beta" ? "beta" : "prod";
@@ -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;
65
66
  states: {
66
67
  clientId: number;
67
68
  state: string;
68
69
  }[];
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;
80
81
  users: {
81
82
  clientId: number;
82
83
  lastSeen: number;
83
84
  }[];
84
- error?: undefined;
85
85
  }>>;
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- ok?: undefined;
30
29
  error: string;
30
+ ok?: undefined;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- error: string;
17
16
  ok?: undefined;
17
+ error: string;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -17,11 +17,11 @@ declare const _default: import("../../action.js").ActionDefinition<{
17
17
  id?: undefined;
18
18
  provider?: undefined;
19
19
  } | {
20
+ error?: undefined;
20
21
  configured?: undefined;
21
22
  connectPath?: undefined;
22
23
  url: string;
23
24
  id: string;
24
25
  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;
14
15
  count: number;
15
16
  updated?: undefined;
16
- error?: undefined;
17
17
  ok?: undefined;
18
18
  } | {
19
+ error?: undefined;
19
20
  count?: undefined;
20
21
  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;
29
30
  count?: undefined;
30
31
  updated?: undefined;
31
- error?: undefined;
32
32
  ok: boolean;
33
33
  }>>;
@@ -62,6 +62,6 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
62
62
  summary?: undefined;
63
63
  spans?: undefined;
64
64
  id?: undefined;
65
- error?: undefined;
66
65
  ok: boolean;
66
+ error?: undefined;
67
67
  }>>;
@@ -15,6 +15,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
15
15
  error: string;
16
16
  ok?: undefined;
17
17
  } | {
18
- ok: boolean;
19
18
  error?: undefined;
19
+ ok: boolean;
20
20
  }>>;
@@ -48,8 +48,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
48
48
  }>;
49
49
  /** DELETE /_agent-native/resources/:id — delete a resource */
50
50
  export declare function handleDeleteResource(event: any): Promise<{
51
- error: string;
52
51
  ok?: undefined;
52
+ error: string;
53
53
  } | {
54
54
  error?: undefined;
55
55
  ok: boolean;
@@ -34,37 +34,37 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
34
34
  /** POST /_agent-native/secrets/:key — write a secret. */
35
35
  export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
36
36
  error: string;
37
- status?: undefined;
38
37
  ok?: undefined;
38
+ status?: undefined;
39
39
  } | {
40
+ error?: undefined;
40
41
  ok: boolean;
41
42
  status: string;
42
- error?: undefined;
43
43
  } | {
44
+ ok?: undefined;
44
45
  error: string;
45
46
  removed?: undefined;
46
- ok?: undefined;
47
47
  } | {
48
+ error?: undefined;
48
49
  ok: boolean;
49
50
  removed: boolean;
50
- error?: undefined;
51
51
  }>>;
52
52
  /**
53
53
  * POST /_agent-native/secrets/:key/test — validate an optional candidate value
54
54
  * or the current stored value without changing anything.
55
55
  */
56
56
  export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
57
+ ok?: undefined;
57
58
  error: string;
58
59
  note?: undefined;
59
- ok?: undefined;
60
60
  } | {
61
+ error?: undefined;
61
62
  ok: boolean;
62
63
  note?: undefined;
63
- error?: undefined;
64
64
  } | {
65
+ error?: undefined;
65
66
  ok: boolean;
66
67
  note: string;
67
- error?: undefined;
68
68
  } | {
69
69
  note?: undefined;
70
70
  ok: boolean;
@@ -95,11 +95,11 @@ export interface AdHocSecretPayload {
95
95
  export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
96
96
  error: string;
97
97
  } | {
98
+ error?: undefined;
98
99
  ok: boolean;
99
100
  key: string;
100
- error?: undefined;
101
101
  } | {
102
+ error?: undefined;
102
103
  ok: boolean;
103
104
  removed: boolean;
104
- error?: undefined;
105
105
  }>>;
@@ -27,10 +27,10 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
27
27
  export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
28
28
  error: any;
29
29
  } | {
30
+ error?: undefined;
30
31
  ok: boolean;
31
32
  key: string;
32
33
  baseUrlKey?: string;
33
34
  scope: AgentEngineApiKeyScope;
34
- error?: undefined;
35
35
  }>>;
36
36
  export {};