@agent-native/core 0.72.3 → 0.73.0

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 (223) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +38 -0
  3. package/corpus/core/docs/content/skills-guide.md +14 -0
  4. package/corpus/core/docs/content/template-clips.md +7 -1
  5. package/corpus/core/package.json +6 -6
  6. package/corpus/core/src/a2a/client.ts +7 -3
  7. package/corpus/core/src/agent/durable-background.ts +25 -12
  8. package/corpus/core/src/cli/create.ts +1 -1
  9. package/corpus/core/src/cli/skills.ts +450 -19
  10. package/corpus/core/src/client/api-path.ts +28 -0
  11. package/corpus/core/src/client/embed-auth.ts +26 -0
  12. package/corpus/core/src/client/mcp-app-host.ts +6 -0
  13. package/corpus/core/src/client/mcp-apps/McpAppRenderer.tsx +227 -33
  14. package/corpus/core/src/client/resources/use-mcp-servers.ts +1 -0
  15. package/corpus/core/src/client/settings/DemoModeSection.tsx +3 -1
  16. package/corpus/core/src/demo/fetch-interceptor.ts +1 -1
  17. package/corpus/core/src/embedding/agent.ts +6 -1
  18. package/corpus/core/src/embedding/bridge.ts +34 -1
  19. package/corpus/core/src/mcp/build-server.ts +38 -10
  20. package/corpus/core/src/mcp/embed-app.ts +120 -45
  21. package/corpus/core/src/mcp/index.ts +5 -0
  22. package/corpus/core/src/mcp/org-directory.ts +70 -11
  23. package/corpus/core/src/mcp/server.ts +14 -0
  24. package/corpus/core/src/mcp-client/config.ts +12 -0
  25. package/corpus/core/src/mcp-client/index.ts +2 -0
  26. package/corpus/core/src/mcp-client/manager.ts +268 -9
  27. package/corpus/core/src/mcp-client/remote-store.ts +154 -0
  28. package/corpus/core/src/mcp-client/routes.ts +2 -0
  29. package/corpus/core/src/server/agent-chat-plugin.ts +8 -0
  30. package/corpus/core/src/server/auth.ts +7 -0
  31. package/corpus/core/src/server/index.ts +1 -0
  32. package/corpus/core/src/server/onboarding-html.ts +95 -9
  33. package/corpus/core/src/shared/mcp-embed-headers.ts +44 -3
  34. package/corpus/core/src/templates/default/AGENTS.md +4 -0
  35. package/corpus/core/src/templates/default/package.json +2 -1
  36. package/corpus/core/src/templates/headless/AGENTS.md +4 -0
  37. package/corpus/core/src/templates/headless/package.json +1 -0
  38. package/corpus/core/src/templates/workspace-root/AGENTS.md +4 -0
  39. package/corpus/core/src/templates/workspace-root/README.md +4 -0
  40. package/corpus/core/src/templates/workspace-root/package.json +1 -0
  41. package/corpus/core/src/vite/client.ts +53 -0
  42. package/corpus/templates/analytics/actions/update-dashboard.ts +3 -4
  43. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +144 -40
  44. package/corpus/templates/analytics/app/global.css +15 -13
  45. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +9 -32
  46. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +0 -26
  47. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +0 -23
  48. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/pivot.ts +65 -2
  49. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +3 -4
  50. package/corpus/templates/analytics/changelog/2026-06-24-dashboard-charts-now-fill-sparse-template-time-series-suppor.md +6 -0
  51. package/corpus/templates/analytics/changelog/2026-06-24-dashboard-rows-now-auto-fit-panels-so-one-two-or-three-chart.md +6 -0
  52. package/corpus/templates/analytics/changelog/2026-06-24-dashboard-traffic-tables-now-show-top-urls-and-shared-clips-.md +6 -0
  53. package/corpus/templates/analytics/changelog/2026-06-24-first-party-signup-and-pageview-panels-now-honor-dashboard-filters.md +5 -0
  54. package/corpus/templates/analytics/changelog/2026-06-24-first-party-template-dashboards-now-include-repeat-users-ret.md +6 -0
  55. package/corpus/templates/analytics/changelog/2026-06-24-retention-charts-now-break-out-1-day-and-7-day-return-rates-.md +6 -0
  56. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +256 -44
  57. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +7 -2
  58. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +35 -8
  59. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +287 -42
  60. package/corpus/templates/assets/.agents/skills/a2a-assets/SKILL.md +17 -10
  61. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +15 -6
  62. package/corpus/templates/assets/AGENTS.md +7 -5
  63. package/corpus/templates/assets/actions/generate-asset.ts +161 -0
  64. package/corpus/templates/assets/actions/list-assets.ts +4 -2
  65. package/corpus/templates/assets/actions/open-asset-picker.ts +84 -3
  66. package/corpus/templates/assets/app/routes/library.tsx +243 -40
  67. package/corpus/templates/calendar/changelog/2026-06-23-added-a-heads-up-explaining-google-s-app-not-verified-screen.md +1 -1
  68. package/corpus/templates/calendar/server/plugins/auth.ts +12 -0
  69. package/corpus/templates/clips/.agents/skills/recording/SKILL.md +7 -7
  70. package/corpus/templates/clips/AGENTS.md +6 -2
  71. package/corpus/templates/clips/app/components/capture-install-options.tsx +20 -4
  72. package/corpus/templates/clips/app/components/player/player-controls.tsx +62 -32
  73. package/corpus/templates/clips/app/lib/capture-install-options.ts +39 -5
  74. package/corpus/templates/clips/app/routes/download.tsx +2 -2
  75. package/corpus/templates/clips/app/routes/share.$shareId.tsx +1 -1
  76. package/corpus/templates/clips/changelog/2026-06-24-inline-slack-playback-controls-no-longer-shift-when-adjustin.md +6 -0
  77. package/corpus/templates/clips/changelog/2026-06-24-shared-clips-now-expose-their-full-console-log-stream-all-le.md +6 -0
  78. package/corpus/templates/clips/changelog/2026-06-24-shared-clips-now-expose-their-full-fetch-xhr-network-request.md +6 -0
  79. package/corpus/templates/clips/changelog/2026-06-24-the-chrome-extension-option-now-only-appears-on-supported-hosts.md +5 -0
  80. package/corpus/templates/clips/chrome-extension/STORE_DRAFT.md +13 -8
  81. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  82. package/corpus/templates/clips/chrome-extension/scripts/package.ts +15 -2
  83. package/corpus/templates/clips/chrome-extension/src/overlay.css +4 -25
  84. package/corpus/templates/clips/chrome-extension/src/overlay.ts +1 -3
  85. package/corpus/templates/clips/desktop/src-tauri/src/native_speech.rs +9 -0
  86. package/corpus/templates/clips/server/lib/public-agent-context.ts +67 -24
  87. package/corpus/templates/design/AGENTS.md +10 -5
  88. package/corpus/templates/design/actions/connect-assets-mcp.ts +131 -0
  89. package/corpus/templates/design/actions/insert-asset.ts +219 -0
  90. package/corpus/templates/design/actions/view-screen.ts +3 -1
  91. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +1 -1
  92. package/corpus/templates/design/app/pages/DesignEditor.tsx +53 -0
  93. package/corpus/templates/design/server/plugins/agent-chat.ts +5 -1
  94. package/corpus/templates/design/server/plugins/assets-mcp.ts +60 -0
  95. package/corpus/templates/mail/server/plugins/auth.ts +4 -1
  96. package/corpus/templates/plan/app/pages/PlansPage.tsx +271 -197
  97. package/corpus/templates/plan/server/plan-content.ts +45 -2
  98. package/dist/a2a/client.d.ts +1 -0
  99. package/dist/a2a/client.d.ts.map +1 -1
  100. package/dist/a2a/client.js +5 -3
  101. package/dist/a2a/client.js.map +1 -1
  102. package/dist/agent/durable-background.d.ts +9 -4
  103. package/dist/agent/durable-background.d.ts.map +1 -1
  104. package/dist/agent/durable-background.js +24 -11
  105. package/dist/agent/durable-background.js.map +1 -1
  106. package/dist/cli/create.js +1 -1
  107. package/dist/cli/create.js.map +1 -1
  108. package/dist/cli/skills.d.ts.map +1 -1
  109. package/dist/cli/skills.js +361 -19
  110. package/dist/cli/skills.js.map +1 -1
  111. package/dist/client/api-path.d.ts.map +1 -1
  112. package/dist/client/api-path.js +27 -0
  113. package/dist/client/api-path.js.map +1 -1
  114. package/dist/client/embed-auth.d.ts.map +1 -1
  115. package/dist/client/embed-auth.js +27 -0
  116. package/dist/client/embed-auth.js.map +1 -1
  117. package/dist/client/mcp-app-host.d.ts.map +1 -1
  118. package/dist/client/mcp-app-host.js +5 -0
  119. package/dist/client/mcp-app-host.js.map +1 -1
  120. package/dist/client/mcp-apps/McpAppRenderer.d.ts +1 -0
  121. package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  122. package/dist/client/mcp-apps/McpAppRenderer.js +179 -33
  123. package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
  124. package/dist/client/resources/use-mcp-servers.d.ts +1 -0
  125. package/dist/client/resources/use-mcp-servers.d.ts.map +1 -1
  126. package/dist/client/resources/use-mcp-servers.js.map +1 -1
  127. package/dist/client/settings/DemoModeSection.d.ts.map +1 -1
  128. package/dist/client/settings/DemoModeSection.js +3 -1
  129. package/dist/client/settings/DemoModeSection.js.map +1 -1
  130. package/dist/demo/fetch-interceptor.js +1 -1
  131. package/dist/demo/fetch-interceptor.js.map +1 -1
  132. package/dist/embedding/agent.d.ts +1 -1
  133. package/dist/embedding/agent.d.ts.map +1 -1
  134. package/dist/embedding/agent.js +1 -1
  135. package/dist/embedding/agent.js.map +1 -1
  136. package/dist/embedding/bridge.d.ts.map +1 -1
  137. package/dist/embedding/bridge.js +27 -1
  138. package/dist/embedding/bridge.js.map +1 -1
  139. package/dist/extensions/schema.d.ts +2 -2
  140. package/dist/mcp/build-server.d.ts +2 -0
  141. package/dist/mcp/build-server.d.ts.map +1 -1
  142. package/dist/mcp/build-server.js +32 -9
  143. package/dist/mcp/build-server.js.map +1 -1
  144. package/dist/mcp/embed-app.d.ts.map +1 -1
  145. package/dist/mcp/embed-app.js +120 -45
  146. package/dist/mcp/embed-app.js.map +1 -1
  147. package/dist/mcp/index.d.ts +1 -0
  148. package/dist/mcp/index.d.ts.map +1 -1
  149. package/dist/mcp/index.js +1 -0
  150. package/dist/mcp/index.js.map +1 -1
  151. package/dist/mcp/org-directory.d.ts +1 -0
  152. package/dist/mcp/org-directory.d.ts.map +1 -1
  153. package/dist/mcp/org-directory.js +59 -11
  154. package/dist/mcp/org-directory.js.map +1 -1
  155. package/dist/mcp/server.d.ts.map +1 -1
  156. package/dist/mcp/server.js +9 -0
  157. package/dist/mcp/server.js.map +1 -1
  158. package/dist/mcp-client/config.d.ts +12 -0
  159. package/dist/mcp-client/config.d.ts.map +1 -1
  160. package/dist/mcp-client/config.js.map +1 -1
  161. package/dist/mcp-client/index.d.ts +1 -1
  162. package/dist/mcp-client/index.d.ts.map +1 -1
  163. package/dist/mcp-client/index.js +1 -1
  164. package/dist/mcp-client/index.js.map +1 -1
  165. package/dist/mcp-client/manager.d.ts +2 -0
  166. package/dist/mcp-client/manager.d.ts.map +1 -1
  167. package/dist/mcp-client/manager.js +201 -9
  168. package/dist/mcp-client/manager.js.map +1 -1
  169. package/dist/mcp-client/remote-store.d.ts +27 -0
  170. package/dist/mcp-client/remote-store.d.ts.map +1 -1
  171. package/dist/mcp-client/remote-store.js +105 -0
  172. package/dist/mcp-client/remote-store.js.map +1 -1
  173. package/dist/mcp-client/routes.d.ts +1 -0
  174. package/dist/mcp-client/routes.d.ts.map +1 -1
  175. package/dist/mcp-client/routes.js +1 -0
  176. package/dist/mcp-client/routes.js.map +1 -1
  177. package/dist/provider-api/actions/github-repo-files.d.ts +2 -2
  178. package/dist/provider-api/actions/query-staged-dataset.d.ts +3 -3
  179. package/dist/provider-api/corpus-jobs.d.ts +8 -8
  180. package/dist/server/agent-chat-plugin.d.ts +2 -0
  181. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  182. package/dist/server/agent-chat-plugin.js +8 -0
  183. package/dist/server/agent-chat-plugin.js.map +1 -1
  184. package/dist/server/auth.d.ts +7 -0
  185. package/dist/server/auth.d.ts.map +1 -1
  186. package/dist/server/auth.js +1 -0
  187. package/dist/server/auth.js.map +1 -1
  188. package/dist/server/index.d.ts +1 -1
  189. package/dist/server/index.d.ts.map +1 -1
  190. package/dist/server/index.js +1 -1
  191. package/dist/server/index.js.map +1 -1
  192. package/dist/server/onboarding-html.d.ts +15 -0
  193. package/dist/server/onboarding-html.d.ts.map +1 -1
  194. package/dist/server/onboarding-html.js +73 -9
  195. package/dist/server/onboarding-html.js.map +1 -1
  196. package/dist/shared/mcp-embed-headers.d.ts +3 -1
  197. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  198. package/dist/shared/mcp-embed-headers.js +40 -3
  199. package/dist/shared/mcp-embed-headers.js.map +1 -1
  200. package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
  201. package/dist/sharing/actions/set-resource-visibility.d.ts +2 -2
  202. package/dist/sharing/actions/share-resource.d.ts +1 -1
  203. package/dist/sharing/schema.d.ts +1 -1
  204. package/dist/templates/default/AGENTS.md +4 -0
  205. package/dist/templates/default/package.json +2 -1
  206. package/dist/templates/headless/AGENTS.md +4 -0
  207. package/dist/templates/headless/package.json +1 -0
  208. package/dist/templates/workspace-root/AGENTS.md +4 -0
  209. package/dist/templates/workspace-root/README.md +4 -0
  210. package/dist/templates/workspace-root/package.json +1 -0
  211. package/dist/vite/client.d.ts.map +1 -1
  212. package/dist/vite/client.js +44 -0
  213. package/dist/vite/client.js.map +1 -1
  214. package/docs/content/skills-guide.md +14 -0
  215. package/docs/content/template-clips.md +7 -1
  216. package/package.json +6 -6
  217. package/src/templates/default/AGENTS.md +4 -0
  218. package/src/templates/default/package.json +2 -1
  219. package/src/templates/headless/AGENTS.md +4 -0
  220. package/src/templates/headless/package.json +1 -0
  221. package/src/templates/workspace-root/AGENTS.md +4 -0
  222. package/src/templates/workspace-root/README.md +4 -0
  223. package/src/templates/workspace-root/package.json +1 -0
@@ -8369,6 +8369,12 @@ function PlanHistorySheet({
8369
8369
  const [selectedVersionId, setSelectedVersionId] = useState<string | null>(
8370
8370
  null,
8371
8371
  );
8372
+ // Version id pending a confirm before restore. Set from the per-row "Restore
8373
+ // this version" action in the list so restore is reachable without first
8374
+ // opening the detail preview.
8375
+ const [restoreCandidateId, setRestoreCandidateId] = useState<string | null>(
8376
+ null,
8377
+ );
8372
8378
  const versionsQuery = usePlanVersions(planId, open);
8373
8379
  const versionQuery = usePlanVersion(open ? planId : null, selectedVersionId);
8374
8380
  const restoreVersion = useRestorePlanVersion();
@@ -8401,14 +8407,12 @@ function PlanHistorySheet({
8401
8407
  onOpenChange(nextOpen);
8402
8408
  };
8403
8409
 
8404
- const restoreSelectedVersion = async () => {
8405
- if (!selectedVersionId) return;
8410
+ const restoreVersionById = async (versionId: string | null) => {
8411
+ if (!versionId) return;
8406
8412
  try {
8407
- await restoreVersion.mutateAsync({
8408
- planId,
8409
- versionId: selectedVersionId,
8410
- });
8413
+ await restoreVersion.mutateAsync({ planId, versionId });
8411
8414
  toast.success("Plan version restored.");
8415
+ setRestoreCandidateId(null);
8412
8416
  close(false);
8413
8417
  } catch (error) {
8414
8418
  toast.error(
@@ -8418,209 +8422,279 @@ function PlanHistorySheet({
8418
8422
  );
8419
8423
  }
8420
8424
  };
8425
+ const restoreCandidate =
8426
+ versions.find((version) => version.id === restoreCandidateId) ?? null;
8421
8427
 
8422
8428
  return (
8423
- <Sheet open={open} onOpenChange={close}>
8424
- <SheetContent side="right" className="w-[92vw] max-w-[720px] p-0">
8425
- <SheetHeader className="px-4 pt-4 pb-0">
8426
- <SheetTitle className="flex min-w-0 items-center gap-2 text-sm font-medium">
8427
- {selectedVersionId ? (
8428
- <button
8429
- type="button"
8430
- onClick={() => setSelectedVersionId(null)}
8431
- className="inline-flex min-w-0 items-center gap-1.5 text-muted-foreground transition-colors hover:text-foreground"
8432
- >
8433
- <IconArrowLeft className="size-4" />
8434
- <span>Back to history</span>
8435
- </button>
8436
- ) : (
8437
- <>
8438
- <IconHistory className="size-4 text-primary" />
8439
- <span>Plan history</span>
8440
- </>
8441
- )}
8442
- </SheetTitle>
8443
- <SheetDescription className="sr-only">
8444
- Browse saved plan versions and restore a previous snapshot.
8445
- </SheetDescription>
8446
- </SheetHeader>
8447
- <Separator className="mt-3" />
8448
-
8449
- {selectedVersionId ? (
8450
- <div className="flex h-[calc(100%-60px)] min-h-0 flex-col">
8451
- <div className="border-b border-border px-4 py-3">
8452
- {versionQuery.isLoading ? (
8453
- <div className="space-y-2">
8454
- <Skeleton className="h-4 w-2/3" />
8455
- <Skeleton className="h-3 w-1/3" />
8456
- </div>
8429
+ <>
8430
+ <Sheet open={open} onOpenChange={close}>
8431
+ <SheetContent side="right" className="w-[92vw] max-w-[720px] p-0">
8432
+ <SheetHeader className="px-4 pt-4 pb-0">
8433
+ <SheetTitle className="flex min-w-0 items-center gap-2 text-sm font-medium">
8434
+ {selectedVersionId ? (
8435
+ <button
8436
+ type="button"
8437
+ onClick={() => setSelectedVersionId(null)}
8438
+ className="inline-flex min-w-0 items-center gap-1.5 text-muted-foreground transition-colors hover:text-foreground"
8439
+ >
8440
+ <IconArrowLeft className="size-4" />
8441
+ <span>Back to history</span>
8442
+ </button>
8457
8443
  ) : (
8458
8444
  <>
8459
- <p className="truncate text-sm font-medium">
8460
- {selectedVersion?.title || "Untitled plan"}
8461
- </p>
8462
- <p className="mt-0.5 text-[11px] text-muted-foreground">
8463
- {selectedVersion
8464
- ? `${shortDate(selectedVersion.createdAt)} · ${planVersionSurfaceLabel(selectedVersion)}`
8465
- : "Snapshot unavailable"}
8466
- </p>
8445
+ <IconHistory className="size-4 text-primary" />
8446
+ <span>Plan history</span>
8467
8447
  </>
8468
8448
  )}
8449
+ </SheetTitle>
8450
+ <SheetDescription className="sr-only">
8451
+ Browse saved plan versions and restore a previous snapshot.
8452
+ </SheetDescription>
8453
+ </SheetHeader>
8454
+ <Separator className="mt-3" />
8455
+
8456
+ {selectedVersionId ? (
8457
+ <div className="flex h-[calc(100%-60px)] min-h-0 flex-col">
8458
+ <div className="border-b border-border px-4 py-3">
8459
+ {versionQuery.isLoading ? (
8460
+ <div className="space-y-2">
8461
+ <Skeleton className="h-4 w-2/3" />
8462
+ <Skeleton className="h-3 w-1/3" />
8463
+ </div>
8464
+ ) : (
8465
+ <>
8466
+ <p className="truncate text-sm font-medium">
8467
+ {selectedVersion?.title || "Untitled plan"}
8468
+ </p>
8469
+ <p className="mt-0.5 text-[11px] text-muted-foreground">
8470
+ {selectedVersion
8471
+ ? `${shortDate(selectedVersion.createdAt)} · ${planVersionSurfaceLabel(selectedVersion)}`
8472
+ : "Snapshot unavailable"}
8473
+ </p>
8474
+ </>
8475
+ )}
8476
+ </div>
8477
+ <ScrollArea className="min-h-0 flex-1 bg-plan-document">
8478
+ {versionQuery.isLoading ? (
8479
+ <div className="space-y-3 p-4">
8480
+ <Skeleton className="h-48 w-full rounded-lg" />
8481
+ <Skeleton className="h-28 w-full rounded-lg" />
8482
+ <Skeleton className="h-28 w-full rounded-lg" />
8483
+ </div>
8484
+ ) : selectedVersion?.plan.content ? (
8485
+ <PlanContentRenderer
8486
+ content={selectedVersion.plan.content}
8487
+ fallbackTitle={selectedVersion.plan.title}
8488
+ fallbackBrief={selectedVersion.plan.brief}
8489
+ contentUpdatedAt={selectedVersion.plan.updatedAt}
8490
+ editingDisabled
8491
+ isRecap={selectedVersion.plan.kind === "recap"}
8492
+ planId={null}
8493
+ />
8494
+ ) : selectedVersion?.html ? (
8495
+ <iframe
8496
+ title="Plan version preview"
8497
+ srcDoc={selectedVersion.html}
8498
+ // Stored plan HTML is agent-authored and may carry
8499
+ // prompt-injected markup. Match the main document iframe
8500
+ // (search "allow-forms allow-scripts"): run scripts only in
8501
+ // an opaque origin — never allow-same-origin — so a malicious
8502
+ // snapshot cannot reach the app origin's cookies, DOM, or
8503
+ // actions.
8504
+ sandbox="allow-forms allow-scripts"
8505
+ className="h-[calc(100vh-142px)] w-full border-0 bg-background"
8506
+ />
8507
+ ) : (
8508
+ <div className="px-6 py-14 text-center text-sm text-muted-foreground">
8509
+ This snapshot has no previewable content.
8510
+ </div>
8511
+ )}
8512
+ </ScrollArea>
8513
+ {canRestore ? (
8514
+ <div className="border-t border-border p-3">
8515
+ <Button
8516
+ type="button"
8517
+ size="sm"
8518
+ className="w-full gap-1.5"
8519
+ onClick={() => void restoreVersionById(selectedVersionId)}
8520
+ disabled={
8521
+ restoreVersion.isPending || versionQuery.isLoading
8522
+ }
8523
+ >
8524
+ {restoreVersion.isPending ? (
8525
+ <IconLoader2 className="size-4 animate-spin" />
8526
+ ) : (
8527
+ <IconRestore className="size-4" />
8528
+ )}
8529
+ Restore this version
8530
+ </Button>
8531
+ <p className="mt-2 text-center text-[11px] text-muted-foreground">
8532
+ Your current version is saved to history first.
8533
+ </p>
8534
+ </div>
8535
+ ) : null}
8469
8536
  </div>
8470
- <ScrollArea className="min-h-0 flex-1 bg-plan-document">
8471
- {versionQuery.isLoading ? (
8472
- <div className="space-y-3 p-4">
8473
- <Skeleton className="h-48 w-full rounded-lg" />
8474
- <Skeleton className="h-28 w-full rounded-lg" />
8475
- <Skeleton className="h-28 w-full rounded-lg" />
8537
+ ) : (
8538
+ <ScrollArea className="h-[calc(100%-60px)]">
8539
+ {versionsQuery.isLoading ? (
8540
+ <div className="space-y-2 p-3">
8541
+ {Array.from({ length: 5 }).map((_, index) => (
8542
+ <Skeleton key={index} className="h-20 w-full rounded-lg" />
8543
+ ))}
8544
+ </div>
8545
+ ) : versions.length ? (
8546
+ <div className="p-2">
8547
+ {versions.map((version, index) => {
8548
+ // Compute a diff summary when both this version and its
8549
+ // predecessor have been loaded into the cache. Versions are
8550
+ // ordered newest-first, so index+1 is the older snapshot.
8551
+ // The oldest entry (no predecessor) shows "Initial version".
8552
+ const cache = versionDetailCache.current;
8553
+ const thisDetail = cache.get(version.id);
8554
+ const olderVersion = versions[index + 1];
8555
+ const olderDetail = olderVersion
8556
+ ? cache.get(olderVersion.id)
8557
+ : undefined;
8558
+ // Show a diff when: this version's detail is loaded AND
8559
+ // (it's the oldest OR the older neighbour's detail is loaded).
8560
+ const isOldest = index === versions.length - 1;
8561
+ const diffSummary =
8562
+ thisDetail && (isOldest || olderDetail)
8563
+ ? formatVersionDiffSummary(
8564
+ diffPlanVersions(
8565
+ {
8566
+ content: thisDetail.plan.content,
8567
+ sections: thisDetail.sections,
8568
+ html: thisDetail.html,
8569
+ },
8570
+ isOldest
8571
+ ? null
8572
+ : {
8573
+ content: olderDetail!.plan.content,
8574
+ sections: olderDetail!.sections,
8575
+ html: olderDetail!.html,
8576
+ },
8577
+ ),
8578
+ )
8579
+ : null;
8580
+
8581
+ return (
8582
+ <div
8583
+ key={version.id}
8584
+ className="group relative rounded-lg transition-colors hover:bg-accent"
8585
+ >
8586
+ <button
8587
+ type="button"
8588
+ onClick={() => setSelectedVersionId(version.id)}
8589
+ className="w-full rounded-lg px-3 py-2.5 text-left"
8590
+ >
8591
+ <div className="flex min-w-0 items-start gap-3">
8592
+ <div className="mt-1 flex size-7 shrink-0 items-center justify-center rounded-md border border-border bg-muted/45">
8593
+ <IconHistory className="size-4 text-muted-foreground" />
8594
+ </div>
8595
+ <div className="min-w-0 flex-1">
8596
+ <div className="flex min-w-0 items-center gap-2 pr-7">
8597
+ <p className="truncate text-sm font-medium">
8598
+ {version.title || "Untitled plan"}
8599
+ </p>
8600
+ <span className="shrink-0 text-[10px] text-muted-foreground">
8601
+ {planVersionSurfaceLabel(version)}
8602
+ </span>
8603
+ </div>
8604
+ <p className="mt-0.5 text-[11px] text-muted-foreground">
8605
+ {shortDate(version.createdAt)}
8606
+ {version.label ? ` · ${version.label}` : ""}
8607
+ </p>
8608
+ {diffSummary ? (
8609
+ <p className="mt-0.5 truncate text-[11px] text-muted-foreground/70">
8610
+ {diffSummary}
8611
+ </p>
8612
+ ) : version.preview ? (
8613
+ <p className="mt-1 line-clamp-2 text-[11px] leading-4 text-muted-foreground/80">
8614
+ {version.preview}
8615
+ </p>
8616
+ ) : null}
8617
+ </div>
8618
+ </div>
8619
+ </button>
8620
+ {canRestore ? (
8621
+ <div className="absolute right-2 top-2 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100">
8622
+ <DropdownMenu>
8623
+ <DropdownMenuTrigger asChild>
8624
+ <button
8625
+ type="button"
8626
+ className="flex size-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
8627
+ aria-label="Version actions"
8628
+ >
8629
+ <IconDots className="size-4" />
8630
+ </button>
8631
+ </DropdownMenuTrigger>
8632
+ <DropdownMenuContent align="end" className="w-52">
8633
+ <DropdownMenuItem
8634
+ onClick={(event) => {
8635
+ event.preventDefault();
8636
+ setRestoreCandidateId(version.id);
8637
+ }}
8638
+ >
8639
+ <IconRestore className="size-4" />
8640
+ Restore this version
8641
+ </DropdownMenuItem>
8642
+ </DropdownMenuContent>
8643
+ </DropdownMenu>
8644
+ </div>
8645
+ ) : null}
8646
+ </div>
8647
+ );
8648
+ })}
8476
8649
  </div>
8477
- ) : selectedVersion?.plan.content ? (
8478
- <PlanContentRenderer
8479
- content={selectedVersion.plan.content}
8480
- fallbackTitle={selectedVersion.plan.title}
8481
- fallbackBrief={selectedVersion.plan.brief}
8482
- contentUpdatedAt={selectedVersion.plan.updatedAt}
8483
- editingDisabled
8484
- isRecap={selectedVersion.plan.kind === "recap"}
8485
- planId={null}
8486
- />
8487
- ) : selectedVersion?.html ? (
8488
- <iframe
8489
- title="Plan version preview"
8490
- srcDoc={selectedVersion.html}
8491
- // Stored plan HTML is agent-authored and may carry
8492
- // prompt-injected markup. Match the main document iframe
8493
- // (search "allow-forms allow-scripts"): run scripts only in
8494
- // an opaque origin — never allow-same-origin — so a malicious
8495
- // snapshot cannot reach the app origin's cookies, DOM, or
8496
- // actions.
8497
- sandbox="allow-forms allow-scripts"
8498
- className="h-[calc(100vh-142px)] w-full border-0 bg-background"
8499
- />
8500
8650
  ) : (
8501
- <div className="px-6 py-14 text-center text-sm text-muted-foreground">
8502
- This snapshot has no previewable content.
8651
+ <div className="px-6 py-14 text-center">
8652
+ <IconHistory className="mx-auto mb-3 size-6 text-muted-foreground/60" />
8653
+ <p className="text-sm font-medium">No saved versions yet</p>
8654
+ <p className="mt-1 text-xs leading-5 text-muted-foreground">
8655
+ Versions are saved automatically before future plan edits.
8656
+ </p>
8503
8657
  </div>
8504
8658
  )}
8505
8659
  </ScrollArea>
8506
- {canRestore ? (
8507
- <div className="border-t border-border p-3">
8508
- <Button
8509
- type="button"
8510
- size="sm"
8511
- className="w-full gap-1.5"
8512
- onClick={() => void restoreSelectedVersion()}
8513
- disabled={restoreVersion.isPending || versionQuery.isLoading}
8514
- >
8515
- {restoreVersion.isPending ? (
8516
- <IconLoader2 className="size-4 animate-spin" />
8517
- ) : (
8518
- <IconRestore className="size-4" />
8519
- )}
8520
- Restore this version
8521
- </Button>
8522
- <p className="mt-2 text-center text-[11px] text-muted-foreground">
8523
- Your current version is saved to history first.
8524
- </p>
8525
- </div>
8526
- ) : null}
8527
- </div>
8528
- ) : (
8529
- <ScrollArea className="h-[calc(100%-60px)]">
8530
- {versionsQuery.isLoading ? (
8531
- <div className="space-y-2 p-3">
8532
- {Array.from({ length: 5 }).map((_, index) => (
8533
- <Skeleton key={index} className="h-20 w-full rounded-lg" />
8534
- ))}
8535
- </div>
8536
- ) : versions.length ? (
8537
- <div className="p-2">
8538
- {versions.map((version, index) => {
8539
- // Compute a diff summary when both this version and its
8540
- // predecessor have been loaded into the cache. Versions are
8541
- // ordered newest-first, so index+1 is the older snapshot.
8542
- // The oldest entry (no predecessor) shows "Initial version".
8543
- const cache = versionDetailCache.current;
8544
- const thisDetail = cache.get(version.id);
8545
- const olderVersion = versions[index + 1];
8546
- const olderDetail = olderVersion
8547
- ? cache.get(olderVersion.id)
8548
- : undefined;
8549
- // Show a diff when: this version's detail is loaded AND
8550
- // (it's the oldest OR the older neighbour's detail is loaded).
8551
- const isOldest = index === versions.length - 1;
8552
- const diffSummary =
8553
- thisDetail && (isOldest || olderDetail)
8554
- ? formatVersionDiffSummary(
8555
- diffPlanVersions(
8556
- {
8557
- content: thisDetail.plan.content,
8558
- sections: thisDetail.sections,
8559
- html: thisDetail.html,
8560
- },
8561
- isOldest
8562
- ? null
8563
- : {
8564
- content: olderDetail!.plan.content,
8565
- sections: olderDetail!.sections,
8566
- html: olderDetail!.html,
8567
- },
8568
- ),
8569
- )
8570
- : null;
8571
-
8572
- return (
8573
- <button
8574
- key={version.id}
8575
- type="button"
8576
- onClick={() => setSelectedVersionId(version.id)}
8577
- className="w-full rounded-lg px-3 py-2.5 text-left transition-colors hover:bg-accent"
8578
- >
8579
- <div className="flex min-w-0 items-start gap-3">
8580
- <div className="mt-1 flex size-7 shrink-0 items-center justify-center rounded-md border border-border bg-muted/45">
8581
- <IconHistory className="size-4 text-muted-foreground" />
8582
- </div>
8583
- <div className="min-w-0 flex-1">
8584
- <div className="flex min-w-0 items-center gap-2">
8585
- <p className="truncate text-sm font-medium">
8586
- {version.title || "Untitled plan"}
8587
- </p>
8588
- <span className="shrink-0 text-[10px] text-muted-foreground">
8589
- {planVersionSurfaceLabel(version)}
8590
- </span>
8591
- </div>
8592
- <p className="mt-0.5 text-[11px] text-muted-foreground">
8593
- {shortDate(version.createdAt)}
8594
- {version.label ? ` · ${version.label}` : ""}
8595
- </p>
8596
- {diffSummary ? (
8597
- <p className="mt-0.5 truncate text-[11px] text-muted-foreground/70">
8598
- {diffSummary}
8599
- </p>
8600
- ) : version.preview ? (
8601
- <p className="mt-1 line-clamp-2 text-[11px] leading-4 text-muted-foreground/80">
8602
- {version.preview}
8603
- </p>
8604
- ) : null}
8605
- </div>
8606
- </div>
8607
- </button>
8608
- );
8609
- })}
8610
- </div>
8611
- ) : (
8612
- <div className="px-6 py-14 text-center">
8613
- <IconHistory className="mx-auto mb-3 size-6 text-muted-foreground/60" />
8614
- <p className="text-sm font-medium">No saved versions yet</p>
8615
- <p className="mt-1 text-xs leading-5 text-muted-foreground">
8616
- Versions are saved automatically before future plan edits.
8617
- </p>
8618
- </div>
8619
- )}
8620
- </ScrollArea>
8621
- )}
8622
- </SheetContent>
8623
- </Sheet>
8660
+ )}
8661
+ </SheetContent>
8662
+ </Sheet>
8663
+ <AlertDialog
8664
+ open={Boolean(restoreCandidateId)}
8665
+ onOpenChange={(next) => {
8666
+ if (!next) setRestoreCandidateId(null);
8667
+ }}
8668
+ >
8669
+ <AlertDialogContent>
8670
+ <AlertDialogHeader>
8671
+ <AlertDialogTitle>Restore this version?</AlertDialogTitle>
8672
+ <AlertDialogDescription>
8673
+ This replaces the current plan with the snapshot
8674
+ {restoreCandidate
8675
+ ? ` from ${shortDate(restoreCandidate.createdAt)}`
8676
+ : ""}
8677
+ . Your current version is saved to history first, so you can undo
8678
+ this.
8679
+ </AlertDialogDescription>
8680
+ </AlertDialogHeader>
8681
+ <AlertDialogFooter>
8682
+ <AlertDialogCancel disabled={restoreVersion.isPending}>
8683
+ Cancel
8684
+ </AlertDialogCancel>
8685
+ <AlertDialogAction
8686
+ onClick={(event) => {
8687
+ event.preventDefault();
8688
+ void restoreVersionById(restoreCandidateId);
8689
+ }}
8690
+ disabled={restoreVersion.isPending}
8691
+ >
8692
+ {restoreVersion.isPending ? "Restoring…" : "Restore"}
8693
+ </AlertDialogAction>
8694
+ </AlertDialogFooter>
8695
+ </AlertDialogContent>
8696
+ </AlertDialog>
8697
+ </>
8624
8698
  );
8625
8699
  }
8626
8700
 
@@ -424,6 +424,17 @@ function sanitizeMaybeBlocks(blocks: unknown) {
424
424
  sanitizeMaybeBlocks((tab as Record<string, unknown>).blocks);
425
425
  }
426
426
  }
427
+ // `columns` is the recommended before/after recap primitive and nests child
428
+ // blocks (commonly wireframes). It must recurse like `tabs` does — otherwise
429
+ // a nested wireframe authored as a full HTML document never gets its
430
+ // scaffold stripped and the whole columns block degrades to an "Unsupported
431
+ // block" card at validation time.
432
+ if (record.type === "columns" && data && Array.isArray(data.columns)) {
433
+ for (const column of data.columns) {
434
+ if (!column || typeof column !== "object") continue;
435
+ sanitizeMaybeBlocks((column as Record<string, unknown>).blocks);
436
+ }
437
+ }
427
438
  }
428
439
  }
429
440
 
@@ -454,9 +465,29 @@ function preSanitizePlanContentInput(input: unknown): unknown {
454
465
  return content;
455
466
  }
456
467
 
468
+ /**
469
+ * Coerce a full HTML document into a bounded fragment. Wireframe, custom-html,
470
+ * and diagram blocks must be bounded fragments (the renderer owns the
471
+ * surrounding document, theme, and styling), so the schema rejects any value
472
+ * carrying document scaffolding. Agents frequently author one of these blocks
473
+ * as a standalone page anyway; rather than degrade the whole block to an
474
+ * "Unsupported block" card, drop the scaffold and keep the body content. The
475
+ * `<head>` is removed wholesale because its `<style>`/`<meta>`/`<link>` are
476
+ * renderer-owned and stripped elsewhere regardless. Fragments without
477
+ * scaffolding pass through untouched.
478
+ */
479
+ function stripDocumentScaffold(value: string): string {
480
+ if (!/<!doctype|<\s*\/?\s*(?:html|head|body)\b/i.test(value)) return value;
481
+ return value
482
+ .replace(/<!doctype[^>]*>/gi, "")
483
+ .replace(/<head\b[^>]*>[\s\S]*?<\/\s*head\s*>/gi, "")
484
+ .replace(/<\/?\s*(?:html|head|body)\b[^>]*>/gi, "")
485
+ .trim();
486
+ }
487
+
457
488
  /** Strip the dangerous surface from a stored custom-html / css string. */
458
489
  export function sanitizeCustomHtml(value: string): string {
459
- let out = value;
490
+ let out = stripDocumentScaffold(value);
460
491
  // Iterate element-stripping so nested / sequential cases collapse fully.
461
492
  for (let i = 0; i < 4; i += 1) {
462
493
  const next = out.replace(FORBIDDEN_ELEMENT, "");
@@ -479,7 +510,7 @@ export function sanitizeCustomHtml(value: string): string {
479
510
  }
480
511
 
481
512
  export function sanitizeDiagramHtml(value: string): string {
482
- let out = value;
513
+ let out = stripDocumentScaffold(value);
483
514
  for (let i = 0; i < 4; i += 1) {
484
515
  const next = out.replace(DIAGRAM_FORBIDDEN_ELEMENT, "");
485
516
  if (next === out) break;
@@ -615,6 +646,18 @@ function sanitizeBlock(block: PlanBlock): PlanBlock {
615
646
  },
616
647
  };
617
648
  }
649
+ if (block.type === "columns") {
650
+ return {
651
+ ...block,
652
+ data: {
653
+ ...block.data,
654
+ columns: block.data.columns.map((column) => ({
655
+ ...column,
656
+ blocks: column.blocks.map(sanitizeBlock),
657
+ })),
658
+ },
659
+ };
660
+ }
618
661
  return block;
619
662
  }
620
663
 
@@ -18,6 +18,7 @@ export declare class A2ATaskTimeoutError extends Error {
18
18
  export declare function signA2AToken(email: string, orgDomain?: string, orgSecret?: string, options?: {
19
19
  expiresIn?: string | number;
20
20
  preferGlobalSecret?: boolean;
21
+ audience?: string | string[];
21
22
  /**
22
23
  * Extra JWT claims to merge alongside `sub` / `org_domain`. Used by the
23
24
  * MCP connect flow to add a revocable `jti` and a `scope: "mcp-connect"`
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"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"}
@@ -35,7 +35,7 @@ export async function signA2AToken(email, orgDomain, orgSecret, options) {
35
35
  const appUrl = process.env.APP_URL ||
36
36
  process.env.BETTER_AUTH_URL ||
37
37
  "http://localhost:3000";
38
- return new jose.SignJWT({
38
+ const jwt = new jose.SignJWT({
39
39
  ...(options?.extraClaims ?? {}),
40
40
  // `sub` / `org_domain` are spread AFTER extraClaims so a caller-supplied
41
41
  // map can never override the verified identity claims.
@@ -45,8 +45,10 @@ export async function signA2AToken(email, orgDomain, orgSecret, options) {
45
45
  .setProtectedHeader({ alg: "HS256" })
46
46
  .setIssuer(appUrl)
47
47
  .setIssuedAt()
48
- .setExpirationTime(options?.expiresIn ?? "15m")
49
- .sign(new TextEncoder().encode(secret));
48
+ .setExpirationTime(options?.expiresIn ?? "15m");
49
+ if (options?.audience)
50
+ jwt.setAudience(options.audience);
51
+ return jwt.sign(new TextEncoder().encode(secret));
50
52
  }
51
53
  export class A2AClient {
52
54
  baseUrl;