recappi 0.1.27 → 0.1.28

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.
package/dist/index.js CHANGED
@@ -1415,11 +1415,12 @@ function PermissionPreflightView({
1415
1415
  items
1416
1416
  }) {
1417
1417
  const allGranted = items.length > 0 && items.every((item) => item.status === "granted" && !item.requiresProcessRestart);
1418
+ const hasRestartRequired = items.some((item) => item.requiresProcessRestart);
1418
1419
  return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", paddingX: 1, children: [
1419
1420
  /* @__PURE__ */ jsx15(Text13, { dimColor: true, children: "\u2039 Recording permissions" }),
1420
1421
  /* @__PURE__ */ jsx15(Box13, { marginTop: 1, flexDirection: "column", children: items.length === 0 ? /* @__PURE__ */ jsx15(Text13, { dimColor: true, children: "Checking permissions\u2026" }) : items.map((item) => {
1421
1422
  const status = statusGlyph2(item.status);
1422
- const hint = item.requiresProcessRestart ? "Screen Recording enabled. Run recappi record again to start." : item.status === "granted" ? void 0 : item.hint ?? DEFAULT_HINTS[item.name];
1423
+ const hint = item.requiresProcessRestart ? item.hint ?? `${item.name} enabled. Run recappi record again to start.` : item.status === "granted" ? void 0 : item.hint ?? DEFAULT_HINTS[item.name];
1423
1424
  return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", children: [
1424
1425
  /* @__PURE__ */ jsxs12(Text13, { children: [
1425
1426
  /* @__PURE__ */ jsx15(Text13, { color: status.color, children: status.glyph }),
@@ -1429,7 +1430,7 @@ function PermissionPreflightView({
1429
1430
  hint ? /* @__PURE__ */ jsx15(Text13, { dimColor: true, children: ` ${hint}` }) : null
1430
1431
  ] }, item.name);
1431
1432
  }) }),
1432
- /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: allGranted ? /* @__PURE__ */ jsx15(Text13, { color: "green", children: "All set \u2014 ready to record." }) : /* @__PURE__ */ jsx15(Text13, { dimColor: true, children: "Grant the permissions above, then press r to recheck." }) }),
1433
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: allGranted ? /* @__PURE__ */ jsx15(Text13, { color: "green", children: "All set \u2014 ready to record." }) : hasRestartRequired ? /* @__PURE__ */ jsx15(Text13, { dimColor: true, children: "Run recappi record again to start, or press r to retry." }) : /* @__PURE__ */ jsx15(Text13, { dimColor: true, children: "Grant the permissions above, then press r to recheck." }) }),
1433
1434
  /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(Text13, { dimColor: true, children: "r recheck \xB7 o open System Settings \xB7 esc back" }) })
1434
1435
  ] });
1435
1436
  }
@@ -1439,7 +1440,7 @@ var init_PermissionPreflightView = __esm({
1439
1440
  "use strict";
1440
1441
  DEFAULT_HINTS = {
1441
1442
  "Screen Recording": "Open System Settings \u203A Privacy & Security \u203A Screen Recording, enable Recappi Recorder, then run recappi record again.",
1442
- Microphone: "Open System Settings \u203A Privacy & Security \u203A Microphone, enable Recappi Recorder, then recheck."
1443
+ Microphone: "Open System Settings \u203A Privacy & Security \u203A Microphone, enable Recappi Recorder, then run recappi record again."
1443
1444
  };
1444
1445
  }
1445
1446
  });
@@ -1703,20 +1704,20 @@ function recordErrorCopy(code, message) {
1703
1704
  }
1704
1705
  function recordErrorState(error51, selection) {
1705
1706
  if (error51 instanceof Error) {
1706
- const descriptor = isRecord7(error51) && isRecord7(error51.descriptor) ? error51.descriptor : void 0;
1707
+ const descriptor = isRecord8(error51) && isRecord8(error51.descriptor) ? error51.descriptor : void 0;
1707
1708
  return {
1708
1709
  kind: "error",
1709
1710
  message: error51.message,
1710
1711
  code: typeof descriptor?.code === "string" ? descriptor.code : "code" in error51 && typeof error51.code === "string" ? error51.code : void 0,
1711
- data: isRecord7(error51) ? error51.data : void 0,
1712
+ data: isRecord8(error51) ? error51.data : void 0,
1712
1713
  ...selection ? { selection } : {}
1713
1714
  };
1714
1715
  }
1715
1716
  return { kind: "error", message: String(error51), ...selection ? { selection } : {} };
1716
1717
  }
1717
1718
  function transcribeHandoffErrorCopy(error51) {
1718
- const descriptor = error51 instanceof Error && isRecord7(error51) && isRecord7(error51.descriptor) ? error51.descriptor : void 0;
1719
- const code = typeof descriptor?.code === "string" ? descriptor.code : isRecord7(error51) && typeof error51.code === "string" ? error51.code : void 0;
1719
+ const descriptor = error51 instanceof Error && isRecord8(error51) && isRecord8(error51.descriptor) ? error51.descriptor : void 0;
1720
+ const code = typeof descriptor?.code === "string" ? descriptor.code : isRecord8(error51) && typeof error51.code === "string" ? error51.code : void 0;
1720
1721
  switch (code) {
1721
1722
  case "auth.not_logged_in":
1722
1723
  return "Sign in to Recappi before transcribing this recording.";
@@ -1746,8 +1747,8 @@ function transcribeHandoffErrorCopy(error51) {
1746
1747
  }
1747
1748
  }
1748
1749
  function permissionItemsFromRecordError(data) {
1749
- const sidecarError = isRecord7(data) ? data : void 0;
1750
- const sidecarData = isRecord7(sidecarError?.data) ? sidecarError.data : void 0;
1750
+ const sidecarError = isRecord8(data) ? data : void 0;
1751
+ const sidecarData = isRecord8(sidecarError?.data) ? sidecarError.data : void 0;
1751
1752
  const permission = typeof sidecarData?.permission === "string" ? sidecarData.permission : "";
1752
1753
  const hint = typeof sidecarData?.recovery === "string" ? sidecarData.recovery : void 0;
1753
1754
  const requiresProcessRestart = sidecarData?.requiresProcessRestart === true || sidecarData?.requiresProcessRestart === "true";
@@ -1762,15 +1763,15 @@ function permissionItemsFromRecordError(data) {
1762
1763
  ];
1763
1764
  }
1764
1765
  function settingsUrlFromRecordError(data) {
1765
- const sidecarError = isRecord7(data) ? data : void 0;
1766
- const sidecarData = isRecord7(sidecarError?.data) ? sidecarError.data : void 0;
1766
+ const sidecarError = isRecord8(data) ? data : void 0;
1767
+ const sidecarData = isRecord8(sidecarError?.data) ? sidecarError.data : void 0;
1767
1768
  const permission = typeof sidecarData?.permission === "string" ? sidecarData.permission : "";
1768
1769
  if (permission === "microphone") {
1769
1770
  return "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone";
1770
1771
  }
1771
1772
  return "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture";
1772
1773
  }
1773
- function isRecord7(value) {
1774
+ function isRecord8(value) {
1774
1775
  return typeof value === "object" && value !== null && !Array.isArray(value);
1775
1776
  }
1776
1777
  function AppShell({
@@ -20361,6 +20362,7 @@ init_LiveCaptionsScreen();
20361
20362
  import { jsx as jsx3 } from "react/jsx-runtime";
20362
20363
  var SIDECAR_COMMAND_ENV = "RECAPPI_MINI_SIDECAR";
20363
20364
  var SIDECAR_HELPER_NAME = "RecappiMiniSidecar";
20365
+ var SIDECAR_APP_BUNDLE_NAME = "Recappi Recorder.app";
20364
20366
  var requireFromCli = createRequire2(import.meta.url);
20365
20367
  async function recordViaSidecar(opts) {
20366
20368
  let liveRenderer;
@@ -20439,6 +20441,20 @@ async function listRecordInputs(opts) {
20439
20441
  }
20440
20442
  }
20441
20443
  async function startRecordSession(opts) {
20444
+ let retriedAfterMicrophoneGrant = false;
20445
+ while (true) {
20446
+ try {
20447
+ return await startRecordSessionOnce(opts);
20448
+ } catch (error51) {
20449
+ if (!retriedAfterMicrophoneGrant && isPermissionRestartRequiredError(error51, "microphone")) {
20450
+ retriedAfterMicrophoneGrant = true;
20451
+ continue;
20452
+ }
20453
+ throw error51;
20454
+ }
20455
+ }
20456
+ }
20457
+ async function startRecordSessionOnce(opts) {
20442
20458
  const command = resolveSidecarCommand(opts);
20443
20459
  const sidecarArgs = opts.sidecarArgs ?? [];
20444
20460
  const spawnSidecar = opts.runtime?.spawnSidecar ?? spawnMiniSidecar;
@@ -20542,6 +20558,17 @@ async function startRecordSession(opts) {
20542
20558
  throw error51;
20543
20559
  }
20544
20560
  }
20561
+ function isPermissionRestartRequiredError(error51, permissionName) {
20562
+ const root = isRecord7(error51) ? error51 : void 0;
20563
+ const descriptor = isRecord7(root?.descriptor) ? root.descriptor : void 0;
20564
+ if (descriptor?.code !== "record.permission_required") return false;
20565
+ const sidecarError = isRecord7(root?.data) ? root.data : void 0;
20566
+ const sidecarData = isRecord7(sidecarError?.data) ? sidecarError.data : void 0;
20567
+ return sidecarData?.permission === permissionName && (sidecarData.requiresProcessRestart === true || sidecarData.requiresProcessRestart === "true");
20568
+ }
20569
+ function isRecord7(value) {
20570
+ return typeof value === "object" && value !== null && !Array.isArray(value);
20571
+ }
20545
20572
  function normalizeSidecarSources(sources) {
20546
20573
  const seen = /* @__PURE__ */ new Set();
20547
20574
  const out = [];
@@ -20658,7 +20685,7 @@ function bundledSidecarCommand(platform, arch) {
20658
20685
  return fileURLToPath(new URL(`helpers/${platform}-${arch}/${executable}`, packageRoot));
20659
20686
  }
20660
20687
  function helperExecutableName(platform) {
20661
- if (platform === "darwin") return `${SIDECAR_HELPER_NAME}.app`;
20688
+ if (platform === "darwin") return SIDECAR_APP_BUNDLE_NAME;
20662
20689
  if (platform === "win32") return `${SIDECAR_HELPER_NAME}.exe`;
20663
20690
  return null;
20664
20691
  }