@agent-native/core 0.84.18 → 0.84.20

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 (55) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +13 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/agent/run-store.ts +180 -13
  5. package/corpus/core/src/client/AssistantChat.tsx +49 -0
  6. package/corpus/core/src/client/active-run-state.ts +30 -0
  7. package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +41 -3
  8. package/corpus/core/src/client/extensions/ExtensionViewer.tsx +133 -0
  9. package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +2 -2
  10. package/corpus/core/src/extensions/html-shell.ts +17 -3
  11. package/corpus/core/src/extensions/theme.ts +39 -0
  12. package/corpus/templates/analytics/actions/provider-api-request.ts +8 -1
  13. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +2 -1
  14. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +91 -33
  15. package/corpus/templates/clips/changelog/2026-07-01-chrome-recording-uploads-now-serialize-chunks-to-avoid-resum.md +6 -0
  16. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  17. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +30 -23
  18. package/dist/agent/run-store.d.ts +19 -6
  19. package/dist/agent/run-store.d.ts.map +1 -1
  20. package/dist/agent/run-store.js +163 -13
  21. package/dist/agent/run-store.js.map +1 -1
  22. package/dist/client/AssistantChat.d.ts +2 -0
  23. package/dist/client/AssistantChat.d.ts.map +1 -1
  24. package/dist/client/AssistantChat.js +36 -2
  25. package/dist/client/AssistantChat.js.map +1 -1
  26. package/dist/client/active-run-state.d.ts +3 -0
  27. package/dist/client/active-run-state.d.ts.map +1 -1
  28. package/dist/client/active-run-state.js +24 -0
  29. package/dist/client/active-run-state.js.map +1 -1
  30. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  31. package/dist/client/extensions/EmbeddedExtension.js +32 -3
  32. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  33. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  34. package/dist/client/extensions/ExtensionViewer.js +59 -2
  35. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  36. package/dist/client/extensions/ExtensionsSidebarSection.js +2 -2
  37. package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
  38. package/dist/collab/awareness.d.ts +2 -2
  39. package/dist/collab/awareness.d.ts.map +1 -1
  40. package/dist/collab/routes.d.ts +2 -2
  41. package/dist/extensions/html-shell.d.ts.map +1 -1
  42. package/dist/extensions/html-shell.js +17 -3
  43. package/dist/extensions/html-shell.js.map +1 -1
  44. package/dist/extensions/theme.d.ts +9 -0
  45. package/dist/extensions/theme.d.ts.map +1 -1
  46. package/dist/extensions/theme.js +38 -0
  47. package/dist/extensions/theme.js.map +1 -1
  48. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  49. package/dist/notifications/routes.d.ts +3 -3
  50. package/dist/observability/routes.d.ts +6 -6
  51. package/dist/progress/routes.d.ts +1 -1
  52. package/dist/resources/handlers.d.ts +3 -3
  53. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  54. package/dist/server/transcribe-voice.d.ts +1 -1
  55. package/package.json +1 -1
@@ -2,6 +2,7 @@ import {
2
2
  IconArrowLeft,
3
3
  IconArrowBackUp,
4
4
  IconChevronRight,
5
+ IconCode,
5
6
  IconDotsVertical,
6
7
  IconHistory,
7
8
  IconLoader2,
@@ -20,6 +21,7 @@ import { getThemeVars } from "../../extensions/theme.js";
20
21
  import { sendToAgentChat } from "../agent-chat.js";
21
22
  import { AgentToggleButton } from "../AgentPanel.js";
22
23
  import { agentNativePath, appPath } from "../api-path.js";
24
+ import { Dialog, DialogContent, DialogTitle } from "../components/ui/dialog.js";
23
25
  import {
24
26
  Popover,
25
27
  PopoverContent,
@@ -324,6 +326,131 @@ function applyCanonicalLink(path: string): () => void {
324
326
  };
325
327
  }
326
328
 
329
+ function SourceCodeDialog({
330
+ extension,
331
+ onSaved,
332
+ }: {
333
+ extension: Extension;
334
+ onSaved?: () => void;
335
+ }) {
336
+ const queryClient = useQueryClient();
337
+ const [open, setOpen] = useState(false);
338
+ const [code, setCode] = useState(extension.content ?? "");
339
+ const [saving, setSaving] = useState(false);
340
+ const [error, setError] = useState<string | null>(null);
341
+
342
+ // Sync in when the dialog opens, or when the viewed extension changes
343
+ // while the dialog stays mounted (e.g. re-parented to a different id).
344
+ useEffect(() => {
345
+ if (open) setCode(extension.content ?? "");
346
+ }, [open, extension.id]);
347
+
348
+ const isDirty = code !== (extension.content ?? "");
349
+
350
+ // Block Escape / outside-click from closing while there are unsaved edits.
351
+ const handleOpenChange = (next: boolean) => {
352
+ if (!next && isDirty) return;
353
+ setOpen(next);
354
+ if (!next) setError(null);
355
+ };
356
+
357
+ const handleCancel = () => {
358
+ setCode(extension.content ?? "");
359
+ setOpen(false);
360
+ setError(null);
361
+ };
362
+
363
+ const handleSave = async () => {
364
+ setSaving(true);
365
+ setError(null);
366
+ try {
367
+ const res = await fetch(
368
+ agentNativePath(`/_agent-native/extensions/${extension.id}`),
369
+ {
370
+ method: "PUT",
371
+ headers: { "Content-Type": "application/json" },
372
+ body: JSON.stringify({ content: code }),
373
+ },
374
+ );
375
+ if (!res.ok) {
376
+ const body = await res.json().catch(() => ({}));
377
+ throw new Error(body?.error ?? `Save failed (${res.status})`);
378
+ }
379
+ setOpen(false);
380
+ queryClient.setQueryData<Extension>(["extension", extension.id], (old) =>
381
+ old ? { ...old, content: code } : old,
382
+ );
383
+ queryClient.invalidateQueries({
384
+ queryKey: ["extension", extension.id],
385
+ });
386
+ queryClient.invalidateQueries({ queryKey: ["extensions"] });
387
+ onSaved?.();
388
+ } catch (err: any) {
389
+ setError(err?.message ?? "Save failed");
390
+ } finally {
391
+ setSaving(false);
392
+ }
393
+ };
394
+
395
+ return (
396
+ <>
397
+ <Tooltip>
398
+ <TooltipTrigger asChild>
399
+ <button
400
+ type="button"
401
+ onClick={() => setOpen(true)}
402
+ className="inline-flex items-center justify-center rounded-md h-8 w-8 text-muted-foreground hover:bg-accent hover:text-accent-foreground cursor-pointer"
403
+ >
404
+ <IconCode className="h-4 w-4" />
405
+ </button>
406
+ </TooltipTrigger>
407
+ <TooltipContent>View / edit source</TooltipContent>
408
+ </Tooltip>
409
+ <Dialog open={open} onOpenChange={handleOpenChange}>
410
+ <DialogContent className="flex h-[85vh] w-[90vw] max-w-[900px] flex-col gap-0 overflow-hidden p-0">
411
+ <div className="flex shrink-0 items-center border-b border-border px-5 py-3 pr-12">
412
+ <DialogTitle className="truncate text-sm font-medium">
413
+ {extension.name} — source
414
+ </DialogTitle>
415
+ </div>
416
+ <textarea
417
+ className="flex-1 resize-none bg-muted/40 px-5 py-4 font-mono text-xs leading-relaxed text-foreground focus:outline-none"
418
+ value={code}
419
+ onChange={(e) => setCode(e.target.value)}
420
+ spellCheck={false}
421
+ />
422
+ <div className="flex shrink-0 items-center justify-between border-t border-border px-5 py-3">
423
+ {error ? (
424
+ <p className="text-xs text-destructive">{error}</p>
425
+ ) : (
426
+ <span className="text-xs text-muted-foreground">
427
+ Alpine.js / HTML &middot; {code.length.toLocaleString()} chars
428
+ </span>
429
+ )}
430
+ <div className="flex items-center gap-2">
431
+ <button
432
+ type="button"
433
+ onClick={handleCancel}
434
+ className="inline-flex h-8 cursor-pointer items-center rounded-md border border-input px-3 text-xs hover:bg-accent"
435
+ >
436
+ Cancel
437
+ </button>
438
+ <button
439
+ type="button"
440
+ onClick={handleSave}
441
+ disabled={saving}
442
+ className="inline-flex h-8 cursor-pointer items-center rounded-md bg-primary px-4 text-xs font-medium text-primary-foreground hover:opacity-90 disabled:opacity-50"
443
+ >
444
+ {saving ? "Saving…" : "Save"}
445
+ </button>
446
+ </div>
447
+ </div>
448
+ </DialogContent>
449
+ </Dialog>
450
+ </>
451
+ );
452
+ }
453
+
327
454
  function EditToolPopover({
328
455
  extension,
329
456
  onOpenChange,
@@ -1157,6 +1284,12 @@ export function ExtensionViewer({ extensionId }: ExtensionViewerProps) {
1157
1284
  onRestored={() => setRefreshKey((k) => k + 1)}
1158
1285
  onOpenChange={onPopoverOpenChange}
1159
1286
  />
1287
+ {extension.canEdit && (
1288
+ <SourceCodeDialog
1289
+ extension={extension}
1290
+ onSaved={() => setRefreshKey((k) => k + 1)}
1291
+ />
1292
+ )}
1160
1293
  <EditToolPopover
1161
1294
  extension={extension}
1162
1295
  onOpenChange={onPopoverOpenChange}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IconChevronDown,
3
3
  IconPlus,
4
- IconSettings,
4
+ IconFilter,
5
5
  IconStar,
6
6
  IconStarFilled,
7
7
  IconTrash,
@@ -570,7 +570,7 @@ function ExtensionSortMenu({
570
570
  className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground/45 opacity-0 transition-all hover:bg-accent hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring group-hover/extensions-section:opacity-100"
571
571
  aria-label={copy.sortOptions}
572
572
  >
573
- <IconSettings className="h-3.5 w-3.5" />
573
+ <IconFilter className="h-3.5 w-3.5" />
574
574
  </button>
575
575
  </DropdownMenuTrigger>
576
576
  </TooltipTrigger>
@@ -226,11 +226,19 @@ export function buildExtensionHtml(
226
226
  </style>
227
227
  <style>
228
228
  *, *::before, *::after { border-color: hsl(var(--border)); }
229
+ html, body {
230
+ /* Transparent so the iframe inherits the host surface (dashboard panel,
231
+ sidebar, chat) instead of painting the browser's default white canvas.
232
+ The dark class still flips the theme vars; content paints its own
233
+ bg-background / bg-card surfaces. */
234
+ background: transparent;
235
+ }
229
236
  body {
230
237
  --agent-native-extension-padding: clamp(16px, 2vw, 24px);
231
238
  /* Legacy alias for pre-rename extension content (do not remove). */
232
239
  --agent-native-tool-padding: var(--agent-native-extension-padding);
233
240
  box-sizing: border-box;
241
+ color: hsl(var(--foreground));
234
242
  font-family: 'Inter', sans-serif;
235
243
  margin: 0;
236
244
  min-height: 100vh;
@@ -403,8 +411,14 @@ export function buildExtensionHtml(
403
411
  }
404
412
 
405
413
  if (!res.ok) {
406
- var err = res.body || { error: res.statusText };
407
- throw new Error(err.error || 'Action failed: ' + res.status);
414
+ var err = res.body || {};
415
+ var rawError = typeof err === 'string' ? err : err.error;
416
+ var message = (typeof rawError === 'string' && rawError.trim())
417
+ ? rawError
418
+ : (res.status === 404
419
+ ? "Action '" + name + "' is not available over HTTP (404). It may be agent-only (http: false); expose it with an HTTP-mounted action to call it from an extension."
420
+ : "Action '" + name + "' failed (" + (res.status || 'network error') + ")");
421
+ throw new Error(message);
408
422
  }
409
423
  return res.body;
410
424
  }
@@ -730,7 +744,7 @@ export function buildExtensionHtml(
730
744
  });
731
745
  </script>
732
746
  </head>
733
- <body${extensionId ? ` data-extension-id="${extensionIdAttr}" data-tool-id="${extensionIdAttr}"` : ""} class="bg-background text-foreground">
747
+ <body${extensionId ? ` data-extension-id="${extensionIdAttr}" data-tool-id="${extensionIdAttr}"` : ""} class="text-foreground">
734
748
  ${content}
735
749
  <div id="__extension-error-toast">
736
750
  <div style="display:flex;align-items:flex-start;gap:8px;">
@@ -1,3 +1,42 @@
1
+ /**
2
+ * Canonical set of semantic theme token names shared by the app and extension
3
+ * iframes. This is the single source of truth: `getThemeVars` bakes default
4
+ * values for these into every iframe, and the host reads the *actual* computed
5
+ * values for the same names to sync its live palette into embedded extensions
6
+ * (see EmbeddedExtension). Custom properties can't be enumerated portably from
7
+ * a computed style, so the names must be listed explicitly.
8
+ */
9
+ export const THEME_VAR_NAMES = [
10
+ "--background",
11
+ "--foreground",
12
+ "--card",
13
+ "--card-foreground",
14
+ "--popover",
15
+ "--popover-foreground",
16
+ "--primary",
17
+ "--primary-foreground",
18
+ "--secondary",
19
+ "--secondary-foreground",
20
+ "--muted",
21
+ "--muted-foreground",
22
+ "--accent",
23
+ "--accent-foreground",
24
+ "--destructive",
25
+ "--destructive-foreground",
26
+ "--border",
27
+ "--input",
28
+ "--ring",
29
+ "--radius",
30
+ "--sidebar-background",
31
+ "--sidebar-foreground",
32
+ "--sidebar-primary",
33
+ "--sidebar-primary-foreground",
34
+ "--sidebar-accent",
35
+ "--sidebar-accent-foreground",
36
+ "--sidebar-border",
37
+ "--sidebar-ring",
38
+ ] as const;
39
+
1
40
  /**
2
41
  * CSS variables baked into every extension iframe. Both light and dark are
3
42
  * always emitted — the `.dark` class on the iframe's `<html>` toggles between
@@ -213,7 +213,14 @@ export default defineAction({
213
213
  "Enable cursor-based pagination. After each response, reads cursorPath from the JSON body and re-issues the request with cursorParam or cursorBodyPath set, accumulating items from itemsPath (or whole bodies) until cursor is empty or maxPages is reached. Combine with saveToFile to write the full dataset to a workspace file; use scratch/... for temporary staging.",
214
214
  ),
215
215
  }),
216
- http: false,
216
+ // Mounted over HTTP (POST) so the agent and frontend (`useActionMutation`)
217
+ // can reach it, consistent with provider-api-catalog / provider-api-docs.
218
+ // toolCallable: false blocks the extension iframe bridge — this action
219
+ // accepts arbitrary methods (PUT/DELETE/etc.) against provider APIs, so
220
+ // allowing shared extensions to call it would let malicious extension authors
221
+ // mutate provider data under the opener's credentials.
222
+ http: { method: "POST" },
223
+ toolCallable: false,
217
224
  run: async (args) => {
218
225
  if (args.stageAs) {
219
226
  const ctx = requireRequestCredentialContext("provider-api staging");
@@ -7,6 +7,7 @@ import {
7
7
  IconStar,
8
8
  IconPencil,
9
9
  IconSettings,
10
+ IconFilter,
10
11
  IconGripVertical,
11
12
  IconBook2,
12
13
  IconDatabase,
@@ -251,7 +252,7 @@ function SidebarSectionSettingsPopover({
251
252
  className="flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/65 opacity-0 transition-all hover:bg-sidebar-accent hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring group-hover/section:opacity-100 data-[state=open]:opacity-100"
252
253
  aria-label={settingsLabel}
253
254
  >
254
- <IconSettings className="h-3.5 w-3.5" />
255
+ <IconFilter className="h-3.5 w-3.5" />
255
256
  </button>
256
257
  </PopoverTrigger>
257
258
  </TooltipTrigger>
@@ -3,6 +3,7 @@ import { useDraggable } from "@dnd-kit/core";
3
3
  import {
4
4
  IconGripVertical,
5
5
  IconDotsVertical,
6
+ IconExternalLink,
6
7
  IconMaximize,
7
8
  IconPencil,
8
9
  IconRefresh,
@@ -12,6 +13,7 @@ import {
12
13
  } from "@tabler/icons-react";
13
14
  import { useIsFetching, useQueryClient } from "@tanstack/react-query";
14
15
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
16
+ import { useNavigate } from "react-router";
15
17
 
16
18
  import { ChartFillHeight, SqlChart } from "@/components/dashboard/SqlChart";
17
19
  import {
@@ -119,6 +121,8 @@ export function SqlChartCard({
119
121
 
120
122
  const [confirmOpen, setConfirmOpen] = useState(false);
121
123
  const [expanded, setExpanded] = useState(false);
124
+ const [extRefreshKey, setExtRefreshKey] = useState(0);
125
+ const navigate = useNavigate();
122
126
  const [exportCsv, setExportCsv] = useState<(() => void) | null>(null);
123
127
  const [shouldLoadData, setShouldLoadData] = useState(
124
128
  eagerLoad ||
@@ -291,10 +295,12 @@ export function SqlChartCard({
291
295
  }
292
296
 
293
297
  // Extension panels render their sandboxed iframe full-bleed with no card chrome
294
- // or title — the extension owns its own UI. Editable dashboards still get a
295
- // hover overlay for delete/drag. Editing routes through the agent (the manual
296
- // panel editor has no extension picker), so no inline edit action here.
298
+ // or title — the extension owns its own UI. All viewers get the read-only
299
+ // actions (full screen, refresh, open extension); editable dashboards also get
300
+ // delete and drag.
297
301
  if (panel.chartType === "extension") {
302
+ const extensionId = (panel.config as Record<string, unknown> | undefined)
303
+ ?.extensionId as string | undefined;
298
304
  return (
299
305
  <div
300
306
  ref={setCardNodeRef}
@@ -302,45 +308,97 @@ export function SqlChartCard({
302
308
  data-dragging={isDragSource ? "true" : undefined}
303
309
  className="dashboard-extension-card group relative h-full"
304
310
  >
305
- <SqlChart panel={panel} resolvedSql={resolvedSql} loadData />
306
- {editable ? (
307
- <div className="absolute right-1 top-1 flex items-center gap-1 opacity-0 group-hover:opacity-100">
308
- <DropdownMenu>
309
- <Tooltip>
310
- <TooltipTrigger asChild>
311
- <DropdownMenuTrigger asChild>
312
- <button
313
- className="p-1 rounded bg-background/80 text-muted-foreground hover:text-foreground"
314
- aria-label={t("sqlDashboard.panelOptions")}
315
- >
316
- <IconDotsVertical className="h-3.5 w-3.5" />
317
- </button>
318
- </DropdownMenuTrigger>
319
- </TooltipTrigger>
320
- <TooltipContent>
321
- {t("sqlDashboard.panelOptions")}
322
- </TooltipContent>
323
- </Tooltip>
324
- <DropdownMenuContent align="end" className="w-40">
311
+ {!expanded && (
312
+ <SqlChart
313
+ key={extRefreshKey}
314
+ panel={panel}
315
+ resolvedSql={resolvedSql}
316
+ loadData
317
+ />
318
+ )}
319
+ <div className="absolute right-1 top-1 flex items-center gap-1 opacity-0 group-hover:opacity-100">
320
+ <DropdownMenu>
321
+ <Tooltip>
322
+ <TooltipTrigger asChild>
323
+ <DropdownMenuTrigger asChild>
324
+ <button
325
+ className="p-1 rounded bg-background/80 text-muted-foreground hover:text-foreground"
326
+ aria-label={t("sqlDashboard.panelOptions")}
327
+ >
328
+ <IconDotsVertical className="h-3.5 w-3.5" />
329
+ </button>
330
+ </DropdownMenuTrigger>
331
+ </TooltipTrigger>
332
+ <TooltipContent>{t("sqlDashboard.panelOptions")}</TooltipContent>
333
+ </Tooltip>
334
+ <DropdownMenuContent align="end" className="w-44">
335
+ <DropdownMenuItem onSelect={() => setExpanded(true)}>
336
+ <IconMaximize className="h-4 w-4 mr-2" />
337
+ {t("sqlDashboard.fullScreen")}
338
+ </DropdownMenuItem>
339
+ {extensionId ? (
325
340
  <DropdownMenuItem
326
- onSelect={(e) => {
327
- e.preventDefault();
328
- setConfirmOpen(true);
329
- }}
341
+ onSelect={() =>
342
+ navigate(
343
+ `/extensions/${extensionId}/${encodeURIComponent(
344
+ (panel.title ?? "extension")
345
+ .toLowerCase()
346
+ .replace(/[^a-z0-9]+/g, "-"),
347
+ )}`,
348
+ )
349
+ }
330
350
  >
331
- <IconTrash className="h-4 w-4 mr-2" />
332
- {t("sidebar.delete")}
351
+ <IconExternalLink className="h-4 w-4 mr-2" />
352
+ Open extension {/* i18n-ignore */}
333
353
  </DropdownMenuItem>
334
- </DropdownMenuContent>
335
- </DropdownMenu>
354
+ ) : null}
355
+ <DropdownMenuSeparator />
356
+ <DropdownMenuItem onSelect={() => setExtRefreshKey((k) => k + 1)}>
357
+ <IconRefresh className="h-4 w-4 mr-2" />
358
+ {t("sqlDashboard.refresh")}
359
+ </DropdownMenuItem>
360
+ {editable ? (
361
+ <>
362
+ <DropdownMenuSeparator />
363
+ <DropdownMenuItem
364
+ onSelect={(e) => {
365
+ e.preventDefault();
366
+ setConfirmOpen(true);
367
+ }}
368
+ >
369
+ <IconTrash className="h-4 w-4 mr-2" />
370
+ {t("sidebar.delete")}
371
+ </DropdownMenuItem>
372
+ </>
373
+ ) : null}
374
+ </DropdownMenuContent>
375
+ </DropdownMenu>
376
+ {editable ? (
336
377
  <PanelDragHandle
337
378
  panelId={panel.id}
338
379
  label={t("sqlDashboard.dragToReorder")}
339
380
  className="p-1 rounded bg-background/80 cursor-grab active:cursor-grabbing text-muted-foreground/50 hover:text-muted-foreground"
340
381
  iconClassName="h-3.5 w-3.5"
341
382
  />
342
- </div>
343
- ) : null}
383
+ ) : null}
384
+ </div>
385
+ <Dialog open={expanded} onOpenChange={setExpanded}>
386
+ <DialogContent className="flex h-[90vh] w-[95vw] max-w-[1400px] flex-col gap-4">
387
+ <DialogHeader className="shrink-0 pr-8 text-left">
388
+ <DialogTitle className="truncate">{panel.title}</DialogTitle>
389
+ </DialogHeader>
390
+ <div className="flex min-h-0 flex-1 flex-col overflow-auto">
391
+ <ChartFillHeight>
392
+ <SqlChart
393
+ key={extRefreshKey}
394
+ panel={panel}
395
+ resolvedSql={resolvedSql}
396
+ loadData
397
+ />
398
+ </ChartFillHeight>
399
+ </div>
400
+ </DialogContent>
401
+ </Dialog>
344
402
  {editable ? (
345
403
  <AlertDialog open={confirmOpen} onOpenChange={setConfirmOpen}>
346
404
  <AlertDialogContent>
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-01
4
+ ---
5
+
6
+ Chrome recording uploads now serialize chunks to avoid resumable upload offset races.
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "name": "Agent-Native Clips",
4
4
  "short_name": "Clips",
5
- "version": "0.1.8",
5
+ "version": "0.1.9",
6
6
  "description": "Start Clips recordings from Chrome, capture optional diagnostics, and preview Clips links on GitHub.",
7
7
  "minimum_chrome_version": "116",
8
8
  "action": {
@@ -129,6 +129,7 @@ type ActiveRecording = {
129
129
  sourceStreams: MediaStream[];
130
130
  audioContext: AudioContext | null;
131
131
  chunkIndex: number;
132
+ uploadChain: Promise<void>;
132
133
  uploadPromises: Promise<unknown>[];
133
134
  uploadFailure: Error | null;
134
135
  // Local safety buffer: every recorded blob is kept here (browser-managed,
@@ -795,6 +796,7 @@ async function begin(message: BeginMessage): Promise<{
795
796
  ],
796
797
  audioContext: mixedAudio.audioContext,
797
798
  chunkIndex: 0,
799
+ uploadChain: Promise.resolve(),
798
800
  uploadPromises: [],
799
801
  uploadFailure: null,
800
802
  recordedBlobs: [],
@@ -837,30 +839,35 @@ async function begin(message: BeginMessage): Promise<{
837
839
  // rejected promise that surfaces as an "Uncaught (in promise)" error (bad
838
840
  // look in a Chrome Web Store review). finalizeStop reads recording.upload-
839
841
  // Failure and surfaces it through the normal error path instead.
840
- const upload = (
841
- recording.uploadMode === "streaming"
842
- ? uploadStreamingBlob(recording, event.data)
843
- : uploadBlobInSlices(recording, event.data)
844
- ).catch((err) => {
845
- recording.uploadFailure =
846
- err instanceof Error ? err : new Error(String(err));
847
- captureExtensionError(recording.uploadFailure, {
848
- tags: {
849
- surface: "offscreen",
850
- recordingStep: "dataavailable-upload",
851
- },
852
- extra: {
853
- recordingId: recording.recordingId,
854
- blobBytes: event.data.size,
855
- chunkIndex: recording.chunkIndex,
856
- mimeType: event.data.type || recording.mimeType,
857
- },
858
- });
859
- reportStatus(recording.sessionId, "error", {
860
- error: recording.uploadFailure.message,
842
+ const upload = recording.uploadChain
843
+ .then(() =>
844
+ recording.cancelled || recording.uploadFailure
845
+ ? undefined
846
+ : recording.uploadMode === "streaming"
847
+ ? uploadStreamingBlob(recording, event.data)
848
+ : uploadBlobInSlices(recording, event.data),
849
+ )
850
+ .catch((err) => {
851
+ recording.uploadFailure =
852
+ err instanceof Error ? err : new Error(String(err));
853
+ captureExtensionError(recording.uploadFailure, {
854
+ tags: {
855
+ surface: "offscreen",
856
+ recordingStep: "dataavailable-upload",
857
+ },
858
+ extra: {
859
+ recordingId: recording.recordingId,
860
+ blobBytes: event.data.size,
861
+ chunkIndex: recording.chunkIndex,
862
+ mimeType: event.data.type || recording.mimeType,
863
+ },
864
+ });
865
+ reportStatus(recording.sessionId, "error", {
866
+ error: recording.uploadFailure.message,
867
+ });
868
+ if (recorder.state !== "inactive") recorder.stop();
861
869
  });
862
- if (recorder.state !== "inactive") recorder.stop();
863
- });
870
+ recording.uploadChain = upload.then(() => undefined);
864
871
  recording.uploadPromises.push(upload);
865
872
  });
866
873
 
@@ -16,6 +16,8 @@ export declare const RUN_STALE_MS = 15000;
16
16
  * With the normal 15s window the reaper would falsely kill that freshly-
17
17
  * inserted-but-not-yet-heartbeaten row. 90s tolerates a slow background
18
18
  * cold-start while still reaping a genuinely dead background worker promptly.
19
+ * Claimed background workers heartbeat during long work; the stale watchdog is a
20
+ * liveness timeout, not the Netlify background-function execution budget.
19
21
  *
20
22
  * Only applied to rows explicitly marked background-dispatched; ordinary
21
23
  * foreground runs keep the tight 15s window unchanged.
@@ -62,13 +64,14 @@ export declare const CLAIMED_BACKGROUND_WORKER_FAILED_ERROR_EVENT: {
62
64
  * Grace period before a never-claimed background run (dispatch_mode still
63
65
  * 'background', no worker claim) is treated as a dead handoff and reaped.
64
66
  *
65
- * This is intentionally MUCH tighter than `BACKGROUND_RUN_STALE_MS` (90s). The
66
- * wide 90s window exists ONLY to protect a CLAIMED worker whose heartbeat lags
67
- * during a slow cold start. A run that is still `dispatch_mode = 'background'`
68
- * has, by definition, NO worker — nothing to protect — so once a Netlify
67
+ * This is intentionally tighter than `BACKGROUND_RUN_STALE_MS`. That wider
68
+ * window protects cold-starting or temporarily delayed background dispatches,
69
+ * while claimed workers stay alive by heartbeat/progress updates. A run that is
70
+ * still `dispatch_mode = 'background'` has, by definition, NO worker — nothing
71
+ * to protect — so once a Netlify
69
72
  * background function has had a reasonable cold-start window to claim it and
70
73
  * hasn't, the handoff is dead and should surface promptly instead of leaving
71
- * the user staring at a spinner for 90s. 25s comfortably exceeds a normal
74
+ * the user staring at a spinner for the durable-worker window. 25s comfortably exceeds a normal
72
75
  * Netlify Lambda cold start while still failing fast on a silent worker death.
73
76
  */
74
77
  export declare const UNCLAIMED_BACKGROUND_RUN_GRACE_MS = 25000;
@@ -159,6 +162,16 @@ export declare function setRunError(runId: string, errorCode: string | undefined
159
162
  * status='completed' + terminal_reason='run_timeout').
160
163
  */
161
164
  export declare function setRunTerminalReason(runId: string, terminalReason: string | undefined): Promise<void>;
165
+ /**
166
+ * Repair a run whose terminal event was durably appended but whose final
167
+ * `agent_runs.status` write lost a race with reconnect/reaper code.
168
+ *
169
+ * The event ledger is the durable transcript users see. If its latest event is
170
+ * terminal, the run is no longer alive and must not be converted into a stale
171
+ * error later. This keeps `agent_runs` and `agent_run_events` from telling two
172
+ * different stories after delayed DB writes or background function teardown.
173
+ */
174
+ export declare function reconcileTerminalRunFromEvents(runId: string): Promise<boolean>;
162
175
  /**
163
176
  * Diagnostic stage names recorded onto a background run as it moves through the
164
177
  * `_process-run` worker pipeline. Each value is the LAST stage successfully
@@ -235,7 +248,7 @@ export declare function reapIfStale(runId: string, maxStaleMs?: number): Promise
235
248
  * before it can claim), the row stays `background`, never heartbeats again, and
236
249
  * — because dispatch returned 202 — the foreground already returned the SSE
237
250
  * stream, so the existing fast-fail inline fallback never engaged. The run would
238
- * otherwise hang for the full 90s background window and then error opaquely.
251
+ * otherwise hang for the full durable background window and then error opaquely.
239
252
  *
240
253
  * This reaps such a run EARLY and DISTINCTLY: a row that is still unclaimed
241
254
  * (`dispatch_mode = 'background'`) past the tight `UNCLAIMED_BACKGROUND_RUN_GRACE_MS`
@@ -1 +1 @@
1
- {"version":3,"file":"run-store.d.ts","sourceRoot":"","sources":["../../src/agent/run-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-store.d.ts","sourceRoot":"","sources":["../../src/agent/run-store.ts"],"names":[],"mappings":"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"}