recappi 0.1.25 → 0.1.26
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 +115 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1414,12 +1414,12 @@ function statusGlyph2(status) {
|
|
|
1414
1414
|
function PermissionPreflightView({
|
|
1415
1415
|
items
|
|
1416
1416
|
}) {
|
|
1417
|
-
const allGranted = items.length > 0 && items.every((item) => item.status === "granted");
|
|
1417
|
+
const allGranted = items.length > 0 && items.every((item) => item.status === "granted" && !item.requiresProcessRestart);
|
|
1418
1418
|
return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", paddingX: 1, children: [
|
|
1419
1419
|
/* @__PURE__ */ jsx15(Text13, { dimColor: true, children: "\u2039 Recording permissions" }),
|
|
1420
1420
|
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, flexDirection: "column", children: items.length === 0 ? /* @__PURE__ */ jsx15(Text13, { dimColor: true, children: "Checking permissions\u2026" }) : items.map((item) => {
|
|
1421
1421
|
const status = statusGlyph2(item.status);
|
|
1422
|
-
const hint = item.status === "granted" ? void 0 : item.hint ?? DEFAULT_HINTS[item.name];
|
|
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
1423
|
return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", children: [
|
|
1424
1424
|
/* @__PURE__ */ jsxs12(Text13, { children: [
|
|
1425
1425
|
/* @__PURE__ */ jsx15(Text13, { color: status.color, children: status.glyph }),
|
|
@@ -1438,8 +1438,8 @@ var init_PermissionPreflightView = __esm({
|
|
|
1438
1438
|
"src/tui/PermissionPreflightView.tsx"() {
|
|
1439
1439
|
"use strict";
|
|
1440
1440
|
DEFAULT_HINTS = {
|
|
1441
|
-
"Screen Recording": "Open System Settings \u203A Privacy & Security \u203A Screen Recording, enable
|
|
1442
|
-
Microphone: "Open System Settings \u203A Privacy & Security \u203A Microphone, enable
|
|
1441
|
+
"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
1443
|
};
|
|
1444
1444
|
}
|
|
1445
1445
|
});
|
|
@@ -1688,7 +1688,7 @@ function recordErrorCopy(code, message) {
|
|
|
1688
1688
|
case "record.permission_required":
|
|
1689
1689
|
return {
|
|
1690
1690
|
title: "Recording needs macOS permission first.",
|
|
1691
|
-
detail: "Open System Settings > Privacy & Security, allow recording access, then
|
|
1691
|
+
detail: "Open System Settings > Privacy & Security, allow recording access, then run recappi record again.",
|
|
1692
1692
|
tone: "yellow"
|
|
1693
1693
|
};
|
|
1694
1694
|
case "record.capture_failed":
|
|
@@ -1750,8 +1750,16 @@ function permissionItemsFromRecordError(data) {
|
|
|
1750
1750
|
const sidecarData = isRecord7(sidecarError?.data) ? sidecarError.data : void 0;
|
|
1751
1751
|
const permission = typeof sidecarData?.permission === "string" ? sidecarData.permission : "";
|
|
1752
1752
|
const hint = typeof sidecarData?.recovery === "string" ? sidecarData.recovery : void 0;
|
|
1753
|
+
const requiresProcessRestart = sidecarData?.requiresProcessRestart === true || sidecarData?.requiresProcessRestart === "true";
|
|
1753
1754
|
const item = permission === "microphone" ? "Microphone" : permission === "screen_recording" ? "Screen Recording" : "Recording";
|
|
1754
|
-
return [
|
|
1755
|
+
return [
|
|
1756
|
+
{
|
|
1757
|
+
name: item,
|
|
1758
|
+
status: requiresProcessRestart ? "granted" : "denied",
|
|
1759
|
+
...hint ? { hint } : {},
|
|
1760
|
+
...requiresProcessRestart ? { requiresProcessRestart } : {}
|
|
1761
|
+
}
|
|
1762
|
+
];
|
|
1755
1763
|
}
|
|
1756
1764
|
function settingsUrlFromRecordError(data) {
|
|
1757
1765
|
const sidecarError = isRecord7(data) ? data : void 0;
|
|
@@ -17139,7 +17147,8 @@ var sidecarPermissionStatusSchema = external_exports.enum(["granted", "denied",
|
|
|
17139
17147
|
var sidecarPermissionItemSchema = external_exports.object({
|
|
17140
17148
|
name: sidecarPermissionNameSchema,
|
|
17141
17149
|
status: sidecarPermissionStatusSchema,
|
|
17142
|
-
hint: external_exports.string().optional()
|
|
17150
|
+
hint: external_exports.string().optional(),
|
|
17151
|
+
requiresProcessRestart: external_exports.boolean().optional()
|
|
17143
17152
|
});
|
|
17144
17153
|
var sidecarPermissionStatusParamsSchema = external_exports.object({
|
|
17145
17154
|
options: sidecarRecordingOptionsSchema
|
|
@@ -17289,10 +17298,11 @@ var sidecarEventSchema = external_exports.discriminatedUnion("type", [
|
|
|
17289
17298
|
external_exports.object({
|
|
17290
17299
|
type: external_exports.literal("audio.level"),
|
|
17291
17300
|
sessionId: external_exports.string(),
|
|
17292
|
-
input: external_exports.enum(["system", "microphone"
|
|
17301
|
+
input: external_exports.enum(["system", "microphone"]),
|
|
17293
17302
|
rmsDb: external_exports.number().optional(),
|
|
17294
17303
|
peakDb: external_exports.number().optional(),
|
|
17295
|
-
at: external_exports.number().int().optional()
|
|
17304
|
+
at: external_exports.number().int().optional(),
|
|
17305
|
+
atMs: external_exports.number().int().optional()
|
|
17296
17306
|
}),
|
|
17297
17307
|
external_exports.object({
|
|
17298
17308
|
type: external_exports.literal("live_caption.delta"),
|
|
@@ -20049,13 +20059,16 @@ var CLI_VERSION = readCliVersion();
|
|
|
20049
20059
|
// src/record.tsx
|
|
20050
20060
|
import { chmodSync, existsSync, statSync } from "fs";
|
|
20051
20061
|
import { createRequire as createRequire2 } from "module";
|
|
20052
|
-
import { dirname, join } from "path";
|
|
20062
|
+
import { dirname, join as join2 } from "path";
|
|
20053
20063
|
import { fileURLToPath } from "url";
|
|
20054
20064
|
import { render, useInput as useInput2 } from "ink";
|
|
20055
20065
|
init_recordingCore();
|
|
20056
20066
|
|
|
20057
20067
|
// src/sidecar.ts
|
|
20058
|
-
import { spawn as spawn2 } from "child_process";
|
|
20068
|
+
import { spawn as spawn2, spawnSync } from "child_process";
|
|
20069
|
+
import { createReadStream, createWriteStream as createWriteStream2, mkdtempSync, rmSync } from "fs";
|
|
20070
|
+
import { tmpdir } from "os";
|
|
20071
|
+
import { join } from "path";
|
|
20059
20072
|
import { createInterface } from "readline";
|
|
20060
20073
|
var MiniSidecarClient = class {
|
|
20061
20074
|
input;
|
|
@@ -20248,6 +20261,9 @@ function isRecord6(value) {
|
|
|
20248
20261
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20249
20262
|
}
|
|
20250
20263
|
function spawnMiniSidecar(opts) {
|
|
20264
|
+
if (isLaunchServicesAppCommand(opts.command)) {
|
|
20265
|
+
return spawnLaunchServicesSidecar(opts);
|
|
20266
|
+
}
|
|
20251
20267
|
const spawnProcess = opts.spawnProcess ?? spawn2;
|
|
20252
20268
|
const child = spawnProcess(opts.command, opts.args ?? [], {
|
|
20253
20269
|
env: opts.env,
|
|
@@ -20272,6 +20288,73 @@ function defaultSidecarHandshakeParams(params) {
|
|
|
20272
20288
|
...params
|
|
20273
20289
|
};
|
|
20274
20290
|
}
|
|
20291
|
+
function isLaunchServicesAppCommand(command, platform = process.platform) {
|
|
20292
|
+
return platform === "darwin" && command.endsWith(".app");
|
|
20293
|
+
}
|
|
20294
|
+
function launchServicesOpenArgs(appPath, pipes, sidecarArgs = []) {
|
|
20295
|
+
return [
|
|
20296
|
+
"-W",
|
|
20297
|
+
"-n",
|
|
20298
|
+
"-g",
|
|
20299
|
+
"--stdin",
|
|
20300
|
+
pipes.stdin,
|
|
20301
|
+
"--stdout",
|
|
20302
|
+
pipes.stdout,
|
|
20303
|
+
"--stderr",
|
|
20304
|
+
pipes.stderr,
|
|
20305
|
+
appPath,
|
|
20306
|
+
"--args",
|
|
20307
|
+
...sidecarArgs
|
|
20308
|
+
];
|
|
20309
|
+
}
|
|
20310
|
+
function spawnLaunchServicesSidecar(opts) {
|
|
20311
|
+
const spawnProcess = opts.spawnProcess ?? spawn2;
|
|
20312
|
+
const tempDir = mkdtempSync(join(tmpdir(), "recappi-sidecar-"));
|
|
20313
|
+
const pipes = {
|
|
20314
|
+
stdin: join(tempDir, "stdin.fifo"),
|
|
20315
|
+
stdout: join(tempDir, "stdout.fifo"),
|
|
20316
|
+
stderr: join(tempDir, "stderr.log")
|
|
20317
|
+
};
|
|
20318
|
+
createFifo(pipes.stdin);
|
|
20319
|
+
createFifo(pipes.stdout);
|
|
20320
|
+
const output = createReadStream(pipes.stdout);
|
|
20321
|
+
const input = createWriteStream2(pipes.stdin);
|
|
20322
|
+
const child = spawnProcess("open", launchServicesOpenArgs(opts.command, pipes, opts.args ?? []), {
|
|
20323
|
+
env: opts.env,
|
|
20324
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
20325
|
+
});
|
|
20326
|
+
const client = new MiniSidecarClient({
|
|
20327
|
+
input,
|
|
20328
|
+
output,
|
|
20329
|
+
requestTimeoutMs: opts.requestTimeoutMs
|
|
20330
|
+
});
|
|
20331
|
+
let cleaned = false;
|
|
20332
|
+
const cleanup = () => {
|
|
20333
|
+
if (cleaned) return;
|
|
20334
|
+
cleaned = true;
|
|
20335
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
20336
|
+
};
|
|
20337
|
+
child.once("exit", cleanup);
|
|
20338
|
+
child.once("error", cleanup);
|
|
20339
|
+
return {
|
|
20340
|
+
client,
|
|
20341
|
+
kill: () => {
|
|
20342
|
+
client.close();
|
|
20343
|
+
input.end();
|
|
20344
|
+
output.destroy();
|
|
20345
|
+
child.kill();
|
|
20346
|
+
cleanup();
|
|
20347
|
+
}
|
|
20348
|
+
};
|
|
20349
|
+
}
|
|
20350
|
+
function createFifo(path6) {
|
|
20351
|
+
const result = spawnSync("mkfifo", [path6], { encoding: "utf8" });
|
|
20352
|
+
if (result.status !== 0) {
|
|
20353
|
+
throw cliError("record.helper_unavailable", "Recappi recording helper could not start.", {
|
|
20354
|
+
hint: result.stderr || "Could not create the local recorder pipes. Try again."
|
|
20355
|
+
});
|
|
20356
|
+
}
|
|
20357
|
+
}
|
|
20275
20358
|
|
|
20276
20359
|
// src/record.tsx
|
|
20277
20360
|
init_LiveCaptionsScreen();
|
|
@@ -20496,6 +20579,7 @@ function assertRecordingPermissions(permissions) {
|
|
|
20496
20579
|
data: {
|
|
20497
20580
|
cliCode: "record.permission_required",
|
|
20498
20581
|
permission: blocked.name,
|
|
20582
|
+
...blocked.requiresProcessRestart ? { requiresProcessRestart: blocked.requiresProcessRestart } : {},
|
|
20499
20583
|
...blocked.hint ? { recovery: blocked.hint } : {},
|
|
20500
20584
|
permissions
|
|
20501
20585
|
}
|
|
@@ -20532,9 +20616,23 @@ function resolveSidecarCommand(opts) {
|
|
|
20532
20616
|
});
|
|
20533
20617
|
}
|
|
20534
20618
|
function ensureBundledHelperExecutable(path6) {
|
|
20619
|
+
if (process.platform === "darwin" && path6.endsWith(".app")) {
|
|
20620
|
+
const executable = darwinAppExecutablePath(path6);
|
|
20621
|
+
if (!existsSync(executable)) {
|
|
20622
|
+
throw cliError("record.helper_unavailable", "Recappi recording helper is not available.", {
|
|
20623
|
+
hint: `Expected bundled helper executable inside ${path6}. Reinstall recappi, or set ${SIDECAR_COMMAND_ENV} to a compatible helper.`
|
|
20624
|
+
});
|
|
20625
|
+
}
|
|
20626
|
+
ensureExecutableMode(executable);
|
|
20627
|
+
return path6;
|
|
20628
|
+
}
|
|
20535
20629
|
if (process.platform === "win32") return path6;
|
|
20630
|
+
ensureExecutableMode(path6);
|
|
20631
|
+
return path6;
|
|
20632
|
+
}
|
|
20633
|
+
function ensureExecutableMode(path6) {
|
|
20536
20634
|
const mode = statSync(path6).mode;
|
|
20537
|
-
if ((mode & 73) !== 0) return
|
|
20635
|
+
if ((mode & 73) !== 0) return;
|
|
20538
20636
|
try {
|
|
20539
20637
|
chmodSync(path6, mode | 493);
|
|
20540
20638
|
} catch (error51) {
|
|
@@ -20543,7 +20641,6 @@ function ensureBundledHelperExecutable(path6) {
|
|
|
20543
20641
|
hint: `Could not make bundled helper executable at ${path6}: ${message}. Reinstall recappi, or set ${SIDECAR_COMMAND_ENV} to a compatible helper.`
|
|
20544
20642
|
});
|
|
20545
20643
|
}
|
|
20546
|
-
return path6;
|
|
20547
20644
|
}
|
|
20548
20645
|
function bundledSidecarCommand(platform, arch) {
|
|
20549
20646
|
const executable = helperExecutableName(platform);
|
|
@@ -20551,16 +20648,19 @@ function bundledSidecarCommand(platform, arch) {
|
|
|
20551
20648
|
const helperPackage = helperPackageName(platform, arch);
|
|
20552
20649
|
if (helperPackage) {
|
|
20553
20650
|
const packageJson = resolveOptionalHelperPackage(helperPackage);
|
|
20554
|
-
if (packageJson) return
|
|
20651
|
+
if (packageJson) return join2(dirname(packageJson), executable);
|
|
20555
20652
|
}
|
|
20556
20653
|
const packageRoot = new URL("..", import.meta.url);
|
|
20557
20654
|
return fileURLToPath(new URL(`helpers/${platform}-${arch}/${executable}`, packageRoot));
|
|
20558
20655
|
}
|
|
20559
20656
|
function helperExecutableName(platform) {
|
|
20560
|
-
if (platform === "darwin") return SIDECAR_HELPER_NAME
|
|
20657
|
+
if (platform === "darwin") return `${SIDECAR_HELPER_NAME}.app`;
|
|
20561
20658
|
if (platform === "win32") return `${SIDECAR_HELPER_NAME}.exe`;
|
|
20562
20659
|
return null;
|
|
20563
20660
|
}
|
|
20661
|
+
function darwinAppExecutablePath(appPath) {
|
|
20662
|
+
return join2(appPath, "Contents", "MacOS", SIDECAR_HELPER_NAME);
|
|
20663
|
+
}
|
|
20564
20664
|
function helperPackageName(platform, arch) {
|
|
20565
20665
|
if (platform === "darwin" && arch === "arm64") return "recappi-helper-darwin-arm64";
|
|
20566
20666
|
return null;
|