@agent-native/core-corpus 0.208.0 → 0.208.1-nightly-20261014010003

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 (151) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  3. package/corpus/templates/analytics/app/lib/format-sql.ts +1 -1
  4. package/corpus/templates/analytics/changelog/2026-10-13-sql-dashboard-typed-filters.md +6 -0
  5. package/corpus/templates/analytics/evals/production-context.ts +1 -1
  6. package/corpus/templates/assets/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  7. package/corpus/templates/brain/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  8. package/corpus/templates/calendar/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  9. package/corpus/templates/chat/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  10. package/corpus/templates/clips/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  11. package/corpus/templates/clips/actions/finalize-recording.ts +12 -8
  12. package/corpus/templates/clips/app/components/lookback/recording-context-panel.tsx +68 -0
  13. package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +61 -3
  14. package/corpus/templates/clips/app/i18n/en-US.ts +4 -0
  15. package/corpus/templates/clips/app/lib/background-ai-error.ts +14 -0
  16. package/corpus/templates/clips/app/routes/_app.r.$recordingId.tsx +41 -15
  17. package/corpus/templates/clips/app/routes/record.tsx +1 -1
  18. package/corpus/templates/clips/app/routes/share.$shareId.tsx +1 -0
  19. package/corpus/templates/clips/changelog/2026-10-13-earlier-screen-time-appears-in-transcript-as-soon-as-clips-s.md +6 -0
  20. package/corpus/templates/clips/changelog/2026-10-13-earlier-screen-time-can-still-be-saved-when-audio-is-unavail.md +6 -0
  21. package/corpus/templates/clips/changelog/2026-10-13-earlier-screen-time-saves-with-available-audio-even-when-som.md +6 -0
  22. package/corpus/templates/clips/changelog/2026-10-13-recordings-export-even-when-some-segments-have-no-audio.md +6 -0
  23. package/corpus/templates/clips/changelog/2026-10-13-silence-removal-errors-explain-when-transcript-cannot-be-used.md +6 -0
  24. package/corpus/templates/clips/changelog/2026-10-13-silence-removal-offers-transcript-regeneration-when-timestam.md +6 -0
  25. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +350 -24
  26. package/corpus/templates/clips/desktop/src-tauri/src/rewind_clip.rs +174 -9
  27. package/corpus/templates/clips/server/lib/agent-views.ts +18 -2
  28. package/corpus/templates/clips/server/lib/clip-funnel-tracking.ts +56 -0
  29. package/corpus/templates/clips/server/lib/public-agent-context.ts +2 -0
  30. package/corpus/templates/clips/server/routes/api/view-event.post.ts +47 -5
  31. package/corpus/templates/content/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  32. package/corpus/templates/content/docs/product/capabilities/content.embed.surface.md +9 -4
  33. package/corpus/templates/content/docs/product/capabilities/content.revision.suggestions.md +9 -4
  34. package/corpus/templates/content/docs/product/encyclopedia.md +6 -6
  35. package/corpus/templates/content/docs/product/features/content.feature.capture-into-action.md +2 -2
  36. package/corpus/templates/content/docs/product/features/content.feature.collaborate-in-context.md +3 -3
  37. package/corpus/templates/content/docs/product/features/content.feature.durable-foundations.md +3 -3
  38. package/corpus/templates/content/docs/product/features/content.feature.move-without-starting-over.md +3 -3
  39. package/corpus/templates/content/docs/product/features/content.feature.review-changes-in-place.md +3 -3
  40. package/corpus/templates/content/docs/product/features/content.feature.work-on-content-inside-another-application.md +4 -4
  41. package/corpus/templates/content/docs/product/roadmap.md +12 -12
  42. package/corpus/templates/crm/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  43. package/corpus/templates/design/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  44. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +46 -7
  45. package/corpus/templates/design/actions/_design-tracking.ts +84 -0
  46. package/corpus/templates/design/actions/_generation-tracking.ts +150 -0
  47. package/corpus/templates/design/actions/add-session-replay-screenshots-to-board.ts +1 -0
  48. package/corpus/templates/design/actions/clone-creative-context-design-native.ts +9 -5
  49. package/corpus/templates/design/actions/create-design-from-template.ts +23 -9
  50. package/corpus/templates/design/actions/create-design-system.ts +2 -4
  51. package/corpus/templates/design/actions/create-design.ts +18 -10
  52. package/corpus/templates/design/actions/create-file.ts +2 -4
  53. package/corpus/templates/design/actions/create-journey-canvas.ts +1 -0
  54. package/corpus/templates/design/actions/duplicate-design.ts +13 -1
  55. package/corpus/templates/design/actions/edit-design.ts +2 -4
  56. package/corpus/templates/design/actions/export-coding-handoff.ts +14 -13
  57. package/corpus/templates/design/actions/export-html.ts +14 -13
  58. package/corpus/templates/design/actions/export-pdf.ts +5 -5
  59. package/corpus/templates/design/actions/export-png.ts +30 -14
  60. package/corpus/templates/design/actions/export-svg.ts +16 -13
  61. package/corpus/templates/design/actions/export-zip.ts +14 -13
  62. package/corpus/templates/design/actions/generate-design.ts +39 -43
  63. package/corpus/templates/design/actions/generate-home-suggestions.ts +3 -4
  64. package/corpus/templates/design/actions/get-design.ts +64 -20
  65. package/corpus/templates/design/actions/import-figma-frame.ts +1 -0
  66. package/corpus/templates/design/actions/open-visual-edit.ts +11 -7
  67. package/corpus/templates/design/actions/present-design-variants.ts +26 -9
  68. package/corpus/templates/design/actions/save-design-as-template.ts +2 -4
  69. package/corpus/templates/design/actions/update-design-system.ts +2 -4
  70. package/corpus/templates/design/app/components/design/LayersPanel.tsx +16 -20
  71. package/corpus/templates/design/app/components/design/TokensPanel.tsx +133 -106
  72. package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +9 -3
  73. package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +23 -15
  74. package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +5 -46
  75. package/corpus/templates/design/app/components/design/editor/LeftPanelSearchField.tsx +38 -0
  76. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +19 -12
  77. package/corpus/templates/design/app/components/design/inspector/color-picker-fill-field.tsx +4 -0
  78. package/corpus/templates/design/app/components/design/inspector/fill-field-reading.ts +5 -0
  79. package/corpus/templates/design/app/components/editor/HomeImportButton.tsx +20 -2
  80. package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +453 -353
  81. package/corpus/templates/design/app/components/visual-editor/review-canvas-state.ts +164 -4
  82. package/corpus/templates/design/app/global.css +18 -13
  83. package/corpus/templates/design/app/i18n/en-US.ts +1 -1
  84. package/corpus/templates/design/app/lib/design-export-tracking.ts +76 -0
  85. package/corpus/templates/design/app/lib/design-funnel-tracking.ts +328 -0
  86. package/corpus/templates/design/app/lib/design-import-file-picker.ts +136 -0
  87. package/corpus/templates/design/app/lib/design-import.ts +5 -1
  88. package/corpus/templates/design/app/lib/design-relay-tracking.ts +65 -0
  89. package/corpus/templates/design/app/pages/Index.tsx +48 -8
  90. package/corpus/templates/design/app/pages/design-editor/commands/copy-as-figma-svg.ts +22 -0
  91. package/corpus/templates/design/app/pages/design-editor/commands/copy-as-png.ts +78 -0
  92. package/corpus/templates/design/app/pages/design-editor/commands/copy-selection.ts +1 -0
  93. package/corpus/templates/design/app/pages/design-editor/commands/download-all-screens-pdf.ts +19 -0
  94. package/corpus/templates/design/app/pages/design-editor/commands/download-figma-svg.ts +99 -0
  95. package/corpus/templates/design/app/pages/design-editor/commands/download-pdf.ts +17 -0
  96. package/corpus/templates/design/app/pages/design-editor/commands/download-png.ts +69 -0
  97. package/corpus/templates/design/app/pages/design-editor/commands/download-svg.ts +27 -0
  98. package/corpus/templates/design/app/pages/design-editor/commands/paste-copied-screens.ts +34 -4
  99. package/corpus/templates/design/app/pages/design-editor/commands/paste-selection.ts +52 -6
  100. package/corpus/templates/design/app/pages/design-editor/commands/paste-view-position.ts +157 -0
  101. package/corpus/templates/design/app/pages/design-editor/design-editor-view.tsx +8 -10
  102. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-clipboard.tsx +10 -0
  103. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-export-and-handoff.ts +82 -102
  104. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-generation-and-access.ts +13 -0
  105. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-layout-and-structure.ts +4 -0
  106. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-screen-rendering.tsx +3 -3
  107. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-source-and-sync.ts +27 -8
  108. package/corpus/templates/design/app/pages/design-editor/left-sidebar-width.ts +3 -8
  109. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +11 -0
  110. package/corpus/templates/design/app/pages/design-editor/view/left-sidebar.tsx +1 -2
  111. package/corpus/templates/design/app/pages/design-editor/view/overview-canvas.tsx +3 -3
  112. package/corpus/templates/design/app/pages/design-editor/view/single-screen-canvas.tsx +2 -2
  113. package/corpus/templates/design/app/root.tsx +2 -0
  114. package/corpus/templates/design/changelog/2026-10-13-comment-pins-no-longer-show-in-interact-mode-or-paint-over-t.md +6 -0
  115. package/corpus/templates/design/changelog/2026-10-13-fill-and-effect-rows-keep-the-reorder-handle-outside-the-fie.md +6 -0
  116. package/corpus/templates/design/changelog/2026-10-13-left-panels-keep-one-width-tokens-search-and-rows-match-laye.md +6 -0
  117. package/corpus/templates/design/changelog/2026-10-13-pasting-a-copied-layer-or-screen-after-panning-away-now-land.md +6 -0
  118. package/corpus/templates/design/changelog/2026-10-13-selecting-a-plain-frame-no-longer-shows-margin-handles-aroun.md +6 -0
  119. package/corpus/templates/design/changelog/2026-10-13-share-panel-uses-the-compact-underline-tab-design-shared-acr.md +6 -0
  120. package/corpus/templates/design/server/lib/design-export-tracking.ts +101 -0
  121. package/corpus/templates/design/server/lib/design-tracking.ts +89 -0
  122. package/corpus/templates/design/server/routes/api/session-replay-storyboard.post.ts +1 -0
  123. package/corpus/templates/design/shared/prompt-length-bucket.ts +9 -0
  124. package/corpus/templates/design/shared/spacing-handle-rule.ts +31 -0
  125. package/corpus/templates/dispatch/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  126. package/corpus/templates/forms/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  127. package/corpus/templates/mail/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  128. package/corpus/templates/plan/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  129. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +4 -2
  130. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +4 -0
  131. package/corpus/templates/slides/.agents/skills/slide-editing/references/style-only-edits.md +6 -3
  132. package/corpus/templates/slides/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
  133. package/corpus/templates/slides/actions/patch-deck.ts +89 -9
  134. package/corpus/templates/slides/actions/update-slide.ts +3 -81
  135. package/corpus/templates/slides/app/components/editor/MissingDeckAccessPane.tsx +19 -1
  136. package/corpus/templates/slides/app/components/editor/QuestionFlow.tsx +21 -15
  137. package/corpus/templates/slides/app/context/DeckContext.tsx +9 -0
  138. package/corpus/templates/slides/app/hooks/use-agent-generating.ts +24 -5
  139. package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
  140. package/corpus/templates/slides/app/lib/generation-state.ts +107 -0
  141. package/corpus/templates/slides/app/pages/DeckEditor.tsx +225 -21
  142. package/corpus/templates/slides/app/pages/Index.tsx +1 -0
  143. package/corpus/templates/slides/changelog/2026-10-13-choosing-a-single-direction-now-continues-slide-generation-a.md +6 -0
  144. package/corpus/templates/slides/changelog/2026-10-13-deck-creation-errors-disappear-after-the-slides-are-edited-t.md +6 -0
  145. package/corpus/templates/slides/changelog/2026-10-13-failed-deck-generations-keep-your-original-prompt-so-you-can.md +6 -0
  146. package/corpus/templates/slides/changelog/2026-10-13-if-slide-creation-fails-you-can-see-your-original-request-be.md +6 -0
  147. package/corpus/templates/slides/changelog/2026-10-13-the-agent-now-fixes-colors-and-other-small-style-issues-acro.md +6 -0
  148. package/corpus/templates/slides/server/lib/slide-content-patch.ts +77 -0
  149. package/corpus/templates/slides/server/plugins/agent-chat.ts +2 -2
  150. package/corpus/templates/slides/shared/deck-write.ts +3 -1
  151. package/package.json +1 -1
package/corpus/README.md CHANGED
@@ -32,4 +32,4 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core-corpus/corpu
32
32
 
33
33
  ## Generated Counts
34
34
 
35
- - template files: 12209
35
+ - template files: 12292
@@ -0,0 +1,10 @@
1
+ // AUTO-GENERATED by @agent-native/core deploy build
2
+ import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
3
+
4
+ const pluginStems = ["agent-chat","analytics-alert-jobs","analytics-rollup-backfill-jobs","auth","collab","config","core-routes","creative-context","dashboard-report-jobs","db","feature-flags","labs","onboarding","otel","session-replay-retention-jobs","transactional-emails","uptime-monitor-jobs"];
5
+
6
+ export default function markBuildDiscoveredPlugins(nitroApp) {
7
+ for (const stem of pluginStems) {
8
+ markDefaultPluginProvided(nitroApp, stem);
9
+ }
10
+ }
@@ -2,7 +2,7 @@ import { format, type SqlLanguage } from "sql-formatter";
2
2
 
3
3
  import type { DataSourceType } from "@/pages/adhoc/sql-dashboard/types";
4
4
 
5
- const TEMPLATE_PARAM_REGEX = String.raw`\{\{[?/]?[A-Za-z_][A-Za-z0-9_]*\}\}`;
5
+ const TEMPLATE_PARAM_REGEX = String.raw`\{\{[?/]?[A-Za-z_][A-Za-z0-9_]*(?::[A-Za-z_][A-Za-z0-9_]*)?\}\}`;
6
6
 
7
7
  function languageForSource(source: DataSourceType): SqlLanguage | null {
8
8
  if (source === "bigquery") return "bigquery";
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-10-13
4
+ ---
5
+
6
+ SQL dashboards preserve typed filters when formatting queries.
@@ -74,7 +74,7 @@ export function buildAnalyticsPromptContext(
74
74
  references.prefetchStatus === "timed_out" ? "timed out" : "failed";
75
75
  const subject =
76
76
  candidates.length > 0 ? "Some preloaded context" : "Preloaded context";
77
- prompt += `\n\n<context-note>${subject} was unavailable this turn (${reason}); search for anything relevant with the available tools before answering.</context-note>`;
77
+ prompt += `\n\n<context-note>${subject} was unavailable this turn (${reason}); if the request depends on workspace knowledge, such as prior work, team docs, brand defaults, or people, search for it with the available tools before answering; otherwise continue without it.</context-note>`;
78
78
  }
79
79
  return prompt;
80
80
  }
@@ -0,0 +1,10 @@
1
+ // AUTO-GENERATED by @agent-native/core deploy build
2
+ import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
3
+
4
+ const pluginStems = ["agent-chat","auth","creative-context","db","labs","onboarding","otel"];
5
+
6
+ export default function markBuildDiscoveredPlugins(nitroApp) {
7
+ for (const stem of pluginStems) {
8
+ markDefaultPluginProvided(nitroApp, stem);
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ // AUTO-GENERATED by @agent-native/core deploy build
2
+ import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
3
+
4
+ const pluginStems = ["agent-chat","auth","brain-jobs","core-routes","db","otel"];
5
+
6
+ export default function markBuildDiscoveredPlugins(nitroApp) {
7
+ for (const stem of pluginStems) {
8
+ markDefaultPluginProvided(nitroApp, stem);
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ // AUTO-GENERATED by @agent-native/core deploy build
2
+ import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
3
+
4
+ const pluginStems = ["agent-chat","auth","core-routes","db","event-rules","oauth-refresh","otel","transactional-emails"];
5
+
6
+ export default function markBuildDiscoveredPlugins(nitroApp) {
7
+ for (const stem of pluginStems) {
8
+ markDefaultPluginProvided(nitroApp, stem);
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ // AUTO-GENERATED by @agent-native/core deploy build
2
+ import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
3
+
4
+ const pluginStems = ["agent-chat","auth","otel"];
5
+
6
+ export default function markBuildDiscoveredPlugins(nitroApp) {
7
+ for (const stem of pluginStems) {
8
+ markDefaultPluginProvided(nitroApp, stem);
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ // AUTO-GENERATED by @agent-native/core deploy build
2
+ import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
3
+
4
+ const pluginStems = ["agent-chat","auth","calendar-jobs","config","core-routes","db","feature-flags","labs","onboarding","onboarding-calendar","otel","transactional-email-catalog"];
5
+
6
+ export default function markBuildDiscoveredPlugins(nitroApp) {
7
+ for (const stem of pluginStems) {
8
+ markDefaultPluginProvided(nitroApp, stem);
9
+ }
10
+ }
@@ -2286,14 +2286,18 @@ export default defineAction({
2286
2286
  expectedValue: processingUploadState,
2287
2287
  nextValue: waitingStorageState,
2288
2288
  },
2289
- {
2290
- key: mediaVerificationStateKey(id),
2291
- expectedValue:
2292
- verificationStateRaw && typeof verificationStateRaw === "object"
2293
- ? (verificationStateRaw as Record<string, unknown>)
2294
- : null,
2295
- nextValue: null,
2296
- },
2289
+ ...(verificationStateRaw && typeof verificationStateRaw === "object"
2290
+ ? [
2291
+ {
2292
+ key: mediaVerificationStateKey(id),
2293
+ expectedValue: verificationStateRaw as Record<
2294
+ string,
2295
+ unknown
2296
+ >,
2297
+ nextValue: null,
2298
+ },
2299
+ ]
2300
+ : []),
2297
2301
  ]);
2298
2302
  if (!waitingStoragePublished) {
2299
2303
  throw new Error(
@@ -3,12 +3,16 @@ import { appBasePath } from "@agent-native/core/client/api-path";
3
3
  import {
4
4
  useActionMutation,
5
5
  useActionQuery,
6
+ useDbSync,
7
+ useSession,
6
8
  } from "@agent-native/core/client/hooks";
7
9
  import { useT } from "@agent-native/core/client/i18n";
8
10
  import { useLabState } from "@agent-native/core/client/labs";
9
11
  import { CLIPS_LOOKBACK_CONTEXT } from "@shared/labs";
10
12
  import { IconArrowsMaximize, IconTrash } from "@tabler/icons-react";
13
+ import { useQueryClient } from "@tanstack/react-query";
11
14
  import { type ReactNode, useEffect, useState } from "react";
15
+ import { useLocation } from "react-router";
12
16
  import { toast } from "sonner";
13
17
 
14
18
  import {
@@ -43,6 +47,19 @@ import {
43
47
  } from "./recording-context-model";
44
48
 
45
49
  const CONTEXT_POLL_MS = 3000;
50
+ const CONTEXT_SYNC_ACTIONS = new Set([
51
+ "request-recording-context",
52
+ "update-recording-context",
53
+ "set-recording-context-window",
54
+ "remove-recording-context",
55
+ ]);
56
+
57
+ export function isAuthenticatedRecordingPath(
58
+ pathname: string,
59
+ authenticated: boolean,
60
+ ): boolean {
61
+ return authenticated && /(?:^|\/)r\/[^/]+$/.test(pathname);
62
+ }
46
63
 
47
64
  // Same route the editor and the Rewind extension use for a recording's own video.
48
65
  export function contextVideoSrc(mediaRecordingId: string): string {
@@ -76,6 +93,31 @@ export function RecordingContextSection({
76
93
  recordingId: string | undefined;
77
94
  }) {
78
95
  const lab = useLabState(CLIPS_LOOKBACK_CONTEXT);
96
+ const location = useLocation();
97
+ const { session } = useSession();
98
+ const queryClient = useQueryClient();
99
+ useDbSync({
100
+ queryClient,
101
+ realtime:
102
+ isAuthenticatedRecordingPath(location.pathname, !!session) &&
103
+ lab.enabled &&
104
+ recordingId
105
+ ? {
106
+ reason: "desktop finishes earlier screen time",
107
+ }
108
+ : undefined,
109
+ actionInvalidatePredicate: (query, events) =>
110
+ query.queryKey[0] === "action" &&
111
+ query.queryKey[1] === "list-recording-context" &&
112
+ (query.queryKey[2] as { recordingId?: unknown } | undefined)
113
+ ?.recordingId === recordingId &&
114
+ events.some(
115
+ (event) =>
116
+ event.source === "action" &&
117
+ typeof event.key === "string" &&
118
+ CONTEXT_SYNC_ACTIONS.has(event.key),
119
+ ),
120
+ });
79
121
  const itemsQuery = useRecordingContextItems(recordingId, lab.enabled);
80
122
  const { isError, error } = itemsQuery;
81
123
  useEffect(() => {
@@ -171,6 +213,7 @@ function ContextItemCard({
171
213
  const [largerOpen, setLargerOpen] = useState(false);
172
214
  const [removeOpen, setRemoveOpen] = useState(false);
173
215
  const removeContext = useActionMutation("remove-recording-context");
216
+ const retryContext = useActionMutation("set-recording-context-window");
174
217
  const label = item.label?.trim() || t("lookbackContext.label");
175
218
  const windowText = t("lookbackContext.window", {
176
219
  start: formatClock(0),
@@ -197,6 +240,20 @@ function ContextItemCard({
197
240
  );
198
241
  }
199
242
 
243
+ function retry() {
244
+ retryContext.mutate(
245
+ {
246
+ id: item.id,
247
+ startedAt: item.startedAt,
248
+ endedAt: item.endedAt,
249
+ },
250
+ {
251
+ onSuccess: () => toast.success(t("lookbackContext.savingEarlierTime")),
252
+ onError: () => toast.error(t("lookbackContext.editFailed")),
253
+ },
254
+ );
255
+ }
256
+
200
257
  return (
201
258
  <div className="flex flex-col gap-2">
202
259
  <div className="flex items-center justify-between gap-2">
@@ -207,6 +264,17 @@ function ContextItemCard({
207
264
  </p>
208
265
  </div>
209
266
  <div className="flex shrink-0 items-center gap-1">
267
+ {item.status === "failed" ? (
268
+ <Button
269
+ type="button"
270
+ variant="outline"
271
+ size="sm"
272
+ disabled={retryContext.isPending}
273
+ onClick={retry}
274
+ >
275
+ {t("lookbackContext.retry")}
276
+ </Button>
277
+ ) : null}
210
278
  {src ? (
211
279
  <Button
212
280
  type="button"
@@ -1,5 +1,9 @@
1
1
  import { agentNativePath } from "@agent-native/core/client/api-path";
2
2
  import { useT } from "@agent-native/core/client/i18n";
3
+ import {
4
+ createOnboardingCorrelationId,
5
+ trackOnboardingEvent,
6
+ } from "@agent-native/core/client/onboarding/use-onboarding";
3
7
  import {
4
8
  BuilderConnectPopover,
5
9
  hasBuilderOAuthCredential,
@@ -26,6 +30,24 @@ import {
26
30
  // cancel belongs to something else.
27
31
  const CANCELLED_SETUP_RECOVERY_MS = 60_000;
28
32
 
33
+ // The S3 path finishes in settings, outside this card, so only the choice is
34
+ // recorded here; a later `recording_started.storage_connected` shows whether
35
+ // it landed.
36
+ function trackStorageStep(
37
+ name:
38
+ | "onboarding_step_viewed"
39
+ | "onboarding_step_completed"
40
+ | "onboarding_step_skipped"
41
+ | "onboarding_method_clicked",
42
+ properties: Record<string, unknown>,
43
+ ): void {
44
+ try {
45
+ trackOnboardingEvent(name, { step_id: "file-storage", ...properties });
46
+ } catch (err) {
47
+ console.warn(`[storage-setup] ${name} tracking failed:`, err);
48
+ }
49
+ }
50
+
29
51
  export interface StorageSetupCardProps {
30
52
  onConfigured: () => void | Promise<void>;
31
53
  onSkip?: () => void;
@@ -70,6 +92,7 @@ export function StorageSetupCard({
70
92
  const visibilityHandlerRef = useRef<(() => void) | null>(null);
71
93
  const connectRequestedRef = useRef(false);
72
94
  const connectIntentExpiresAtRef = useRef<number | null>(null);
95
+ const [stepViewId] = useState(createOnboardingCorrelationId);
73
96
 
74
97
  const clearConfiguredTimeout = useCallback(() => {
75
98
  if (configuredTimeoutRef.current !== null) {
@@ -146,6 +169,11 @@ export function StorageSetupCard({
146
169
  stop();
147
170
  setConnecting(false);
148
171
  setConnected(true);
172
+ trackStorageStep("onboarding_step_completed", {
173
+ flow: connectSource,
174
+ step_view_id: stepViewId,
175
+ method_id: "builder",
176
+ });
149
177
  clearConfiguredTimeout();
150
178
  configuredTimeoutRef.current = setTimeout(() => {
151
179
  configuredTimeoutRef.current = null;
@@ -177,7 +205,14 @@ export function StorageSetupCard({
177
205
  if (!document.hidden) void tick();
178
206
  };
179
207
  document.addEventListener("visibilitychange", visibilityHandlerRef.current);
180
- }, [clearConfiguredTimeout, onConfigured, stopVisibilityHandler, t]);
208
+ }, [
209
+ clearConfiguredTimeout,
210
+ connectSource,
211
+ onConfigured,
212
+ stepViewId,
213
+ stopVisibilityHandler,
214
+ t,
215
+ ]);
181
216
 
182
217
  const handleBuilderConnected = useCallback(() => {
183
218
  if (!connectRequestedRef.current) return;
@@ -235,12 +270,17 @@ export function StorageSetupCard({
235
270
  connectRequestedRef.current = true;
236
271
  connectIntentExpiresAtRef.current = null;
237
272
  setStatusIssue(null);
273
+ trackStorageStep("onboarding_method_clicked", {
274
+ flow: connectSource,
275
+ step_view_id: stepViewId,
276
+ method_id: "builder",
277
+ });
238
278
  builderConnect.start({
239
279
  provisionAccount,
240
280
  scope: builderConnectionScope,
241
281
  });
242
282
  },
243
- [builderConnectionScope, builderConnect.start],
283
+ [builderConnectionScope, builderConnect.start, connectSource, stepViewId],
244
284
  );
245
285
  const handleBuilderCancel = useCallback(() => {
246
286
  connectIntentExpiresAtRef.current =
@@ -249,8 +289,12 @@ export function StorageSetupCard({
249
289
  }, [builderConnect.cancel]);
250
290
  const handleSkip = useCallback(() => {
251
291
  clearConfiguredTimeout();
292
+ trackStorageStep("onboarding_step_skipped", {
293
+ flow: connectSource,
294
+ step_view_id: stepViewId,
295
+ });
252
296
  onSkip?.();
253
- }, [clearConfiguredTimeout, onSkip]);
297
+ }, [clearConfiguredTimeout, connectSource, onSkip, stepViewId]);
254
298
  const builderConnectErrorMessage = builderConnect.error
255
299
  ? builderConnect.errorKind === "launch"
256
300
  ? t("storageSetup.builderConnectPopupError")
@@ -265,6 +309,13 @@ export function StorageSetupCard({
265
309
  const builderConnecting = builderConnect.connecting;
266
310
  const actionConnecting = connecting || builderConnecting;
267
311
 
312
+ useEffect(() => {
313
+ trackStorageStep("onboarding_step_viewed", {
314
+ flow: connectSource,
315
+ step_view_id: stepViewId,
316
+ });
317
+ }, [connectSource, stepViewId]);
318
+
268
319
  useEffect(() => {
269
320
  mountedRef.current = true;
270
321
  return () => {
@@ -320,6 +371,13 @@ export function StorageSetupCard({
320
371
  <Button asChild variant="secondary" className="w-full">
321
372
  <a
322
373
  href={storageSetupHref}
374
+ onClick={() =>
375
+ trackStorageStep("onboarding_method_clicked", {
376
+ flow: connectSource,
377
+ step_view_id: stepViewId,
378
+ method_id: "s3",
379
+ })
380
+ }
323
381
  {...(openSettingsInNewTab
324
382
  ? { target: "_blank", rel: "noopener noreferrer" }
325
383
  : {})}
@@ -242,6 +242,10 @@ const messages = {
242
242
  transcriptionCompleted: "Transcription complete",
243
243
  transcriptNotReady: "Transcript is not ready yet",
244
244
  tryAfterTranscription: "Try again after transcription finishes.",
245
+ silenceTranscriptUnavailableTitle:
246
+ "This transcript can't be used to remove silences",
247
+ silenceTranscriptUnavailableDescription:
248
+ "Try generating a new transcript, then remove silences again.",
245
249
  titleGenerationQueued: "Generating title…",
246
250
  descriptionQueued: "Generating description…",
247
251
  chapterQueued: "Generating chapters…",
@@ -0,0 +1,14 @@
1
+ import type { ClipsAiRequestKind } from "@shared/ai-request-status";
2
+
3
+ export function shouldOfferTranscriptRegeneration(
4
+ kind: ClipsAiRequestKind | undefined,
5
+ errorCode: unknown,
6
+ recordingId: string | undefined,
7
+ ): boolean {
8
+ return (
9
+ kind === "remove-silences" &&
10
+ Boolean(recordingId) &&
11
+ (errorCode === "transcript_unreadable" ||
12
+ errorCode === "timestamped_transcript_required")
13
+ );
14
+ }
@@ -158,6 +158,7 @@ import { useSonnerLifecycleToast } from "@/hooks/use-sonner-lifecycle-toast";
158
158
  import { useUnviewedDebugEventCount } from "@/hooks/use-unviewed-debug-event-count";
159
159
  import { useViewTracking } from "@/hooks/use-view-tracking";
160
160
  import enMessages from "@/i18n/en-US";
161
+ import { shouldOfferTranscriptRegeneration } from "@/lib/background-ai-error";
161
162
  import { withMediaVersion } from "@/lib/media-url";
162
163
  import { parsePlaybackSpeed } from "@/lib/playback-speed";
163
164
  import {
@@ -1665,21 +1666,45 @@ export default function RecordingPage() {
1665
1666
  const errorCode = (err as Error & { errorCode?: unknown }).errorCode;
1666
1667
  activeAiRequestRef.current = null;
1667
1668
  cancelCompletionCue();
1668
- failAiRequestToast(t("recordingPage.aiRequestFailed"), {
1669
- description:
1670
- errorCode === "edits_unreadable"
1671
- ? t("recordingPage.silenceEditsUnreadable")
1672
- : (actionErrorMessage(err) ?? t("recordingPage.tryAgainMoment")),
1673
- ...(retryKind === "remove-filler-words" || retryKind === "remove-silences"
1674
- ? {
1675
- action: {
1676
- label: t("agentChat.common.retry"),
1677
- onClick: () => retryAiRequestRef.current?.(retryKind),
1678
- },
1679
- }
1680
- : {}),
1681
- duration: Number.POSITIVE_INFINITY,
1682
- });
1669
+ const transcriptNeedsRegeneration = shouldOfferTranscriptRegeneration(
1670
+ retryKind,
1671
+ errorCode,
1672
+ recording?.id,
1673
+ );
1674
+ failAiRequestToast(
1675
+ transcriptNeedsRegeneration
1676
+ ? t("recordingPage.silenceTranscriptUnavailableTitle")
1677
+ : t("recordingPage.aiRequestFailed"),
1678
+ {
1679
+ description: transcriptNeedsRegeneration
1680
+ ? t("recordingPage.silenceTranscriptUnavailableDescription")
1681
+ : errorCode === "edits_unreadable"
1682
+ ? t("recordingPage.silenceEditsUnreadable")
1683
+ : (actionErrorMessage(err) ?? t("recordingPage.tryAgainMoment")),
1684
+ ...(transcriptNeedsRegeneration
1685
+ ? {
1686
+ action: {
1687
+ label: t("transcriptPanel.regenerate"),
1688
+ onClick: () =>
1689
+ requestTranscriptWithLifecycle({
1690
+ recordingId: recording!.id,
1691
+ force: true,
1692
+ regenerate: true,
1693
+ }),
1694
+ },
1695
+ }
1696
+ : retryKind === "remove-filler-words" ||
1697
+ retryKind === "remove-silences"
1698
+ ? {
1699
+ action: {
1700
+ label: t("agentChat.common.retry"),
1701
+ onClick: () => retryAiRequestRef.current?.(retryKind),
1702
+ },
1703
+ }
1704
+ : {}),
1705
+ duration: Number.POSITIVE_INFINITY,
1706
+ },
1707
+ );
1683
1708
  };
1684
1709
  const requestTranscript = useActionMutation("request-transcript" as any, {
1685
1710
  onSuccess: (result: any) => {
@@ -2247,6 +2272,7 @@ export default function RecordingPage() {
2247
2272
  </div>
2248
2273
  ) : (
2249
2274
  <StorageSetupCard
2275
+ connectSource="clips_recording_page_storage_setup_card"
2250
2276
  title={
2251
2277
  loomStorageSetupFailure
2252
2278
  ? t("recordingPage.connectStorageImportLoomTitle")
@@ -4365,7 +4365,7 @@ export default function RecordRoute() {
4365
4365
  connectedDescription={t(
4366
4366
  "recordRoute.storageConnectedReopeningRecorder",
4367
4367
  )}
4368
- connectSource="clips_record_storage_setup_card"
4368
+ connectSource="clips_record_error_storage_setup_card"
4369
4369
  connectFlow="record"
4370
4370
  />
4371
4371
  </div>
@@ -1491,6 +1491,7 @@ export default function ShareRoute() {
1491
1491
  {storageSetupFailure && canManageStorage ? (
1492
1492
  <div className="mb-4 w-full">
1493
1493
  <StorageSetupCard
1494
+ connectSource="clips_share_page_storage_setup_card"
1494
1495
  title={t("sharePage.connectStorageFinishSaving")}
1495
1496
  description={t("sharePage.chooseStorageCheck")}
1496
1497
  connectedDescription={t("sharePage.storageConnectedChecking")}
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-10-13
4
+ ---
5
+
6
+ Earlier screen time appears in Transcript as soon as Clips saves it
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-10-13
4
+ ---
5
+
6
+ Earlier screen time can still be saved when audio is unavailable, and failed saves can be retried.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-10-13
4
+ ---
5
+
6
+ Earlier screen time saves with available audio even when some tracks are missing.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-10-13
4
+ ---
5
+
6
+ Recordings export even when some segments have no audio.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-10-13
4
+ ---
5
+
6
+ Silence-removal errors now explain when a transcript can't be used.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-10-13
4
+ ---
5
+
6
+ Silence removal offers transcript regeneration when timestamps are missing.