@agent-native/core 0.79.6 → 0.79.9

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 (97) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +19 -0
  3. package/corpus/core/docs/content/locales/zh-TW/durable-background-runs.md +74 -0
  4. package/corpus/core/package.json +1 -1
  5. package/corpus/core/src/agent/production-agent.ts +0 -93
  6. package/corpus/core/src/agent/run-manager.ts +9 -1
  7. package/corpus/core/src/client/agent-chat-adapter.ts +24 -16
  8. package/corpus/core/src/client/session-replay.ts +67 -13
  9. package/corpus/core/src/onboarding/default-steps.ts +3 -3
  10. package/corpus/core/src/server/agent-chat-plugin.ts +82 -162
  11. package/corpus/core/src/server/agent-run-context.ts +204 -0
  12. package/corpus/core/src/server/credential-provider.ts +20 -4
  13. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +14 -4
  14. package/corpus/templates/analytics/changelog/2026-06-26-session-replay-uploads-now-accept-compressed-payloads-so-lar.md +6 -0
  15. package/corpus/templates/analytics/changelog/2026-06-26-sql-chart-tooltips-now-stay-stable-while-moving-across-dense.md +6 -0
  16. package/corpus/templates/analytics/server/handlers/session-replay.ts +56 -8
  17. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +1 -1
  18. package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +44 -16
  19. package/corpus/templates/clips/app/i18n/ar-SA.ts +12 -9
  20. package/corpus/templates/clips/app/i18n/de-DE.ts +12 -9
  21. package/corpus/templates/clips/app/i18n/en-US.ts +19 -16
  22. package/corpus/templates/clips/app/i18n/es-ES.ts +12 -9
  23. package/corpus/templates/clips/app/i18n/fr-FR.ts +12 -9
  24. package/corpus/templates/clips/app/i18n/hi-IN.ts +13 -9
  25. package/corpus/templates/clips/app/i18n/ja-JP.ts +12 -9
  26. package/corpus/templates/clips/app/i18n/ko-KR.ts +12 -9
  27. package/corpus/templates/clips/app/i18n/pt-BR.ts +12 -9
  28. package/corpus/templates/clips/app/i18n/zh-CN.ts +19 -14
  29. package/corpus/templates/clips/app/i18n/zh-TW.ts +19 -14
  30. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +7 -0
  31. package/corpus/templates/clips/app/routes/record.tsx +2 -2
  32. package/corpus/templates/clips/changelog/2026-06-26-desktop-recordings-recover-more-reliably-when-macos-reports-.md +6 -0
  33. package/corpus/templates/clips/changelog/2026-06-26-slack-unfurls-now-recognize-recording-dashboard-links-pasted.md +6 -0
  34. package/corpus/templates/clips/changelog/2026-06-26-storage-setup-now-explains-why-clips-needs-connected-storage.md +6 -0
  35. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  36. package/corpus/templates/clips/chrome-extension/src/background.ts +24 -3
  37. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +28 -2
  38. package/corpus/templates/clips/chrome-extension/src/popup.html +16 -0
  39. package/corpus/templates/clips/chrome-extension/src/popup.ts +59 -7
  40. package/corpus/templates/clips/chrome-extension/src/sentry.ts +28 -1
  41. package/corpus/templates/clips/chrome-extension/src/styles.css +74 -0
  42. package/corpus/templates/clips/desktop/src/app.tsx +85 -18
  43. package/corpus/templates/clips/desktop/src/styles.css +55 -0
  44. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +88 -51
  45. package/corpus/templates/clips/desktop/src-tauri/src/native_speech.rs +12 -3
  46. package/corpus/templates/clips/server/lib/slack-unfurls.ts +5 -2
  47. package/corpus/templates/slides/actions/_app-url.ts +1 -1
  48. package/corpus/templates/slides/changelog/2026-06-26-deck-links-now-use-the-workspace-gateway-when-available-so-g.md +6 -0
  49. package/dist/agent/production-agent.d.ts.map +1 -1
  50. package/dist/agent/production-agent.js +0 -79
  51. package/dist/agent/production-agent.js.map +1 -1
  52. package/dist/agent/run-manager.d.ts.map +1 -1
  53. package/dist/agent/run-manager.js +12 -1
  54. package/dist/agent/run-manager.js.map +1 -1
  55. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  56. package/dist/client/agent-chat-adapter.js +15 -8
  57. package/dist/client/agent-chat-adapter.js.map +1 -1
  58. package/dist/client/session-replay.d.ts.map +1 -1
  59. package/dist/client/session-replay.js +55 -14
  60. package/dist/client/session-replay.js.map +1 -1
  61. package/dist/collab/awareness.d.ts +2 -2
  62. package/dist/collab/awareness.d.ts.map +1 -1
  63. package/dist/collab/routes.d.ts +2 -2
  64. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  65. package/dist/notifications/routes.d.ts +1 -1
  66. package/dist/observability/routes.d.ts +7 -7
  67. package/dist/onboarding/default-steps.js +3 -3
  68. package/dist/onboarding/default-steps.js.map +1 -1
  69. package/dist/progress/routes.d.ts +1 -1
  70. package/dist/resources/handlers.d.ts +3 -3
  71. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  72. package/dist/server/agent-chat-plugin.js +69 -154
  73. package/dist/server/agent-chat-plugin.js.map +1 -1
  74. package/dist/server/agent-engine-api-key-route.d.ts +2 -2
  75. package/dist/server/agent-run-context.d.ts +35 -0
  76. package/dist/server/agent-run-context.d.ts.map +1 -0
  77. package/dist/server/agent-run-context.js +137 -0
  78. package/dist/server/agent-run-context.js.map +1 -0
  79. package/dist/server/credential-provider.d.ts.map +1 -1
  80. package/dist/server/credential-provider.js +15 -4
  81. package/dist/server/credential-provider.js.map +1 -1
  82. package/dist/server/transcribe-voice.d.ts +1 -1
  83. package/docs/content/locales/zh-TW/durable-background-runs.md +74 -0
  84. package/package.json +1 -1
  85. package/corpus/templates/.retired/README.md +0 -9
  86. package/corpus/templates/.retired/calls/package.json +0 -8
  87. package/corpus/templates/.retired/code/package.json +0 -8
  88. package/corpus/templates/.retired/contracts/package.json +0 -8
  89. package/corpus/templates/.retired/images/package.json +0 -8
  90. package/corpus/templates/.retired/issues/package.json +0 -8
  91. package/corpus/templates/.retired/meeting-notes/package.json +0 -8
  92. package/corpus/templates/.retired/migration/package.json +0 -8
  93. package/corpus/templates/.retired/recruiting/package.json +0 -8
  94. package/corpus/templates/.retired/scheduling/package.json +0 -8
  95. package/corpus/templates/.retired/visual-plans/package.json +0 -8
  96. package/corpus/templates/.retired/voice/package.json +0 -8
  97. package/corpus/templates/.retired/workbench/package.json +0 -8
@@ -341,7 +341,7 @@ const messages = {
341
341
  cleanupBuilderFailed:
342
342
  "Builder.io कनेक्ट होने के बावजूद सफाई समाप्त नहीं हो सकी। मूल प्रतिलेख रखा गया था.",
343
343
  cleanupPaused:
344
- "सफ़ाई रुकी हुई है. इसे सक्षम करने के लिए सेटिंग्स में Builder.io कनेक्ट करें।",
344
+ "क्लीनअप रुका है। सेटिंग्स में AI कनेक्ट करें: Builder.io (मुफ्त क्रेडिट) या अपनी LLM key.",
345
345
  builderNoResponse:
346
346
  "बिल्डर से कोई जवाब नहीं मिला. पॉपअप की अनुमति दें और पुनः प्रयास करें।",
347
347
  saveFailed: "सहेजना विफल ({{status}})",
@@ -581,7 +581,7 @@ Clips में उपयोगकर्ताओं को दिखने व
581
581
  "Builder.io Clips अपलोड के लिए मुख्य स्टोरेज पथ है। अपना bucket लाने की ज़रूरत हो तो S3 उपलब्ध है।",
582
582
  checkingBuilder: "Builder.io जाँचा जा रहा है",
583
583
  builderConnected: "Builder.io कनेक्टेड",
584
- connectBuilder: "Builder.io कनेक्ट करें",
584
+ connectBuilder: "Builder.io इस्तेमाल करें (मुफ्त)",
585
585
  builderConnectedFor: "{{orgName}} के लिए Builder.io इस्तेमाल हो रहा है।",
586
586
  builderConnectedGeneric:
587
587
  "नई क्लिप्स कनेक्टेड Builder.io प्रोवाइडर का उपयोग करती हैं।",
@@ -608,12 +608,12 @@ Clips में उपयोगकर्ताओं को दिखने व
608
608
  s3PublicBaseUrlLabel: "सार्वजनिक बेस URL",
609
609
  apiSetup: "AI सेटअप",
610
610
  apiSetupDescription:
611
- "Builder.io मैनेज्ड AI क्रेडिट का डिफ़ॉल्ट पथ है। प्रोवाइडर कीज़ वैकल्पिक हैं और यहाँ जोड़ी जा सकती हैं।",
612
- builderEasySetup: "Builder.io सबसे आसान सेटअप है",
611
+ "Builder.io मुफ्त क्रेडिट या अपनी LLM keys के साथ AI कनेक्ट करें.",
612
+ builderEasySetup: "Builder.io मुफ्त क्रेडिट",
613
613
  builderAiAvailable:
614
614
  "Clips के लिए शामिल AI क्रेडिट और मैनेज्ड ट्रांसक्रिप्शन उपलब्ध हैं।",
615
615
  builderAiDescription:
616
- "शामिल AI क्रेडिट, ऑब्जेक्ट स्टोरेज, अपलोड और मैनेज्ड ट्रांसक्रिप्शन के लिए पहले Builder कनेक्ट करें।",
616
+ "शामिल AI क्रेडिट, ऑब्जेक्ट स्टोरेज, अपलोड और managed transcription के लिए पहले Builder.io इस्तेमाल करें.",
617
617
  providerKeyTitle: "अपनी प्रोवाइडर की लाएँ",
618
618
  providerKeyDescription:
619
619
  "प्रोवाइडर-बिल्ड उपयोग के लिए Anthropic, OpenAI, Gemini, Groq या OpenRouter कीज़ जोड़ें।",
@@ -755,7 +755,8 @@ Clips में उपयोगकर्ताओं को दिखने व
755
755
  title: "रिकॉर्डिंग जोड़ें",
756
756
  pickAtLeastTwo: "जोड़ने के लिए कम से कम 2 रिकॉर्डिंग चुनें",
757
757
  videoUrlMissing: "एक या अधिक रिकॉर्डिंग के पास अभी तैयार वीडियो URL नहीं है",
758
- connectStorage: "रिकॉर्डिंग जोड़ने से पहले Builder.io या S3-संगत स्टोरेज कनेक्ट करें।",
758
+ connectStorage:
759
+ "रिकॉर्डिंग जोड़ने से पहले स्टोरेज कनेक्ट करें: Builder.io (free tier storage + AI) या S3-संगत स्टोरेज.",
759
760
  created: "सिली हुई रिकॉर्डिंग बनाई गई",
760
761
  failed: "रिकॉर्डिंग जोड़ने में विफल",
761
762
  noOtherRecordings: "कोई अन्य रिकॉर्डिंग उपलब्ध नहीं।",
@@ -981,9 +982,12 @@ Clips में उपयोगकर्ताओं को दिखने व
981
982
  "5 मिनट में Builder से जवाब नहीं मिला। पॉपअप जांचें और फिर कोशिश करें।",
982
983
  builderConnected: "Builder.io कनेक्ट है",
983
984
  waitingForBuilder: "Builder की प्रतीक्षा...",
984
- connectBuilder: "Builder.io कनेक्ट करें",
985
+ connectBuilder: "Builder.io इस्तेमाल करें (मुफ्त)",
985
986
  free: "मुफ्त",
986
987
  configureS3: "S3-संगत स्टोरेज कॉन्फ़िगर करें",
988
+ whyPrompt: "मैं यह क्यों देख रहा हूं?",
989
+ whyDescription:
990
+ "Clips 100% मुफ्त और ओपन सोर्स ऐप है, इसलिए आपको क्लिप स्टोर करने का तरीका जोड़ना होगा। Builder.io से free-tier storage और AI वाला स्टोरेज कनेक्ट करें, या S3-संगत ऑब्जेक्ट स्टोरेज और अपनी LLM keys इस्तेमाल करें.",
987
991
  },
988
992
  captureInstall: {
989
993
  title: "Choose your recorder (स्थानीयकृत)",
@@ -1186,9 +1190,9 @@ Clips में उपयोगकर्ताओं को दिखने व
1186
1190
  downloadRecording: "Download recording (स्थानीयकृत)",
1187
1191
  openRecorderInTab: "Open recorder in tab (स्थानीयकृत)",
1188
1192
  connectStorageToFinish:
1189
- "Connect Builder.io or S3 storage on the next screen and Clips will finish saving it. (स्थानीयकृत)",
1193
+ "अगली स्क्रीन पर स्टोरेज कनेक्ट करें: Builder.io (free tier storage + AI) या S3-संगत स्टोरेज. Clips सेव पूरा करेगा.",
1190
1194
  connectStorageToRetryLoom:
1191
- "Connect Builder.io or S3 storage on the next screen and Clips will retry the import. (स्थानीयकृत)",
1195
+ "अगली स्क्रीन पर स्टोरेज कनेक्ट करें: Builder.io (free tier storage + AI) या S3-संगत स्टोरेज. Clips इंपोर्ट फिर से करेगा.",
1192
1196
  },
1193
1197
  dictateRoute: {
1194
1198
  pageTitle: "Dictate · Clips (स्थानीयकृत)",
@@ -353,7 +353,7 @@ const messages = {
353
353
  cleanupBuilderFailed:
354
354
  "Builder.io が接続されているにもかかわらず、クリーンアップが完了できませんでした。ネイティブのトランスクリプトが保存されました。",
355
355
  cleanupPaused:
356
- "クリーンアップは一時停止されています。設定でBuilder.ioを接続して有効にします。",
356
+ "クリーンアップは一時停止されています。設定で AI を接続してください: Builder.io (無料クレジット) または自分の LLM キー。",
357
357
  builderNoResponse:
358
358
  "ビルダーからは返事がありませんでした。ポップアップを許可して、再試行してください。",
359
359
  saveFailed: "保存に失敗しました ({{status}})",
@@ -595,7 +595,7 @@ Clips のユーザー向けの主な変更はここに記録されます。コ
595
595
  "Builder.io は Clips アップロードの主要な保存先です。独自バケットが必要な場合は S3 も利用できます。",
596
596
  checkingBuilder: "Builder.io を確認中",
597
597
  builderConnected: "Builder.io 接続済み",
598
- connectBuilder: "Builder.io に接続",
598
+ connectBuilder: "Builder.io を使用 (無料)",
599
599
  builderConnectedFor: "{{orgName}} で Builder.io を使用中です。",
600
600
  builderConnectedGeneric:
601
601
  "新しいクリップは接続済みの Builder.io プロバイダーを使用します。",
@@ -622,12 +622,12 @@ Clips のユーザー向けの主な変更はここに記録されます。コ
622
622
  s3PublicBaseUrlLabel: "公開ベース URL",
623
623
  apiSetup: "AI 設定",
624
624
  apiSetupDescription:
625
- "Builder.io はマネージド AI クレジットのデフォルト経路です。プロバイダーキーは任意でここに追加できます。",
626
- builderEasySetup: "Builder.io が最も簡単な設定です",
625
+ "Builder.io の無料クレジット、または自分の LLM キーで AI を接続します。",
626
+ builderEasySetup: "Builder.io 無料クレジット",
627
627
  builderAiAvailable:
628
628
  "Clips では付属の AI クレジットとマネージド文字起こしを利用できます。",
629
629
  builderAiDescription:
630
- "付属の AI クレジット、オブジェクトストレージ、アップロード、マネージド文字起こしを使うには、先に Builder を接続してください。",
630
+ "含まれる AI クレジット、オブジェクトストレージ、アップロード、管理された文字起こしには、まず Builder.io を使用します。",
631
631
  providerKeyTitle: "独自のプロバイダーキーを使用",
632
632
  providerKeyDescription:
633
633
  "プロバイダー課金で使用する Anthropic、OpenAI、Gemini、Groq、OpenRouter のキーを追加します。",
@@ -770,7 +770,7 @@ Clips のユーザー向けの主な変更はここに記録されます。コ
770
770
  pickAtLeastTwo: "結合する録画を少なくとも 2 件選択してください",
771
771
  videoUrlMissing: "1 件以上の録画に準備済みの動画 URL がありません",
772
772
  connectStorage:
773
- "録画を結合する前に Builder.io または S3 互換ストレージを接続してください。",
773
+ "録画を結合する前にストレージを接続してください: Builder.io (無料プランのストレージ + AI) または S3 互換ストレージ。",
774
774
  created: "結合録画を作成しました",
775
775
  failed: "録画の結合に失敗しました",
776
776
  noOtherRecordings: "他に利用できる録画はありません。",
@@ -1000,9 +1000,12 @@ Clips のユーザー向けの主な変更はここに記録されます。コ
1000
1000
  "5分以内に Builder から応答がありませんでした。ポップアップを確認してもう一度お試しください。",
1001
1001
  builderConnected: "Builder.io 接続済み",
1002
1002
  waitingForBuilder: "Builder を待機中...",
1003
- connectBuilder: "Builder.io に接続",
1003
+ connectBuilder: "Builder.io を使用 (無料)",
1004
1004
  free: "無料",
1005
1005
  configureS3: "S3 互換ストレージを設定",
1006
+ whyPrompt: "なぜこれが表示されていますか?",
1007
+ whyDescription:
1008
+ "Clips は 100% 無料でオープンソースのアプリなので、クリップを保存する方法を接続する必要があります。Builder.io で無料プランのストレージと AI を使うか、S3 互換オブジェクトストレージと自分の LLM キーを使用します。",
1006
1009
  },
1007
1010
  captureInstall: {
1008
1011
  title: "Choose your recorder (ローカライズ済み)",
@@ -1206,9 +1209,9 @@ Clips のユーザー向けの主な変更はここに記録されます。コ
1206
1209
  downloadRecording: "Download recording (ローカライズ済み)",
1207
1210
  openRecorderInTab: "Open recorder in tab (ローカライズ済み)",
1208
1211
  connectStorageToFinish:
1209
- "Connect Builder.io or S3 storage on the next screen and Clips will finish saving it. (ローカライズ済み)",
1212
+ "次の画面でストレージを接続してください: Builder.io (無料プランのストレージ + AI) または S3 互換ストレージ。Clips が保存を完了します。",
1210
1213
  connectStorageToRetryLoom:
1211
- "Connect Builder.io or S3 storage on the next screen and Clips will retry the import. (ローカライズ済み)",
1214
+ "次の画面でストレージを接続してください: Builder.io (無料プランのストレージ + AI) または S3 互換ストレージ。Clips がインポートを再試行します。",
1212
1215
  },
1213
1216
  dictateRoute: {
1214
1217
  pageTitle: "Dictate · Clips (ローカライズ済み)",
@@ -346,7 +346,7 @@ const messages = {
346
346
  cleanupBuilderFailed:
347
347
  "Builder.io가 연결되어 있어도 정리를 완료할 수 없습니다. 원어민 성적표가 보관되었습니다.",
348
348
  cleanupPaused:
349
- "정리가 일시중지되었습니다. 활성화하려면 설정에서 Builder.io 연결하세요.",
349
+ "정리가 일시중지되었습니다. 설정에서 AI를 연결하세요: Builder.io(무료 크레딧) 또는 직접 보유한 LLM 키.",
350
350
  builderNoResponse:
351
351
  "Builder로부터 답변을 듣지 못했습니다. 팝업을 허용하고 다시 시도하세요.",
352
352
  saveFailed: "저장 실패({{status}})",
@@ -588,7 +588,7 @@ Clips의 모든 사용자 대상 변경 사항은 여기에 기록됩니다. 명
588
588
  "Builder.io는 Clips 업로드의 기본 저장 경로입니다. 자체 버킷이 필요할 때 S3를 사용할 수 있습니다.",
589
589
  checkingBuilder: "Builder.io 확인 중",
590
590
  builderConnected: "Builder.io 연결됨",
591
- connectBuilder: "Builder.io 연결",
591
+ connectBuilder: "Builder.io 사용 (무료)",
592
592
  builderConnectedFor: "{{orgName}}에 Builder.io를 사용 중입니다.",
593
593
  builderConnectedGeneric: "새 클립은 연결된 Builder.io 제공자를 사용합니다.",
594
594
  builderIncludes:
@@ -614,12 +614,12 @@ Clips의 모든 사용자 대상 변경 사항은 여기에 기록됩니다. 명
614
614
  s3PublicBaseUrlLabel: "공개 기본 URL",
615
615
  apiSetup: "AI 설정",
616
616
  apiSetupDescription:
617
- "Builder.io 관리형 AI 크레딧의 기본 경로입니다. 제공자 키는 선택 사항이며 여기에서 추가할 수 있습니다.",
618
- builderEasySetup: "Builder.io 가장 쉬운 설정입니다",
617
+ "Builder.io 무료 크레딧 또는 직접 보유한 LLM 키로 AI를 연결하세요.",
618
+ builderEasySetup: "Builder.io 무료 크레딧",
619
619
  builderAiAvailable:
620
620
  "포함된 AI 크레딧과 관리형 전사를 Clips에서 사용할 수 있습니다.",
621
621
  builderAiDescription:
622
- "포함된 AI 크레딧, 객체 저장소, 업로드, 관리형 전사를 사용하려면 먼저 Builder를 연결하세요.",
622
+ "포함된 AI 크레딧, 객체 스토리지, 업로드, 관리형 전사에는 먼저 Builder.io사용하세요.",
623
623
  providerKeyTitle: "자체 제공자 키 사용",
624
624
  providerKeyDescription:
625
625
  "제공자 과금 사용을 위해 Anthropic, OpenAI, Gemini, Groq 또는 OpenRouter 키를 추가하세요.",
@@ -761,7 +761,7 @@ Clips의 모든 사용자 대상 변경 사항은 여기에 기록됩니다. 명
761
761
  pickAtLeastTwo: "이어붙일 녹화를 2개 이상 선택하세요",
762
762
  videoUrlMissing: "하나 이상의 녹화에 준비된 동영상 URL이 아직 없습니다",
763
763
  connectStorage:
764
- "녹화를 이어붙이기 전에 Builder.io 또는 S3 호환 스토리지를 연결하세요.",
764
+ "녹화를 이어붙이기 전에 스토리지를 연결하세요: Builder.io(무료 티어 스토리지 + AI) 또는 S3 호환 스토리지.",
765
765
  created: "이어붙인 녹화가 생성됨",
766
766
  failed: "녹화 이어붙이기 실패",
767
767
  noOtherRecordings: "사용 가능한 다른 녹화가 없습니다.",
@@ -990,9 +990,12 @@ Clips의 모든 사용자 대상 변경 사항은 여기에 기록됩니다. 명
990
990
  "5분 동안 Builder 응답이 없습니다. 팝업을 확인하고 다시 시도하세요.",
991
991
  builderConnected: "Builder.io 연결됨",
992
992
  waitingForBuilder: "Builder 대기 중...",
993
- connectBuilder: "Builder.io 연결",
993
+ connectBuilder: "Builder.io 사용 (무료)",
994
994
  free: "무료",
995
995
  configureS3: "S3 호환 스토리지 구성",
996
+ whyPrompt: "왜 이 화면이 보이나요?",
997
+ whyDescription:
998
+ "Clips는 100% 무료 오픈 소스 앱이므로 클립을 저장할 방법을 연결해야 합니다. Builder.io로 무료 티어 스토리지와 AI를 사용하거나, S3 호환 객체 스토리지와 직접 보유한 LLM 키를 사용하세요.",
996
999
  },
997
1000
  captureInstall: {
998
1001
  title: "Choose your recorder (현지화됨)",
@@ -1195,9 +1198,9 @@ Clips의 모든 사용자 대상 변경 사항은 여기에 기록됩니다. 명
1195
1198
  downloadRecording: "Download recording (현지화됨)",
1196
1199
  openRecorderInTab: "Open recorder in tab (현지화됨)",
1197
1200
  connectStorageToFinish:
1198
- "Connect Builder.io or S3 storage on the next screen and Clips will finish saving it. (현지화됨)",
1201
+ "다음 화면에서 스토리지를 연결하세요: Builder.io(무료 티어 스토리지 + AI) 또는 S3 호환 스토리지. Clips 저장을 완료합니다.",
1199
1202
  connectStorageToRetryLoom:
1200
- "Connect Builder.io or S3 storage on the next screen and Clips will retry the import. (현지화됨)",
1203
+ "다음 화면에서 스토리지를 연결하세요: Builder.io(무료 티어 스토리지 + AI) 또는 S3 호환 스토리지. Clips 가져오기를 다시 시도합니다.",
1201
1204
  },
1202
1205
  dictateRoute: {
1203
1206
  pageTitle: "Dictate · Clips (현지화됨)",
@@ -353,7 +353,7 @@ const messages = {
353
353
  cleanupBuilderFailed:
354
354
  "A limpeza não pôde ser concluída mesmo que Builder.io estivesse conectado. A transcrição nativa foi mantida.",
355
355
  cleanupPaused:
356
- "A limpeza está pausada. Conecte Builder.io em Configurações para habilitá-lo.",
356
+ "A limpeza está pausada. Conecte IA em Configurações: Builder.io (créditos grátis) ou sua própria chave LLM.",
357
357
  builderNoResponse:
358
358
  "Não recebi resposta do Builder. Permita pop-ups e tente novamente.",
359
359
  saveFailed: "Falha ao salvar ({{status}})",
@@ -598,7 +598,7 @@ Todas as mudanças visíveis para usuários do Clips são documentadas aqui. Voc
598
598
  "Builder.io é o caminho principal de armazenamento para uploads do Clips. S3 está disponível quando você precisa trazer seu próprio bucket.",
599
599
  checkingBuilder: "Verificando Builder.io",
600
600
  builderConnected: "Builder.io conectado",
601
- connectBuilder: "Conectar Builder.io",
601
+ connectBuilder: "Usar Builder.io (grátis)",
602
602
  builderConnectedFor: "Usando Builder.io para {{orgName}}.",
603
603
  builderConnectedGeneric:
604
604
  "Novos clipes usam o provedor Builder.io conectado.",
@@ -625,12 +625,12 @@ Todas as mudanças visíveis para usuários do Clips são documentadas aqui. Voc
625
625
  s3PublicBaseUrlLabel: "URL base pública",
626
626
  apiSetup: "Configuração de IA",
627
627
  apiSetupDescription:
628
- "Builder.io é o caminho padrão para créditos de IA gerenciados. Chaves de provedor são opcionais e podem ser adicionadas aqui.",
629
- builderEasySetup: "Builder.io é a configuração mais simples",
628
+ "Conecte IA com créditos grátis da Builder.io ou suas próprias chaves LLM.",
629
+ builderEasySetup: "Créditos grátis da Builder.io",
630
630
  builderAiAvailable:
631
631
  "Créditos de IA incluídos e transcrição gerenciada estão disponíveis para Clips.",
632
632
  builderAiDescription:
633
- "Conecte Builder primeiro para usar créditos de IA incluídos, armazenamento de objetos, uploads e transcrição gerenciada.",
633
+ "Use Builder.io primeiro para créditos de IA incluídos, armazenamento de objetos, uploads e transcrição gerenciada.",
634
634
  providerKeyTitle: "Usar sua própria chave de provedor",
635
635
  providerKeyDescription:
636
636
  "Adicione chaves da Anthropic, OpenAI, Gemini, Groq ou OpenRouter para uso cobrado pelo provedor.",
@@ -777,7 +777,7 @@ Todas as mudanças visíveis para usuários do Clips são documentadas aqui. Voc
777
777
  videoUrlMissing:
778
778
  "Uma ou mais gravações ainda não têm uma URL de vídeo pronta",
779
779
  connectStorage:
780
- "Conecte Builder.io ou armazenamento compatível com S3 antes de unir gravações.",
780
+ "Conecte armazenamento antes de unir gravações: Builder.io (armazenamento + IA no plano gratuito) ou armazenamento compatível com S3.",
781
781
  created: "Gravação unida criada",
782
782
  failed: "Falha ao unir gravações",
783
783
  noOtherRecordings: "Nenhuma outra gravação disponível.",
@@ -1007,9 +1007,12 @@ Todas as mudanças visíveis para usuários do Clips são documentadas aqui. Voc
1007
1007
  "Não houve resposta do Builder em 5 minutos. Verifique o pop-up e tente novamente.",
1008
1008
  builderConnected: "Builder.io conectado",
1009
1009
  waitingForBuilder: "Aguardando Builder...",
1010
- connectBuilder: "Conectar Builder.io",
1010
+ connectBuilder: "Usar Builder.io (grátis)",
1011
1011
  free: "Grátis",
1012
1012
  configureS3: "configurar armazenamento compatível com S3",
1013
+ whyPrompt: "Por que estou vendo isso?",
1014
+ whyDescription:
1015
+ "Clips é 100% gratuito e open source, então você precisa conectar uma forma de armazenar seus clipes. Conecte armazenamento com Builder.io para armazenamento e IA no plano gratuito, ou use armazenamento compatível com S3 e suas próprias chaves LLM.",
1013
1016
  },
1014
1017
  captureInstall: {
1015
1018
  title: "Choose your recorder (Localizado)",
@@ -1212,9 +1215,9 @@ Todas as mudanças visíveis para usuários do Clips são documentadas aqui. Voc
1212
1215
  downloadRecording: "Download recording (Localizado)",
1213
1216
  openRecorderInTab: "Open recorder in tab (Localizado)",
1214
1217
  connectStorageToFinish:
1215
- "Connect Builder.io or S3 storage on the next screen and Clips will finish saving it. (Localizado)",
1218
+ "Conecte armazenamento na próxima tela: Builder.io (armazenamento + IA no plano gratuito) ou armazenamento compatível com S3. Clips terminará de salvar.",
1216
1219
  connectStorageToRetryLoom:
1217
- "Connect Builder.io or S3 storage on the next screen and Clips will retry the import. (Localizado)",
1220
+ "Conecte armazenamento na próxima tela: Builder.io (armazenamento + IA no plano gratuito) ou armazenamento compatível com S3. Clips tentará importar novamente.",
1218
1221
  },
1219
1222
  dictateRoute: {
1220
1223
  pageTitle: "Dictate · Clips (Localizado)",
@@ -146,7 +146,7 @@ const messages = {
146
146
  savingWentWrong: "保存此剪辑时出现问题。",
147
147
  finishingClip: "正在完成您的剪辑...",
148
148
  loomSourcePreserved:
149
- "Loom 源链接被保留。连接 Builder.io S3 存储,Clips 将重试保存其自己的副本。",
149
+ "Loom 源链接被保留。连接存储:Builder.io(免费套餐存储 + AI)或 S3 兼容存储,Clips 将重试保存自己的副本。",
150
150
  clipDataPreserved:
151
151
  "Your clip data is still preserved.连接Builder.io或S3存储,Clips将自动上传。",
152
152
  details: "细节",
@@ -223,12 +223,13 @@ const messages = {
223
223
  savingWentWrong: "保存此剪辑时出现问题。",
224
224
  finishingClip: "完成这个剪辑...",
225
225
  loomPreservedManage:
226
- "Loom 源链接被保留。连接 Builder.io S3 存储,然后重试导入。",
226
+ "Loom 源链接被保留。连接存储:Builder.io(免费套餐存储 + AI)或 S3 兼容存储,然后重试导入。",
227
227
  videoPreservedManage:
228
228
  "视频被保留。连接Builder.io或S3存储,Clips将完成上传。",
229
- creatorNeedsStorage: "创建者需要连接 Builder.io 或 S3 存储才能完成此剪辑。",
229
+ creatorNeedsStorage:
230
+ "创建者需要先连接存储才能完成此剪辑:Builder.io(免费套餐存储 + AI)或 S3 兼容存储。",
230
231
  signInStorage:
231
- "如果这是您的剪辑,请在此处登录以连接 Builder.io S3 存储并完成上传。",
232
+ "如果这是您的剪辑,请在此处登录以连接存储:Builder.io(免费套餐存储 + AI)或 S3 兼容存储,并完成上传。",
232
233
  uploadNotCompleteSession:
233
234
  "上传尚未完成。打开此剪辑的仪表板或要求创建者检查存储空间。",
234
235
  uploadNotCompleteSignIn:
@@ -330,7 +331,8 @@ const messages = {
330
331
  cleanupKept: "清理工作无法完成。保留了本机转录本。",
331
332
  cleanupBuilderFailed:
332
333
  "即使 Builder.io 已连接,清理也无法完成。保留了本机转录本。",
333
- cleanupPaused: "清理已暂停。在“设置”中连接 Builder.io 即可启用它。",
334
+ cleanupPaused:
335
+ "清理已暂停。请在“设置”中连接 AI:Builder.io(免费额度)或你自己的 LLM 密钥。",
334
336
  builderNoResponse: "没有收到Builder的回复。允许弹出窗口并重试。",
335
337
  saveFailed: "保存失败({{status}})",
336
338
  savedRetrying: "已保存。正在重试转录...",
@@ -562,7 +564,7 @@ Clips 中所有面向用户的重要更改都会记录在这里。你可以随
562
564
  "Builder.io 是 Clips 上传的主要存储路径。需要自带存储桶时,也可以使用 S3。",
563
565
  checkingBuilder: "正在检查 Builder.io",
564
566
  builderConnected: "Builder.io 已连接",
565
- connectBuilder: "连接 Builder.io",
567
+ connectBuilder: "使用 Builder.io(免费)",
566
568
  builderConnectedFor: "正在为 {{orgName}} 使用 Builder.io。",
567
569
  builderConnectedGeneric: "新的剪辑会使用已连接的 Builder.io 提供方。",
568
570
  builderIncludes: "包含对象存储、上传,以及新剪辑的托管转录。",
@@ -586,12 +588,11 @@ Clips 中所有面向用户的重要更改都会记录在这里。你可以随
586
588
  s3RegionLabel: "区域",
587
589
  s3PublicBaseUrlLabel: "公共基础 URL",
588
590
  apiSetup: "AI 设置",
589
- apiSetupDescription:
590
- "Builder.io 是托管 AI 额度的默认路径。也可以在这里添加可选的提供方密钥。",
591
- builderEasySetup: "Builder.io 是最简单的设置方式",
591
+ apiSetupDescription: "使用 Builder.io 免费额度或你自己的 LLM 密钥连接 AI。",
592
+ builderEasySetup: "Builder.io 免费额度",
592
593
  builderAiAvailable: "Clips 可使用包含的 AI 额度和托管转录。",
593
594
  builderAiDescription:
594
- "先连接 Builder,即可使用包含的 AI 额度、对象存储、上传和托管转录。",
595
+ "优先使用 Builder.io,可获得内置 AI 额度、对象存储、上传和托管转录。",
595
596
  providerKeyTitle: "使用自己的提供方密钥",
596
597
  providerKeyDescription:
597
598
  "添加 Anthropic、OpenAI、Gemini、Groq 或 OpenRouter 密钥,用于按提供方计费的使用。",
@@ -730,7 +731,8 @@ Clips 中所有面向用户的重要更改都会记录在这里。你可以随
730
731
  title: "拼接录制",
731
732
  pickAtLeastTwo: "请选择至少 2 个录制进行拼接",
732
733
  videoUrlMissing: "一个或多个录制还没有可用的视频 URL",
733
- connectStorage: "拼接录制前请连接 Builder.io 或 S3 兼容存储。",
734
+ connectStorage:
735
+ "拼接录制前请连接存储:Builder.io(免费套餐存储 + AI)或 S3 兼容存储。",
734
736
  created: "拼接录制已创建",
735
737
  failed: "拼接录制失败",
736
738
  noOtherRecordings: "没有其他可用录制。",
@@ -954,9 +956,12 @@ Clips 中所有面向用户的重要更改都会记录在这里。你可以随
954
956
  builderTimeout: "5 分钟内未收到 Builder 响应。请检查弹出窗口并重试。",
955
957
  builderConnected: "Builder.io 已连接",
956
958
  waitingForBuilder: "正在等待 Builder...",
957
- connectBuilder: "连接 Builder.io",
959
+ connectBuilder: "使用 Builder.io(免费)",
958
960
  free: "免费",
959
961
  configureS3: "配置 S3 兼容存储",
962
+ whyPrompt: "为什么会看到这个?",
963
+ whyDescription:
964
+ "Clips 是 100% 免费且开源的应用,所以你需要连接一种方式来存储剪辑。使用 Builder.io 可获得免费套餐存储和 AI,或使用 S3 兼容对象存储和你自己的 LLM 密钥。",
960
965
  },
961
966
  captureInstall: {
962
967
  title: "Choose your recorder (已本地化)",
@@ -1159,9 +1164,9 @@ Clips 中所有面向用户的重要更改都会记录在这里。你可以随
1159
1164
  downloadRecording: "Download recording (已本地化)",
1160
1165
  openRecorderInTab: "Open recorder in tab (已本地化)",
1161
1166
  connectStorageToFinish:
1162
- "Connect Builder.io or S3 storage on the next screen and Clips will finish saving it. (已本地化)",
1167
+ "在下一屏连接存储:Builder.io(免费套餐存储 + AI)或 S3 兼容存储。Clips 将完成保存。",
1163
1168
  connectStorageToRetryLoom:
1164
- "Connect Builder.io or S3 storage on the next screen and Clips will retry the import. (已本地化)",
1169
+ "在下一屏连接存储:Builder.io(免费套餐存储 + AI)或 S3 兼容存储。Clips 将重试导入。",
1165
1170
  },
1166
1171
  dictateRoute: {
1167
1172
  pageTitle: "Dictate · Clips (已本地化)",
@@ -146,7 +146,7 @@ const messages = {
146
146
  savingWentWrong: "儲存此剪輯時出現問題。",
147
147
  finishingClip: "正在完成您的剪輯...",
148
148
  loomSourcePreserved:
149
- "Loom 來源連結被保留。連線 Builder.io S3 存儲,Clips 將重試儲存其自己的副本。",
149
+ "Loom 來源連結被保留。連接儲存:Builder.io(免費方案儲存 + AI)或 S3 相容儲存,Clips 將重試儲存自己的副本。",
150
150
  clipDataPreserved:
151
151
  "Your clip data is still preserved.連線Builder.io或S3存儲,Clips將自動上傳。",
152
152
  details: "細節",
@@ -223,12 +223,13 @@ const messages = {
223
223
  savingWentWrong: "儲存此剪輯時出現問題。",
224
224
  finishingClip: "完成這個剪輯...",
225
225
  loomPreservedManage:
226
- "Loom 來源連結被保留。連線 Builder.io S3 存儲,然後重試匯入。",
226
+ "Loom 來源連結被保留。連接儲存:Builder.io(免費方案儲存 + AI)或 S3 相容儲存,然後重試匯入。",
227
227
  videoPreservedManage:
228
228
  "影片被保留。連線Builder.io或S3存儲,Clips將完成上傳。",
229
- creatorNeedsStorage: "建立者需要連線 Builder.io 或 S3 存儲才能完成此剪輯。",
229
+ creatorNeedsStorage:
230
+ "建立者需要先連接儲存才能完成此剪輯:Builder.io(免費方案儲存 + AI)或 S3 相容儲存。",
230
231
  signInStorage:
231
- "如果這是您的剪輯,請在此處登入以連線 Builder.io S3 存儲並完成上傳。",
232
+ "如果這是您的剪輯,請在此處登入以連接儲存:Builder.io(免費方案儲存 + AI)或 S3 相容儲存,並完成上傳。",
232
233
  uploadNotCompleteSession:
233
234
  "上傳尚未完成。開啟此剪輯的儀表板或要求建立者檢查存儲空間。",
234
235
  uploadNotCompleteSignIn:
@@ -330,7 +331,8 @@ const messages = {
330
331
  cleanupKept: "清理工作無法完成。保留了本機轉錄本。",
331
332
  cleanupBuilderFailed:
332
333
  "即使 Builder.io 已連線,清理也無法完成。保留了本機轉錄本。",
333
- cleanupPaused: "清理已暫停。在“設定”中連線 Builder.io 即可啟用它。",
334
+ cleanupPaused:
335
+ "清理已暫停。請在「設定」中連接 AI:Builder.io(免費額度)或你自己的 LLM 金鑰。",
334
336
  builderNoResponse: "沒有收到Builder的回複。允許快顯窗口並重試。",
335
337
  saveFailed: "儲存失敗({{status}})",
336
338
  savedRetrying: "已儲存。正在重試轉錄...",
@@ -555,7 +557,7 @@ const messages = {
555
557
  "Builder.io 是 Clips 上傳的主要存儲路徑。需要自帶存儲桶時,也可以使用 S3。",
556
558
  checkingBuilder: "正在檢查 Builder.io",
557
559
  builderConnected: "Builder.io 已連線",
558
- connectBuilder: "連線 Builder.io",
560
+ connectBuilder: "使用 Builder.io(免費)",
559
561
  builderConnectedFor: "正在為 {{orgName}} 使用 Builder.io。",
560
562
  builderConnectedGeneric: "新的剪輯會使用已連線的 Builder.io 提供方。",
561
563
  builderIncludes: "包含物件存儲、上傳,以及新剪輯的託管轉錄。",
@@ -579,12 +581,11 @@ const messages = {
579
581
  s3RegionLabel: "區域",
580
582
  s3PublicBaseUrlLabel: "公開基礎 URL",
581
583
  apiSetup: "AI 設定",
582
- apiSetupDescription:
583
- "Builder.io 是託管 AI 額度的預設路徑。也可以在這裡新增可選的提供方金鑰。",
584
- builderEasySetup: "Builder.io 是最簡單的設定方式",
584
+ apiSetupDescription: "使用 Builder.io 免費額度或你自己的 LLM 金鑰連接 AI。",
585
+ builderEasySetup: "Builder.io 免費額度",
585
586
  builderAiAvailable: "Clips 可使用包含的 AI 額度和託管轉錄。",
586
587
  builderAiDescription:
587
- "先連線 Builder,即可使用包含的 AI 額度、物件存儲、上傳和託管轉錄。",
588
+ "優先使用 Builder.io,可獲得內建 AI 額度、物件儲存、上傳和託管轉錄。",
588
589
  providerKeyTitle: "使用自己的提供方金鑰",
589
590
  providerKeyDescription:
590
591
  "新增 Anthropic、OpenAI、Gemini、Groq 或 OpenRouter 金鑰,用於按提供方計費的使用。",
@@ -723,7 +724,8 @@ const messages = {
723
724
  title: "拼接錄製",
724
725
  pickAtLeastTwo: "請選取至少 2 個錄製進行拼接",
725
726
  videoUrlMissing: "一個或多個錄製還沒有可用的影片 URL",
726
- connectStorage: "拼接錄製前請連線 Builder.io 或 S3 兼容存儲。",
727
+ connectStorage:
728
+ "拼接錄製前請連接儲存:Builder.io(免費方案儲存 + AI)或 S3 相容儲存。",
727
729
  created: "拼接錄製已建立",
728
730
  failed: "拼接錄製失敗",
729
731
  noOtherRecordings: "沒有其他可用錄製。",
@@ -947,9 +949,12 @@ const messages = {
947
949
  builderTimeout: "5 分鐘內未收到 Builder 回應。請檢查快顯窗口並重試。",
948
950
  builderConnected: "Builder.io 已連線",
949
951
  waitingForBuilder: "正在等待 Builder...",
950
- connectBuilder: "連線 Builder.io",
952
+ connectBuilder: "使用 Builder.io(免費)",
951
953
  free: "免費",
952
954
  configureS3: "設定 S3 兼容存儲",
955
+ whyPrompt: "為什麼我會看到這個?",
956
+ whyDescription:
957
+ "Clips 是 100% 免費且開源的,因此你需要連接一種儲存 clips 的方式。使用 Builder.io 可取得免費方案儲存和 AI,或使用 S3 相容物件儲存和你自己的 LLM 金鑰。",
953
958
  },
954
959
  captureInstall: {
955
960
  title: "Choose your recorder (已本機化)",
@@ -1152,9 +1157,9 @@ const messages = {
1152
1157
  downloadRecording: "Download recording (已本機化)",
1153
1158
  openRecorderInTab: "Open recorder in tab (已本機化)",
1154
1159
  connectStorageToFinish:
1155
- "Connect Builder.io or S3 storage on the next screen and Clips will finish saving it. (已本機化)",
1160
+ "在下一屏連接儲存:Builder.io(免費方案儲存 + AI)或 S3 相容儲存。Clips 將完成儲存。",
1156
1161
  connectStorageToRetryLoom:
1157
- "Connect Builder.io or S3 storage on the next screen and Clips will retry the import. (已本機化)",
1162
+ "在下一屏連接儲存:Builder.io(免費方案儲存 + AI)或 S3 相容儲存。Clips 將重試匯入。",
1158
1163
  },
1159
1164
  dictateRoute: {
1160
1165
  pageTitle: "Dictate · Clips (已本機化)",
@@ -114,6 +114,13 @@ function failureDetail(reason: string | null | undefined): string | null {
114
114
 
115
115
  function nativeSaveFailureMessage(reason: string | null | undefined): string {
116
116
  const text = reason ?? "";
117
+ if (
118
+ /finalization callback failed|missing required metadata|missing playback metadata|corrupted or incomplete|missing moov/i.test(
119
+ text,
120
+ )
121
+ ) {
122
+ return "macOS could not finish writing this desktop recording. The local file is incomplete, so discard it from the Clips menu and record again.";
123
+ }
117
124
  if (/too large|compression/i.test(text)) {
118
125
  return "Clips tried to compress this desktop recording, but it is still too large to upload. The original is saved locally and can be retried from the Clips menu.";
119
126
  }
@@ -1119,7 +1119,7 @@ export default function RecordRoute() {
1119
1119
  markStorageConfigured(status);
1120
1120
  if (!status.configured) {
1121
1121
  throw new Error(
1122
- "No video storage configured. Open Settings to connect Builder.io or S3-compatible storage.",
1122
+ "No video storage configured. Connect storage: Builder.io (free tier storage + AI) or S3-compatible storage.",
1123
1123
  );
1124
1124
  }
1125
1125
 
@@ -1329,7 +1329,7 @@ export default function RecordRoute() {
1329
1329
  markStorageConfigured(status);
1330
1330
  if (!status.configured) {
1331
1331
  throw new Error(
1332
- "No video storage configured. Open Settings to connect Builder.io or S3-compatible storage.",
1332
+ "No video storage configured. Connect storage: Builder.io (free tier storage + AI) or S3-compatible storage.",
1333
1333
  );
1334
1334
  }
1335
1335
 
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-26
4
+ ---
5
+
6
+ Desktop recordings recover more reliably when macOS reports a finalization error.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-26
4
+ ---
5
+
6
+ Slack unfurls now recognize recording dashboard links pasted from Clips.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-26
4
+ ---
5
+
6
+ Storage setup now explains why Clips needs connected storage and guides saved desktop or Chrome uploads back to Builder.io.
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "name": "Agent-Native Clips",
4
4
  "short_name": "Clips",
5
- "version": "0.1.4",
5
+ "version": "0.1.5",
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": {
@@ -8,6 +8,10 @@ const MAX_CONSOLE_LOGS = 400;
8
8
  const MAX_NETWORK_REQUESTS = 400;
9
9
  const MAX_MESSAGE_LENGTH = 2_000;
10
10
  const MAX_URL_LENGTH = 1_000;
11
+ const STORAGE_SETUP_REQUIRED_MESSAGE =
12
+ "Connect storage to finish saving this clip: Builder.io (free tier storage + AI) or S3-compatible storage.";
13
+ const STORAGE_SETUP_FAILURE_RE =
14
+ /video storage is not connected|no video storage configured|file upload provider|storage provider|connect builder|s3-compatible/i;
11
15
  const SECRET_KEY_FRAGMENT =
12
16
  "(?:authorization|cookie|set[-_]?cookie|token|secret|password|passwd|pwd|api[-_]?key|apikey|session|credential)";
13
17
  const AUTHORIZATION_SCHEME_RE =
@@ -151,6 +155,7 @@ type OffscreenStatusMessage = {
151
155
  recordingId?: string;
152
156
  result?: Record<string, unknown>;
153
157
  error?: string;
158
+ storageSetupRequired?: boolean;
154
159
  };
155
160
 
156
161
  type ExtensionErrorMessage = {
@@ -162,6 +167,16 @@ type ExtensionErrorMessage = {
162
167
  context?: Record<string, unknown>;
163
168
  };
164
169
 
170
+ function isStorageSetupFailureMessage(message: string | null | undefined) {
171
+ return STORAGE_SETUP_FAILURE_RE.test(message ?? "");
172
+ }
173
+
174
+ function friendlyRecordingError(message: string | null | undefined): string {
175
+ return isStorageSetupFailureMessage(message)
176
+ ? STORAGE_SETUP_REQUIRED_MESSAGE
177
+ : message || "Could not stop recording.";
178
+ }
179
+
165
180
  type PendingNetworkRequest = {
166
181
  requestId: string;
167
182
  timestampMs: number;
@@ -1369,8 +1384,9 @@ async function stopRecording() {
1369
1384
  };
1370
1385
  } catch (err) {
1371
1386
  recording.status = "error";
1372
- recording.error =
1373
- err instanceof Error ? err.message : "Could not stop recording.";
1387
+ recording.error = friendlyRecordingError(
1388
+ err instanceof Error ? err.message : null,
1389
+ );
1374
1390
  resetOverlay();
1375
1391
  await broadcastUnmount();
1376
1392
  broadcastOverlayState();
@@ -2032,7 +2048,12 @@ async function dispatchRuntimeMessage(message: unknown): Promise<unknown> {
2032
2048
  ) {
2033
2049
  activeNativeRecording.status = status.status;
2034
2050
  activeNativeRecording.error =
2035
- typeof status.error === "string" ? status.error : null;
2051
+ typeof status.error === "string"
2052
+ ? status.storageSetupRequired === true ||
2053
+ isStorageSetupFailureMessage(status.error)
2054
+ ? STORAGE_SETUP_REQUIRED_MESSAGE
2055
+ : status.error
2056
+ : null;
2036
2057
  if (typeof status.recordingId === "string") {
2037
2058
  activeNativeRecording.recordingId = status.recordingId;
2038
2059
  activeNativeRecording.recordingUrl = recordingUrl(