@agent-native/core 0.114.5 → 0.114.7

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 (210) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +14 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/cli/mcp-config-writers.ts +6 -4
  5. package/corpus/core/src/cli/mcp.ts +124 -0
  6. package/corpus/core/src/cli/skills-content/help.ts +4 -3
  7. package/corpus/core/src/cli/skills-content/index.ts +1 -0
  8. package/corpus/core/src/cli/skills-content/rewind-skill.ts +52 -0
  9. package/corpus/core/src/cli/skills.ts +115 -13
  10. package/corpus/core/src/client/resources/ResourceTree.tsx +11 -5
  11. package/corpus/core/src/client/resources/ResourcesPanel.tsx +141 -18
  12. package/corpus/core/src/mcp/screen-memory-stdio.ts +1360 -104
  13. package/corpus/core/src/mcp-client/index.ts +9 -0
  14. package/corpus/core/src/mcp-client/screen-memory-local.ts +847 -13
  15. package/corpus/templates/clips/actions/apply-rewind-extension.ts +195 -0
  16. package/corpus/templates/clips/actions/delete-agent-recording-if-unpromoted.ts +64 -0
  17. package/corpus/templates/clips/actions/get-rewind-extension-request.ts +22 -0
  18. package/corpus/templates/clips/actions/get-screen-memory-status.ts +18 -2
  19. package/corpus/templates/clips/actions/list-rewind-extension-requests.ts +52 -0
  20. package/corpus/templates/clips/actions/make-recording-private-for-rewind.ts +55 -0
  21. package/corpus/templates/clips/actions/query-screen-memory-context.ts +4 -4
  22. package/corpus/templates/clips/actions/request-rewind-extension.ts +81 -0
  23. package/corpus/templates/clips/actions/update-rewind-extension-request.ts +47 -0
  24. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +25 -0
  25. package/corpus/templates/clips/app/components/editor/editor-toolbar.tsx +36 -0
  26. package/corpus/templates/clips/app/components/editor/rewind-extension-dialog.tsx +338 -0
  27. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +1 -16
  28. package/corpus/templates/clips/app/components/editor/timeline.tsx +26 -0
  29. package/corpus/templates/clips/app/components/meetings/meeting-card.tsx +1 -2
  30. package/corpus/templates/clips/app/i18n/en-US.ts +18 -0
  31. package/corpus/templates/clips/app/lib/ffmpeg-export.ts +19 -12
  32. package/corpus/templates/clips/app/lib/rewind-visibility.ts +31 -0
  33. package/corpus/templates/clips/app/lib/timestamp-mapping.ts +7 -0
  34. package/corpus/templates/clips/app/lib/upload-file-client.ts +17 -0
  35. package/corpus/templates/clips/changelog/2026-07-14-rewind-keeps-recent-screen-context-local-and-turns-it-into-clips.md +6 -0
  36. package/corpus/templates/clips/changelog/2026-07-17-active-clips-keep-rewind-stable-and-settings-clear.md +12 -0
  37. package/corpus/templates/clips/changelog/2026-07-17-clicking-the-clips-icon-during-a-recording-now-opens-the-app.md +6 -0
  38. package/corpus/templates/clips/changelog/2026-07-17-default-mic-now-uses-the-mac-default-and-transcription-shares-one-capture.md +6 -0
  39. package/corpus/templates/clips/changelog/2026-07-17-full-screen-clips-finalize-even-when-screencapturekit-stop-hangs.md +6 -0
  40. package/corpus/templates/clips/changelog/2026-07-17-normal-full-screen-clips-no-longer-stop-immediately-after-th.md +6 -0
  41. package/corpus/templates/clips/changelog/2026-07-17-rewind-can-hand-one-bounded-private-clip-to-your-agent.md +12 -0
  42. package/corpus/templates/clips/changelog/2026-07-17-rewind-home-can-copy-a-local-agent-prompt.md +6 -0
  43. package/corpus/templates/clips/changelog/2026-07-17-rewind-now-has-a-calm-home-status-focused-first-run-consent-.md +6 -0
  44. package/corpus/templates/clips/changelog/2026-07-17-rewind-settings-are-smaller-clearer-and-agent-first.md +6 -0
  45. package/corpus/templates/clips/changelog/2026-07-17-the-full-clips-interface-stays-available-while-recording.md +6 -0
  46. package/corpus/templates/clips/changelog/2026-07-18-rewind-organizes-recent-work-into-local-searchable-chapters.md +8 -0
  47. package/corpus/templates/clips/changelog/2026-07-18-searchable-rewind-chapters.md +6 -0
  48. package/corpus/templates/clips/changelog/2026-07-19-rewind-backed-recordings-now-start-immediately-after-the-cou.md +6 -0
  49. package/corpus/templates/clips/changelog/2026-07-20-opening-zoom-meeting-launches-native-app.md +6 -0
  50. package/corpus/templates/clips/changelog/2026-07-20-rewind-can-set-up-your-local-agent-once-so-future-requests-w.md +6 -0
  51. package/corpus/templates/clips/desktop/package.json +1 -0
  52. package/corpus/templates/clips/desktop/scripts/sign-macos-local.ts +12 -1
  53. package/corpus/templates/clips/desktop/src/app.tsx +2478 -223
  54. package/corpus/templates/clips/desktop/src/components/ReadinessPanel.tsx +21 -1
  55. package/corpus/templates/clips/desktop/src/components/Switch.tsx +3 -0
  56. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +156 -24
  57. package/corpus/templates/clips/desktop/src/lib/native-recording-warm.ts +6 -7
  58. package/corpus/templates/clips/desktop/src/lib/open-meeting-join-url.ts +22 -0
  59. package/corpus/templates/clips/desktop/src/lib/recorder.ts +1763 -1160
  60. package/corpus/templates/clips/desktop/src/lib/rewind-agent-prompt.ts +9 -0
  61. package/corpus/templates/clips/desktop/src/lib/rewind-recording-start.ts +20 -0
  62. package/corpus/templates/clips/desktop/src/main.tsx +3 -0
  63. package/corpus/templates/clips/desktop/src/overlays/countdown.tsx +14 -14
  64. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +2 -3
  65. package/corpus/templates/clips/desktop/src/overlays/onboarding.tsx +4 -4
  66. package/corpus/templates/clips/desktop/src/overlays/preparing.tsx +13 -0
  67. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +27 -2
  68. package/corpus/templates/clips/desktop/src/shared/config.ts +16 -0
  69. package/corpus/templates/clips/desktop/src/styles.css +956 -134
  70. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +5 -0
  71. package/corpus/templates/clips/desktop/src-tauri/build.rs +69 -1
  72. package/corpus/templates/clips/desktop/src-tauri/src/accessibility.rs +386 -12
  73. package/corpus/templates/clips/desktop/src-tauri/src/capture_audio_bus.rs +382 -0
  74. package/corpus/templates/clips/desktop/src-tauri/src/capture_graph.rs +777 -0
  75. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +249 -22
  76. package/corpus/templates/clips/desktop/src-tauri/src/config.rs +148 -1
  77. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +58 -4
  78. package/corpus/templates/clips/desktop/src-tauri/src/logfile.rs +13 -1
  79. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +1505 -51
  80. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +124 -0
  81. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1006 -95
  82. package/corpus/templates/clips/desktop/src-tauri/src/rewind_capture_suspension.rs +165 -0
  83. package/corpus/templates/clips/desktop/src-tauri/src/rewind_chapters.rs +2434 -0
  84. package/corpus/templates/clips/desktop/src-tauri/src/rewind_clip.rs +1650 -0
  85. package/corpus/templates/clips/desktop/src-tauri/src/rewind_egress.rs +643 -0
  86. package/corpus/templates/clips/desktop/src-tauri/src/rewind_local_ask.rs +803 -0
  87. package/corpus/templates/clips/desktop/src-tauri/src/rewind_meeting_history.rs +595 -0
  88. package/corpus/templates/clips/desktop/src-tauri/src/screen_memory.rs +2900 -91
  89. package/corpus/templates/clips/desktop/src-tauri/src/screen_memory_ocr.rs +360 -0
  90. package/corpus/templates/clips/desktop/src-tauri/src/screen_memory_transcript.rs +408 -0
  91. package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +114 -33
  92. package/corpus/templates/clips/desktop/src-tauri/src/state.rs +2 -2
  93. package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +13 -3
  94. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +4 -1
  95. package/corpus/templates/clips/desktop/src-tauri/src/util.rs +7 -13
  96. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +198 -11
  97. package/corpus/templates/clips/desktop/src-tauri/tauri.alpha.conf.json +17 -0
  98. package/corpus/templates/clips/shared/meeting-join-url.ts +0 -5
  99. package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +9 -1
  100. package/corpus/templates/content/AGENTS.md +4 -1
  101. package/corpus/templates/content/actions/_content-spaces.ts +6 -1
  102. package/corpus/templates/content/actions/_database-row-batch.ts +15 -2
  103. package/corpus/templates/content/actions/_database-utils.ts +83 -15
  104. package/corpus/templates/content/actions/add-database-item.ts +3 -0
  105. package/corpus/templates/content/actions/connect-local-folder-source.ts +2 -1
  106. package/corpus/templates/content/actions/delete-content-database.ts +12 -9
  107. package/corpus/templates/content/actions/delete-database-items.ts +3 -2
  108. package/corpus/templates/content/actions/delete-document.ts +233 -6
  109. package/corpus/templates/content/actions/duplicate-database-item.ts +1 -0
  110. package/corpus/templates/content/actions/get-document.ts +4 -1
  111. package/corpus/templates/content/actions/list-content-databases.ts +1 -0
  112. package/corpus/templates/content/actions/list-documents.ts +1 -0
  113. package/corpus/templates/content/actions/list-trashed-content-databases.ts +8 -2
  114. package/corpus/templates/content/actions/list-trashed-documents.ts +50 -0
  115. package/corpus/templates/content/actions/permanently-delete-document.ts +28 -0
  116. package/corpus/templates/content/actions/pull-document.ts +15 -2
  117. package/corpus/templates/content/actions/restore-content-database.ts +48 -11
  118. package/corpus/templates/content/actions/restore-document.ts +28 -0
  119. package/corpus/templates/content/actions/search-documents.ts +2 -1
  120. package/corpus/templates/content/actions/view-screen.ts +2 -1
  121. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +149 -55
  122. package/corpus/templates/content/app/components/editor/database/GalleryView.tsx +7 -2
  123. package/corpus/templates/content/app/components/editor/database/ListView.tsx +7 -2
  124. package/corpus/templates/content/app/components/editor/database/TimelineView.tsx +3 -0
  125. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +26 -5
  126. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +243 -163
  127. package/corpus/templates/content/app/components/sidebar/WorkspaceSourceMenu.tsx +154 -0
  128. package/corpus/templates/content/app/components/sidebar/select-content-space.ts +11 -0
  129. package/corpus/templates/content/app/hooks/use-content-database.ts +6 -0
  130. package/corpus/templates/content/app/hooks/use-documents.ts +57 -0
  131. package/corpus/templates/content/app/i18n-data.ts +83 -2
  132. package/corpus/templates/content/app/routes/_app.local-files.tsx +8 -1
  133. package/corpus/templates/content/changelog/2026-07-19-pages-now-move-to-a-reversible-trash-and-the-organization-pi.md +6 -0
  134. package/corpus/templates/content/changelog/2026-07-20-trash-actions-now-preserve-independent-archived-pages-enforc.md +6 -0
  135. package/corpus/templates/content/changelog/2026-07-20-workspace-toggles-now-stay-independently-open-or-closed-and-.md +6 -0
  136. package/corpus/templates/content/changelog/2026-07-20-workspaces-can-be-added-from-a-blank-workspace-or-a-connecte.md +6 -0
  137. package/corpus/templates/content/parity/matrix.md +1 -1
  138. package/corpus/templates/content/parity/matrix.ts +3 -0
  139. package/corpus/templates/content/server/db/schema.ts +2 -0
  140. package/corpus/templates/content/server/lib/public-documents.ts +8 -2
  141. package/corpus/templates/content/server/plugins/db.ts +52 -0
  142. package/corpus/templates/content/server/routes/api/document-agent-context.json.get.ts +2 -2
  143. package/corpus/templates/content/shared/api.ts +10 -0
  144. package/corpus/toolkit/CHANGELOG.md +6 -0
  145. package/corpus/toolkit/package.json +1 -1
  146. package/corpus/toolkit/src/ui/progress.tsx +3 -2
  147. package/dist/cli/mcp-config-writers.d.ts +2 -2
  148. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  149. package/dist/cli/mcp-config-writers.js +6 -6
  150. package/dist/cli/mcp-config-writers.js.map +1 -1
  151. package/dist/cli/mcp.d.ts +14 -0
  152. package/dist/cli/mcp.d.ts.map +1 -1
  153. package/dist/cli/mcp.js +79 -0
  154. package/dist/cli/mcp.js.map +1 -1
  155. package/dist/cli/skills-content/help.d.ts +1 -1
  156. package/dist/cli/skills-content/help.d.ts.map +1 -1
  157. package/dist/cli/skills-content/help.js +4 -3
  158. package/dist/cli/skills-content/help.js.map +1 -1
  159. package/dist/cli/skills-content/index.d.ts +1 -0
  160. package/dist/cli/skills-content/index.d.ts.map +1 -1
  161. package/dist/cli/skills-content/index.js +1 -0
  162. package/dist/cli/skills-content/index.js.map +1 -1
  163. package/dist/cli/skills-content/rewind-skill.d.ts +2 -0
  164. package/dist/cli/skills-content/rewind-skill.d.ts.map +1 -0
  165. package/dist/cli/skills-content/rewind-skill.js +53 -0
  166. package/dist/cli/skills-content/rewind-skill.js.map +1 -0
  167. package/dist/cli/skills.d.ts +6 -0
  168. package/dist/cli/skills.d.ts.map +1 -1
  169. package/dist/cli/skills.js +90 -14
  170. package/dist/cli/skills.js.map +1 -1
  171. package/dist/client/resources/ResourceTree.d.ts +3 -1
  172. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  173. package/dist/client/resources/ResourceTree.js +4 -4
  174. package/dist/client/resources/ResourceTree.js.map +1 -1
  175. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  176. package/dist/client/resources/ResourcesPanel.js +55 -6
  177. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  178. package/dist/collab/routes.d.ts +1 -1
  179. package/dist/collab/struct-routes.d.ts +1 -1
  180. package/dist/mcp/screen-memory-stdio.d.ts +365 -0
  181. package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
  182. package/dist/mcp/screen-memory-stdio.js +1014 -91
  183. package/dist/mcp/screen-memory-stdio.js.map +1 -1
  184. package/dist/mcp-client/index.d.ts +1 -1
  185. package/dist/mcp-client/index.d.ts.map +1 -1
  186. package/dist/mcp-client/index.js +1 -1
  187. package/dist/mcp-client/index.js.map +1 -1
  188. package/dist/mcp-client/screen-memory-local.d.ts +90 -0
  189. package/dist/mcp-client/screen-memory-local.d.ts.map +1 -1
  190. package/dist/mcp-client/screen-memory-local.js +590 -12
  191. package/dist/mcp-client/screen-memory-local.js.map +1 -1
  192. package/dist/notifications/routes.d.ts +2 -2
  193. package/dist/observability/routes.d.ts +5 -5
  194. package/dist/progress/routes.d.ts +1 -1
  195. package/dist/provider-api/actions/provider-api.d.ts +4 -4
  196. package/dist/resources/handlers.d.ts +1 -1
  197. package/dist/secrets/routes.d.ts +9 -9
  198. package/dist/server/transcribe-voice.d.ts +1 -1
  199. package/package.json +2 -2
  200. package/src/cli/mcp-config-writers.ts +6 -4
  201. package/src/cli/mcp.ts +124 -0
  202. package/src/cli/skills-content/help.ts +4 -3
  203. package/src/cli/skills-content/index.ts +1 -0
  204. package/src/cli/skills-content/rewind-skill.ts +52 -0
  205. package/src/cli/skills.ts +115 -13
  206. package/src/client/resources/ResourceTree.tsx +11 -5
  207. package/src/client/resources/ResourcesPanel.tsx +141 -18
  208. package/src/mcp/screen-memory-stdio.ts +1360 -104
  209. package/src/mcp-client/index.ts +9 -0
  210. package/src/mcp-client/screen-memory-local.ts +847 -13
@@ -0,0 +1,9 @@
1
+ export const REWIND_AGENT_PROMPT = `Set up Agent Native Rewind for this agent once so I can later say things like “Look at Rewind” or “What did I just say?” without pasting setup instructions again.
2
+
3
+ Install or refresh the public Rewind skill and its local Clips Screen Memory MCP connection with:
4
+
5
+ \`npx -y @agent-native/core@latest skills add rewind --client <client> --scope user --yes\`
6
+
7
+ Replace \`<client>\` with the compatible host you are running in: \`codex\`, \`claude-code\`, \`cursor\`, \`opencode\`, \`github-copilot\`, or \`cowork\`. Run the command yourself if you have shell access. Ask me to restart the host only if it cannot reload MCP servers in place, then verify the connection with \`screen_memory_status\`.
8
+
9
+ If this host cannot install skills or MCP servers, explain that limitation clearly. For this request only, use any already-configured Screen Memory tools with the same local-first boundaries: search chapters before raw context, read the smallest relevant range, flag uncertainty, inspect local frames before escalation, never crawl Clips' archive paths, and request a bounded private Clip only when local evidence is insufficient.`;
@@ -0,0 +1,20 @@
1
+ export interface RewindRecordingStartPhases<TPrepared, TStarted> {
2
+ prepare(): Promise<TPrepared>;
3
+ countdown(): Promise<void>;
4
+ activate(prepared: TPrepared): Promise<TStarted>;
5
+ onActivated?(): void;
6
+ }
7
+
8
+ /**
9
+ * Keep setup work ahead of the numeric countdown so zero is a media boundary,
10
+ * not the beginning of another asynchronous setup pipeline.
11
+ */
12
+ export async function prepareRewindRecordingStart<TPrepared, TStarted>(
13
+ phases: RewindRecordingStartPhases<TPrepared, TStarted>,
14
+ ): Promise<TStarted> {
15
+ const prepared = await phases.prepare();
16
+ await phases.countdown();
17
+ const started = await phases.activate(prepared);
18
+ phases.onActivated?.();
19
+ return started;
20
+ }
@@ -11,6 +11,7 @@ import { FlowBar } from "./overlays/flow-bar";
11
11
  import { MeetingNotification } from "./overlays/meeting-notification";
12
12
  import { MeetingNub } from "./overlays/meeting-nub";
13
13
  import { Onboarding } from "./overlays/onboarding";
14
+ import { Preparing } from "./overlays/preparing";
14
15
  import { RecordingPill } from "./overlays/recording-pill";
15
16
  import { RegionGuideEditor, RegionGuides } from "./overlays/region-guides";
16
17
  import { RegionRecordBorder } from "./overlays/region-record-border";
@@ -43,6 +44,8 @@ function pickRoute(route: string): React.ReactElement {
43
44
  return <Bubble />;
44
45
  case "finalizing":
45
46
  return <Finalizing />;
47
+ case "preparing":
48
+ return <Preparing />;
46
49
  case "onboarding":
47
50
  return <Onboarding />;
48
51
  case "meeting-notif":
@@ -15,16 +15,17 @@ export function Countdown() {
15
15
  const closingRef = useRef(false);
16
16
 
17
17
  const closeWithEvent = useCallback(
18
- (eventName: "clips:countdown-done" | "clips:countdown-cancel") => {
18
+ (
19
+ eventName: "clips:countdown-done" | "clips:countdown-cancel",
20
+ cause: "escape" | "return" | "button" | "timer",
21
+ ) => {
19
22
  if (closingRef.current) return;
20
23
  closingRef.current = true;
21
- emit(eventName)
22
- .finally(() => emit("clips:countdown-shortcuts-active", false))
23
- .finally(() => {
24
- getCurrentWindow()
25
- .close()
26
- .catch(() => {});
27
- });
24
+ emit(eventName, { cause }).finally(() => {
25
+ getCurrentWindow()
26
+ .close()
27
+ .catch(() => {});
28
+ });
28
29
  },
29
30
  [],
30
31
  );
@@ -33,22 +34,21 @@ export function Countdown() {
33
34
  const onKeyDown = (event: KeyboardEvent) => {
34
35
  if (event.key === "Escape") {
35
36
  event.preventDefault();
36
- closeWithEvent("clips:countdown-cancel");
37
+ closeWithEvent("clips:countdown-cancel", "escape");
37
38
  } else if (event.key === "Enter") {
38
39
  event.preventDefault();
39
- closeWithEvent("clips:countdown-done");
40
+ closeWithEvent("clips:countdown-done", "return");
40
41
  }
41
42
  };
42
43
  window.addEventListener("keydown", onKeyDown);
43
44
  return () => {
44
45
  window.removeEventListener("keydown", onKeyDown);
45
- emit("clips:countdown-shortcuts-active", false).catch(() => {});
46
46
  };
47
47
  }, [closeWithEvent]);
48
48
 
49
49
  useEffect(() => {
50
50
  if (n <= 0) {
51
- closeWithEvent("clips:countdown-done");
51
+ closeWithEvent("clips:countdown-done", "timer");
52
52
  return;
53
53
  }
54
54
  const t = setTimeout(() => setN((v) => v - 1), COUNTDOWN_STEP_MS);
@@ -62,7 +62,7 @@ export function Countdown() {
62
62
  type="button"
63
63
  className="countdown-control countdown-control-cancel"
64
64
  aria-label="Cancel recording"
65
- onClick={() => closeWithEvent("clips:countdown-cancel")}
65
+ onClick={() => closeWithEvent("clips:countdown-cancel", "button")}
66
66
  >
67
67
  <IconX size={30} stroke={2.4} />
68
68
  </button>
@@ -75,7 +75,7 @@ export function Countdown() {
75
75
  type="button"
76
76
  className="countdown-control countdown-control-skip"
77
77
  aria-label="Skip countdown and start recording now"
78
- onClick={() => closeWithEvent("clips:countdown-done")}
78
+ onClick={() => closeWithEvent("clips:countdown-done", "button")}
79
79
  >
80
80
  <IconPlayerSkipForwardFilled size={28} />
81
81
  </button>
@@ -9,16 +9,15 @@ import { invoke } from "@tauri-apps/api/core";
9
9
  import { LogicalSize } from "@tauri-apps/api/dpi";
10
10
  import { emit, listen } from "@tauri-apps/api/event";
11
11
  import { getCurrentWindow } from "@tauri-apps/api/window";
12
- import { open as openExternal } from "@tauri-apps/plugin-shell";
13
12
  import { useEffect, useRef, useState } from "react";
14
13
 
15
- import { resolveDesktopMeetingJoinUrl } from "../lib/meeting-join-url";
16
14
  import {
17
15
  detectMeetingJoinProvider,
18
16
  joinProviderLabel,
19
17
  meetingNotificationAutoHideMs,
20
18
  type MeetingJoinProvider,
21
19
  } from "../lib/meeting-notification-timing";
20
+ import { openMeetingJoinUrl } from "../lib/open-meeting-join-url";
22
21
 
23
22
  interface NotificationData {
24
23
  type: "calendar" | "adhoc";
@@ -51,7 +50,7 @@ const NOTIFICATION_MENU_HEIGHT = 224;
51
50
  async function openJoinUrl(url: string | null | undefined): Promise<void> {
52
51
  if (!url) return;
53
52
  try {
54
- await openExternal(resolveDesktopMeetingJoinUrl(url));
53
+ await openMeetingJoinUrl(url);
55
54
  } catch (err) {
56
55
  console.error("[clips-tray] openJoinUrl failed:", err);
57
56
  }
@@ -56,13 +56,13 @@ const PERMISSION_CARDS: Array<{
56
56
  // fails — same URLs the main app window uses.
57
57
  const MACOS_PRIVACY_URLS: Record<PermissionPane, string> = {
58
58
  microphone:
59
- "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone",
59
+ "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?Privacy_Microphone",
60
60
  speech:
61
- "x-apple.systempreferences:com.apple.preference.security?Privacy_SpeechRecognition",
61
+ "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?Privacy_SpeechRecognition",
62
62
  accessibility:
63
- "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility",
63
+ "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?Privacy_Accessibility",
64
64
  "input-monitoring":
65
- "x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent",
65
+ "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?Privacy_ListenEvent",
66
66
  };
67
67
 
68
68
  function openPermissionSettings(pane: PermissionPane): void {
@@ -0,0 +1,13 @@
1
+ /** Visible readiness state shown while the shared Rewind Clip writer and
2
+ * resumable upload session are prepared. The numeric countdown replaces it
3
+ * only after zero can be an immediate media boundary. */
4
+ export function Preparing() {
5
+ return (
6
+ <div className="preparing-root">
7
+ <div className="preparing-card" role="status" aria-live="polite">
8
+ <div className="preparing-spinner" aria-hidden="true" />
9
+ <span>Preparing recording…</span>
10
+ </div>
11
+ </div>
12
+ );
13
+ }
@@ -6,6 +6,7 @@ import {
6
6
  IconRefresh,
7
7
  IconTrash,
8
8
  } from "@tabler/icons-react";
9
+ import { invoke } from "@tauri-apps/api/core";
9
10
  import { LogicalSize } from "@tauri-apps/api/dpi";
10
11
  import { emit, listen } from "@tauri-apps/api/event";
11
12
  import { getCurrentWindow } from "@tauri-apps/api/window";
@@ -58,6 +59,8 @@ export function Toolbar() {
58
59
  // Stop / Pause are disabled until the recorder actually begins, at which
59
60
  // point `clips:toolbar-enabled` fires with `true` from the recorder.
60
61
  const [enabled, setEnabled] = useState(false);
62
+ const [preparing, setPreparing] = useState(false);
63
+ const [popoverVisible, setPopoverVisible] = useState(true);
61
64
  const [diskSpaceLevel, setDiskSpaceLevel] = useState<
62
65
  "ok" | "warning" | "critical"
63
66
  >("ok");
@@ -121,6 +124,7 @@ export function Toolbar() {
121
124
  trackListen(
122
125
  listen<boolean>("clips:toolbar-enabled", (ev) => {
123
126
  setEnabled(!!ev.payload);
127
+ setPreparing(false);
124
128
  setPendingAction(null);
125
129
  if (!ev.payload) {
126
130
  setDiskSpaceLevel("ok");
@@ -129,6 +133,16 @@ export function Toolbar() {
129
133
  }
130
134
  }),
131
135
  );
136
+ trackListen(
137
+ listen<boolean>("clips:toolbar-preparing", (ev) => {
138
+ setPreparing(!!ev.payload);
139
+ }),
140
+ );
141
+ trackListen(
142
+ listen<boolean>("clips:popover-visible", (ev) => {
143
+ setPopoverVisible(!!ev.payload);
144
+ }),
145
+ );
132
146
  trackListen(
133
147
  listen<{ freeMb: number }>("clips:disk-space-warning", () => {
134
148
  setDiskSpaceLevel((prev) =>
@@ -205,6 +219,8 @@ export function Toolbar() {
205
219
  // left with a zombie pill floating over their screen. The recorder
206
220
  // closing us first is a no-op on the already-closed window.
207
221
  }
222
+
223
+ const isPreparing = preparing || (!enabled && !popoverVisible);
208
224
  function togglePause() {
209
225
  if (!enabled || pendingAction) return;
210
226
  const transition = paused ? "resume" : "pause";
@@ -319,13 +335,22 @@ export function Toolbar() {
319
335
  }
320
336
  data-no-drag
321
337
  >
322
- {pendingAction === "stop" ? (
338
+ {pendingAction === "stop" || isPreparing ? (
323
339
  <IconLoader2 className="toolbar-v-spinner" size={18} />
324
340
  ) : (
325
341
  <span className="toolbar-v-stop-square" />
326
342
  )}
327
343
  </button>
328
- <div className="toolbar-v-time">{formatTime(elapsed)}</div>
344
+ <button
345
+ type="button"
346
+ className={`toolbar-v-time ${isPreparing ? "toolbar-v-time-preparing" : ""}`}
347
+ onClick={() => invoke("show_popover").catch(() => {})}
348
+ aria-label="Open Clips"
349
+ title="Open Clips"
350
+ data-no-drag
351
+ >
352
+ {isPreparing ? "Preparing…" : formatTime(elapsed)}
353
+ </button>
329
354
  {diskSpaceLevel !== "ok" && (
330
355
  <div
331
356
  className={`toolbar-v-disk-indicator toolbar-v-disk-indicator-${diskSpaceLevel}`}
@@ -3,6 +3,12 @@ import { listen } from "@tauri-apps/api/event";
3
3
  import { useState, useEffect } from "react";
4
4
 
5
5
  export type LocalRecordingMode = "off" | "composed" | "separate";
6
+ export type RewindCaptureMode = "visuals" | "visuals-audio";
7
+ export type RewindAgentClipRetention =
8
+ | "forever"
9
+ | "24-hours"
10
+ | "7-days"
11
+ | "30-days";
6
12
 
7
13
  export interface RegionGuideRect {
8
14
  id: string;
@@ -25,6 +31,12 @@ export interface ScreenMemoryConfig {
25
31
  maxBytes: number;
26
32
  segmentSeconds: number;
27
33
  sampleIntervalSeconds: number;
34
+ captureMode: RewindCaptureMode;
35
+ reviewBeforeSending: boolean;
36
+ autoPreviewBeforeSending: boolean;
37
+ agentClipRetention: RewindAgentClipRetention;
38
+ excludedBundleIds: string[];
39
+ excludePrivateWindows: boolean;
28
40
  }
29
41
 
30
42
  export type ScreenMemoryRuntimeState =
@@ -44,6 +56,8 @@ export interface ScreenMemorySegmentMetadata {
44
56
  width?: number | null;
45
57
  height?: number | null;
46
58
  bytes: number;
59
+ systemAudioPath?: string | null;
60
+ microphonePath?: string | null;
47
61
  corrupt: boolean;
48
62
  error?: string | null;
49
63
  }
@@ -66,6 +80,8 @@ export interface ScreenMemoryStatus {
66
80
  activeSegment?: ScreenMemoryActiveSegment | null;
67
81
  recentSegments: ScreenMemorySegmentMetadata[];
68
82
  lastError?: string | null;
83
+ exclusionActive: boolean;
84
+ coverage: string;
69
85
  }
70
86
 
71
87
  export interface ScreenMemoryDeleteResult {