recappi 0.1.47 → 0.1.49
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 +117 -56
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -592,18 +592,18 @@ var init_LiveCaptionsScreen = __esm({
|
|
|
592
592
|
});
|
|
593
593
|
|
|
594
594
|
// src/tui/RecordingHeroScreen.tsx
|
|
595
|
-
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
595
|
+
import { useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
596
596
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
597
597
|
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
598
|
-
function
|
|
599
|
-
|
|
598
|
+
function litCount(level) {
|
|
599
|
+
const amp = Math.max(0, Math.min(1, level));
|
|
600
|
+
if (amp <= 0.028) return 0;
|
|
601
|
+
return Math.max(1, Math.min(WAVE_ROWS, Math.ceil(Math.pow(amp, 0.58) * WAVE_ROWS)));
|
|
602
|
+
}
|
|
603
|
+
function litCounts(samples, width) {
|
|
604
|
+
if (width <= 0) return [];
|
|
600
605
|
const tail = samples.slice(-width);
|
|
601
|
-
|
|
602
|
-
const cells = tail.map((v) => {
|
|
603
|
-
const i = Math.max(0, Math.min(BLOCKS.length - 1, Math.round(Math.max(0, Math.min(1, v)) * (BLOCKS.length - 1))));
|
|
604
|
-
return BLOCKS[i];
|
|
605
|
-
});
|
|
606
|
-
return "\u2581".repeat(Math.max(0, pad)) + cells.join("");
|
|
606
|
+
return [...Array(Math.max(0, width - tail.length)).fill(0), ...tail].map(litCount);
|
|
607
607
|
}
|
|
608
608
|
function levelDb(level) {
|
|
609
609
|
if (level <= 0.03) return "silent";
|
|
@@ -617,10 +617,19 @@ function MeterRow({
|
|
|
617
617
|
width
|
|
618
618
|
}) {
|
|
619
619
|
const silent = level <= 0.03;
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
/* @__PURE__ */
|
|
620
|
+
const cols = litCounts(samples, width);
|
|
621
|
+
const litColor = paused ? "gray" : "cyan";
|
|
622
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
623
|
+
/* @__PURE__ */ jsxs2(Box2, { width: width + 9, children: [
|
|
624
|
+
/* @__PURE__ */ jsx3(Box2, { width: 9, children: /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: label }) }),
|
|
625
|
+
/* @__PURE__ */ jsx3(Box2, { flexGrow: 1, justifyContent: "flex-end", children: !paused && silent ? /* @__PURE__ */ jsx3(Text2, { color: "yellow", children: "silent" }) : /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: paused ? "paused" : levelDb(level) }) })
|
|
626
|
+
] }),
|
|
627
|
+
Array.from({ length: WAVE_ROWS }, (_, r) => {
|
|
628
|
+
const fromBottom = WAVE_ROWS - r;
|
|
629
|
+
return /* @__PURE__ */ jsx3(Text2, { children: cols.map(
|
|
630
|
+
(c, i) => c >= fromBottom ? /* @__PURE__ */ jsx3(Text2, { color: litColor, children: c === fromBottom ? "\u2022" : "\u25CF" }, i) : /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "\xB7" }, i)
|
|
631
|
+
) }, r);
|
|
632
|
+
})
|
|
624
633
|
] });
|
|
625
634
|
}
|
|
626
635
|
function ProgressBar({ fraction, width = 12 }) {
|
|
@@ -654,10 +663,14 @@ function RecordingHeroScreen({
|
|
|
654
663
|
const [tick, setTick] = useState3(() => now());
|
|
655
664
|
const [waveSys, setWaveSys] = useState3([]);
|
|
656
665
|
const [waveMic, setWaveMic] = useState3([]);
|
|
666
|
+
const lastAppendRef = useRef(0);
|
|
657
667
|
useEffect2(() => {
|
|
658
668
|
if (telemetry.level == null) return;
|
|
659
|
-
|
|
660
|
-
|
|
669
|
+
const t = now();
|
|
670
|
+
if (t - lastAppendRef.current < WAVE_THROTTLE_MS) return;
|
|
671
|
+
lastAppendRef.current = t;
|
|
672
|
+
setWaveSys((w) => [...w.slice(-512), telemetry.level.system ?? 0]);
|
|
673
|
+
setWaveMic((w) => [...w.slice(-512), telemetry.level.mic ?? 0]);
|
|
661
674
|
}, [telemetry.level]);
|
|
662
675
|
useEffect2(() => {
|
|
663
676
|
const id = setInterval(() => setTick(now()), 1e3);
|
|
@@ -704,15 +717,18 @@ function RecordingHeroScreen({
|
|
|
704
717
|
const paused = telemetry.status === "paused";
|
|
705
718
|
const starting = telemetry.status === "starting" || telemetry.status === "stopping";
|
|
706
719
|
const badge = paused ? "\u23F8 PAUSED" : starting ? "\u2026" : "\u23FA REC";
|
|
707
|
-
const meterW = Math.max(10, Math.min(
|
|
720
|
+
const meterW = Math.max(10, Math.min(72, innerWidth - 20));
|
|
708
721
|
const sizeStr = telemetry.sizeBytes ? formatBytes2(telemetry.sizeBytes) : "";
|
|
709
722
|
const context = [telemetry.sourceLabel, telemetry.micEnabled ? "Microphone" : null, sizeStr || null].filter(Boolean).join(" \xB7 ");
|
|
710
|
-
|
|
723
|
+
const meterBlockRows = (telemetry.micEnabled ? 2 : 1) * (WAVE_ROWS + 1) + (telemetry.micEnabled ? 1 : 0);
|
|
724
|
+
const fixedRows = 8 + meterBlockRows;
|
|
725
|
+
const captionRows = Math.max(2, size.rows - fixedRows);
|
|
726
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
|
|
711
727
|
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
712
728
|
/* @__PURE__ */ jsx3(Text2, { bold: true, color: "green", children: "recappi" }),
|
|
713
729
|
/* @__PURE__ */ jsx3(Text2, { dimColor: true, children: " \xB7 Recording" })
|
|
714
730
|
] }),
|
|
715
|
-
/* @__PURE__ */ jsxs2(Box2, { marginTop: 1, paddingX: 1,
|
|
731
|
+
/* @__PURE__ */ jsxs2(Box2, { marginTop: 1, paddingX: 1, flexDirection: "column", children: [
|
|
716
732
|
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
717
733
|
/* @__PURE__ */ jsx3(Text2, { bold: true, color: paused ? "yellow" : "red", children: badge }),
|
|
718
734
|
/* @__PURE__ */ jsx3(Text2, { children: " " }),
|
|
@@ -724,38 +740,53 @@ function RecordingHeroScreen({
|
|
|
724
740
|
/* @__PURE__ */ jsx3(Text2, { dimColor: true, children: paused ? "Paused" : `Capturing audio${".".repeat(Math.floor(tick / 1e3) % 3 + 1)}` })
|
|
725
741
|
) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
726
742
|
/* @__PURE__ */ jsx3(MeterRow, { label: "System", samples: waveSys, level: telemetry.level.system ?? 0, paused, width: meterW }),
|
|
727
|
-
telemetry.micEnabled ? /* @__PURE__ */ jsx3(MeterRow, { label: "Mic", samples: waveMic, level: telemetry.level.mic ?? 0, paused, width: meterW }) : null
|
|
743
|
+
telemetry.micEnabled ? /* @__PURE__ */ jsx3(Box2, { marginTop: 1, children: /* @__PURE__ */ jsx3(MeterRow, { label: "Mic", samples: waveMic, level: telemetry.level.mic ?? 0, paused, width: meterW }) }) : null
|
|
728
744
|
] }) }),
|
|
729
745
|
/* @__PURE__ */ jsx3(Box2, { marginTop: 1, children: /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: context }) }),
|
|
730
746
|
captions ? /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
|
|
731
747
|
/* @__PURE__ */ jsx3(Text2, { bold: true, dimColor: true, children: "LIVE CAPTIONS" }),
|
|
732
|
-
/* @__PURE__ */ jsx3(HeroCaptions, { state: captions })
|
|
748
|
+
/* @__PURE__ */ jsx3(HeroCaptions, { state: captions, maxRows: captionRows })
|
|
733
749
|
] }) : null
|
|
734
750
|
] }),
|
|
735
|
-
/* @__PURE__ */ jsx3(Box2, { children: /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
751
|
+
/* @__PURE__ */ jsx3(Box2, { marginTop: 1, children: /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
736
752
|
"q stop & save",
|
|
737
753
|
canPause ? ` \xB7 p ${paused ? "resume" : "pause"}` : ""
|
|
738
754
|
] }) })
|
|
739
755
|
] });
|
|
740
756
|
}
|
|
741
|
-
function HeroCaptions({ state }) {
|
|
742
|
-
const MAX_LINES = 3;
|
|
743
|
-
const recent = state.lines.slice(-MAX_LINES);
|
|
757
|
+
function HeroCaptions({ state, maxRows }) {
|
|
744
758
|
const hasPartial = Boolean(state.partial && state.partial.length > 0);
|
|
745
759
|
const captionError = state.status === "error" ? `Captions unavailable: ${state.error ?? "Live captions unavailable."}` : null;
|
|
746
|
-
if (
|
|
760
|
+
if (state.lines.length === 0 && !hasPartial) {
|
|
747
761
|
return /* @__PURE__ */ jsx3(Text2, { color: captionError ? "yellow" : void 0, dimColor: !captionError, wrap: "truncate-end", children: captionError ?? (state.status === "live" ? "Listening for speech\u2026" : liveCaptionStatusLabel(state.status)) });
|
|
748
762
|
}
|
|
749
|
-
|
|
750
|
-
|
|
763
|
+
const rows = [];
|
|
764
|
+
for (const line of state.lines) {
|
|
765
|
+
rows.push(
|
|
751
766
|
/* @__PURE__ */ jsxs2(Text2, { wrap: "truncate-end", children: [
|
|
752
767
|
line.speaker ? `${line.speaker}: ` : "",
|
|
753
|
-
line.text
|
|
754
|
-
] })
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
768
|
+
trimLead(line.text)
|
|
769
|
+
] }, `${line.id}-s`)
|
|
770
|
+
);
|
|
771
|
+
if (line.translation) {
|
|
772
|
+
rows.push(
|
|
773
|
+
/* @__PURE__ */ jsx3(Text2, { dimColor: true, wrap: "truncate-end", children: ` \u21B3 ${trimLead(line.translation)}` }, `${line.id}-t`)
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
if (hasPartial) {
|
|
778
|
+
rows.push(
|
|
779
|
+
/* @__PURE__ */ jsx3(Text2, { dimColor: true, wrap: "truncate-end", children: trimLead(state.partial) }, "partial")
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
if (state.translationPartial) {
|
|
783
|
+
rows.push(
|
|
784
|
+
/* @__PURE__ */ jsx3(Text2, { dimColor: true, wrap: "truncate-end", children: ` \u21B3 ${trimLead(state.translationPartial)}` }, "tpartial")
|
|
785
|
+
);
|
|
786
|
+
}
|
|
787
|
+
const visible = rows.slice(-Math.max(1, maxRows));
|
|
788
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
789
|
+
visible,
|
|
759
790
|
captionError ? /* @__PURE__ */ jsx3(Text2, { color: "yellow", wrap: "truncate-end", children: captionError }) : null
|
|
760
791
|
] });
|
|
761
792
|
}
|
|
@@ -777,32 +808,40 @@ function stoppedHandoffCopy(artifact, canTranscribe) {
|
|
|
777
808
|
}
|
|
778
809
|
return { text: "Transcribe now? \u23CE yes \xB7 n not now", tone: "normal" };
|
|
779
810
|
}
|
|
780
|
-
var
|
|
811
|
+
var WAVE_ROWS, WAVE_THROTTLE_MS, trimLead;
|
|
781
812
|
var init_RecordingHeroScreen = __esm({
|
|
782
813
|
"src/tui/RecordingHeroScreen.tsx"() {
|
|
783
814
|
"use strict";
|
|
784
815
|
init_format();
|
|
785
816
|
init_liveCaptions();
|
|
786
817
|
init_terminal();
|
|
787
|
-
|
|
818
|
+
WAVE_ROWS = 5;
|
|
819
|
+
WAVE_THROTTLE_MS = 220;
|
|
820
|
+
trimLead = (s) => s.replace(/^\s+/, "");
|
|
788
821
|
}
|
|
789
822
|
});
|
|
790
823
|
|
|
791
824
|
// src/tui/AccountView.tsx
|
|
792
825
|
import { Box as Box3, Text as Text3 } from "ink";
|
|
793
826
|
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
794
|
-
function AccountView({
|
|
827
|
+
function AccountView({
|
|
828
|
+
status,
|
|
829
|
+
nowMs = Date.now()
|
|
830
|
+
}) {
|
|
795
831
|
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingX: 1, children: [
|
|
796
832
|
/* @__PURE__ */ jsx5(Text3, { dimColor: true, children: "\u2039 Account" }),
|
|
797
833
|
status === "loading" || status === void 0 ? /* @__PURE__ */ jsx5(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text3, { dimColor: true, children: "Loading account\u2026" }) }) : status === "error" ? /* @__PURE__ */ jsx5(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text3, { color: "red", children: "Couldn't load account status" }) }) : !status.loggedIn ? /* @__PURE__ */ jsxs3(Box3, { marginTop: 1, flexDirection: "column", children: [
|
|
798
834
|
/* @__PURE__ */ jsx5(Text3, { color: "yellow", children: "Not signed in" }),
|
|
799
835
|
/* @__PURE__ */ jsx5(Text3, { dimColor: true, children: `origin ${status.origin}` }),
|
|
800
836
|
/* @__PURE__ */ jsx5(Text3, { dimColor: true, children: "Run `recappi auth login` to sign in." })
|
|
801
|
-
] }) : /* @__PURE__ */ jsx5(AccountBody, { status }),
|
|
837
|
+
] }) : /* @__PURE__ */ jsx5(AccountBody, { status, nowMs }),
|
|
802
838
|
/* @__PURE__ */ jsx5(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text3, { dimColor: true, children: "r refresh \xB7 esc back \xB7 q quit" }) })
|
|
803
839
|
] });
|
|
804
840
|
}
|
|
805
|
-
function AccountBody({
|
|
841
|
+
function AccountBody({
|
|
842
|
+
status,
|
|
843
|
+
nowMs
|
|
844
|
+
}) {
|
|
806
845
|
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
807
846
|
/* @__PURE__ */ jsxs3(Box3, { marginTop: 1, flexDirection: "column", children: [
|
|
808
847
|
/* @__PURE__ */ jsxs3(Text3, { children: [
|
|
@@ -812,7 +851,7 @@ function AccountBody({ status }) {
|
|
|
812
851
|
status.email && status.userId ? /* @__PURE__ */ jsx5(Text3, { dimColor: true, children: status.userId }) : null,
|
|
813
852
|
/* @__PURE__ */ jsx5(Text3, { dimColor: true, children: `origin ${status.origin}` })
|
|
814
853
|
] }),
|
|
815
|
-
status.billing ? /* @__PURE__ */ jsx5(Usage, { billing: status.billing }) : null,
|
|
854
|
+
status.billing ? /* @__PURE__ */ jsx5(Usage, { billing: status.billing, nowMs }) : null,
|
|
816
855
|
/* @__PURE__ */ jsxs3(Box3, { marginTop: 1, flexDirection: "column", children: [
|
|
817
856
|
/* @__PURE__ */ jsx5(Text3, { bold: true, dimColor: true, children: "LOCAL STORE" }),
|
|
818
857
|
/* @__PURE__ */ jsx5(Text3, { dimColor: true, wrap: "truncate-middle", children: status.localStore.path }),
|
|
@@ -823,7 +862,10 @@ function AccountBody({ status }) {
|
|
|
823
862
|
] })
|
|
824
863
|
] });
|
|
825
864
|
}
|
|
826
|
-
function Usage({
|
|
865
|
+
function Usage({
|
|
866
|
+
billing,
|
|
867
|
+
nowMs
|
|
868
|
+
}) {
|
|
827
869
|
const minutesCap = billing.minutesCap;
|
|
828
870
|
const minutesUsed = billing.minutesUsed;
|
|
829
871
|
const storageCap = billing.storageCapBytes;
|
|
@@ -850,11 +892,11 @@ function Usage({ billing }) {
|
|
|
850
892
|
billing.isOverMinutes ? "Over minutes limit. " : "",
|
|
851
893
|
billing.isOverStorage ? "Over storage limit." : ""
|
|
852
894
|
] }) : null,
|
|
853
|
-
/* @__PURE__ */ jsx5(Text3, { dimColor: true, children: `Period ${periodText(billing)}` })
|
|
895
|
+
/* @__PURE__ */ jsx5(Text3, { dimColor: true, children: `Period ${periodText(billing, nowMs)}` })
|
|
854
896
|
] });
|
|
855
897
|
}
|
|
856
|
-
function periodText(billing) {
|
|
857
|
-
const remainingMs = epochToMs(billing.periodEnd) -
|
|
898
|
+
function periodText(billing, nowMs) {
|
|
899
|
+
const remainingMs = epochToMs(billing.periodEnd) - nowMs;
|
|
858
900
|
if (!Number.isFinite(remainingMs) || remainingMs <= 0) return "\u2014";
|
|
859
901
|
const days = Math.floor(remainingMs / 864e5);
|
|
860
902
|
if (days >= 1) return `${days}d left`;
|
|
@@ -1677,7 +1719,7 @@ var init_PermissionPreflightView = __esm({
|
|
|
1677
1719
|
});
|
|
1678
1720
|
|
|
1679
1721
|
// src/tui/RecordSetupView.tsx
|
|
1680
|
-
import { useEffect as useEffect3, useRef, useState as useState6 } from "react";
|
|
1722
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState6 } from "react";
|
|
1681
1723
|
import { Box as Box15, Text as Text15, useInput as useInput5 } from "ink";
|
|
1682
1724
|
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1683
1725
|
function levelDb2(level) {
|
|
@@ -1710,7 +1752,7 @@ function RecordSetupView({
|
|
|
1710
1752
|
() => Math.max(0, model.microphones?.findIndex((device) => device.isDefault) ?? 0)
|
|
1711
1753
|
);
|
|
1712
1754
|
const [sceneIdx, setSceneIdx] = useState6(0);
|
|
1713
|
-
const userPickedMic =
|
|
1755
|
+
const userPickedMic = useRef2(false);
|
|
1714
1756
|
const sources = model.sources;
|
|
1715
1757
|
const microphones = model.microphones ?? [];
|
|
1716
1758
|
const selected = sources[Math.min(srcIdx, Math.max(0, sources.length - 1))];
|
|
@@ -2118,7 +2160,9 @@ function AppShell({
|
|
|
2118
2160
|
};
|
|
2119
2161
|
});
|
|
2120
2162
|
}).catch((error51) => {
|
|
2121
|
-
setLiveRecord(
|
|
2163
|
+
setLiveRecord(
|
|
2164
|
+
(current) => current?.kind === "starting" ? recordErrorState(error51, selection) : current
|
|
2165
|
+
);
|
|
2122
2166
|
});
|
|
2123
2167
|
},
|
|
2124
2168
|
[now, recordSetupModel.sources, startLiveRecord]
|
|
@@ -2138,7 +2182,7 @@ function AppShell({
|
|
|
2138
2182
|
const data = await current.session.stop();
|
|
2139
2183
|
const artifact = recordingArtifactFromRecordData(data);
|
|
2140
2184
|
const fallbackDuration = current.telemetry.startedAtMs != null ? Math.max(0, now() - current.telemetry.startedAtMs) : void 0;
|
|
2141
|
-
|
|
2185
|
+
const stoppedRecord = {
|
|
2142
2186
|
kind: "stopped",
|
|
2143
2187
|
selection: current.selection,
|
|
2144
2188
|
artifact,
|
|
@@ -2148,17 +2192,25 @@ function AppShell({
|
|
|
2148
2192
|
...artifact.durationMs == null && fallbackDuration != null ? { durationMs: fallbackDuration } : {},
|
|
2149
2193
|
status: "stopped"
|
|
2150
2194
|
}
|
|
2195
|
+
};
|
|
2196
|
+
setLiveRecord((next) => {
|
|
2197
|
+
if (next?.kind !== "stopping" || next.session !== current.session) return next;
|
|
2198
|
+
return stoppedRecord;
|
|
2151
2199
|
});
|
|
2152
2200
|
void refreshDownloadedIds();
|
|
2153
2201
|
} catch (error51) {
|
|
2154
|
-
setLiveRecord({
|
|
2155
|
-
kind
|
|
2156
|
-
|
|
2202
|
+
setLiveRecord((next) => {
|
|
2203
|
+
if (next?.kind !== "stopping" || next.session !== current.session) return next;
|
|
2204
|
+
return {
|
|
2205
|
+
kind: "error",
|
|
2206
|
+
message: error51 instanceof Error ? error51.message : String(error51)
|
|
2207
|
+
};
|
|
2157
2208
|
});
|
|
2158
2209
|
}
|
|
2159
2210
|
return;
|
|
2160
2211
|
}
|
|
2161
|
-
if (current?.kind === "stopped" || current?.kind === "error")
|
|
2212
|
+
if (current?.kind === "starting" || current?.kind === "stopping" || current?.kind === "stopped" || current?.kind === "error")
|
|
2213
|
+
setLiveRecord(void 0);
|
|
2162
2214
|
setStack([{ kind: "overview" }]);
|
|
2163
2215
|
}, [liveRecord, now, refreshDownloadedIds]);
|
|
2164
2216
|
const liveSession = liveRecord?.kind === "live" ? liveRecord.session : void 0;
|
|
@@ -2473,7 +2525,11 @@ function AppShell({
|
|
|
2473
2525
|
void transcribeStoppedRecording();
|
|
2474
2526
|
return;
|
|
2475
2527
|
}
|
|
2476
|
-
if (
|
|
2528
|
+
if (liveRecord?.kind === "stopped" && input === "n") {
|
|
2529
|
+
void stopLiveRecord();
|
|
2530
|
+
return;
|
|
2531
|
+
}
|
|
2532
|
+
if (input === "q" || key.escape || key.leftArrow) void stopLiveRecord();
|
|
2477
2533
|
return;
|
|
2478
2534
|
}
|
|
2479
2535
|
if (input === "q") return exit();
|
|
@@ -2497,6 +2553,8 @@ function AppShell({
|
|
|
2497
2553
|
}
|
|
2498
2554
|
if (input === "r") return void refresh({ resetRecordings: true });
|
|
2499
2555
|
if (screen.kind === "overview") {
|
|
2556
|
+
if (input === "g") setSelected(0);
|
|
2557
|
+
if (input === "G") setSelected(Math.max(0, recordings.length - 1));
|
|
2500
2558
|
if (key.upArrow || input === "k") setSelected((i) => Math.max(0, i - 1));
|
|
2501
2559
|
if (key.downArrow || input === "j") setSelected((i) => Math.min(recordings.length - 1, i + 1));
|
|
2502
2560
|
const rec = recordings[selected];
|
|
@@ -2506,6 +2564,8 @@ function AppShell({
|
|
|
2506
2564
|
return;
|
|
2507
2565
|
}
|
|
2508
2566
|
if (screen.kind === "jobs") {
|
|
2567
|
+
if (input === "g") setSelected(0);
|
|
2568
|
+
if (input === "G") setSelected(Math.max(0, jobs.length - 1));
|
|
2509
2569
|
if (key.upArrow || input === "k") setSelected((i) => Math.max(0, i - 1));
|
|
2510
2570
|
if (key.downArrow || input === "j") setSelected((i) => Math.min(jobs.length - 1, i + 1));
|
|
2511
2571
|
const job = jobs[selected];
|
|
@@ -2639,7 +2699,7 @@ function AppShell({
|
|
|
2639
2699
|
);
|
|
2640
2700
|
} else if (screen.kind === "account") {
|
|
2641
2701
|
position = "";
|
|
2642
|
-
body = /* @__PURE__ */ jsx18(AccountView, { status: accountStatus });
|
|
2702
|
+
body = /* @__PURE__ */ jsx18(AccountView, { status: accountStatus, nowMs: now() });
|
|
2643
2703
|
} else {
|
|
2644
2704
|
const win = listWindow(selected, jobs.length, Math.max(3, size.rows - 4));
|
|
2645
2705
|
position = jobs.length ? `${selected + 1} / ${jobs.length}` : "0";
|
|
@@ -2652,7 +2712,7 @@ function AppShell({
|
|
|
2652
2712
|
}
|
|
2653
2713
|
);
|
|
2654
2714
|
}
|
|
2655
|
-
const footerKeys = screen.kind === "jobs" ? `${position} \xB7 \u2191\u2193 select \xB7 \u23CE job \xB7 t transcript \xB7 n record \xB7 1 overview \xB7 3 account \xB7 r refresh \xB7 q quit` : screen.kind === "account" ? "
|
|
2715
|
+
const footerKeys = screen.kind === "jobs" ? `${position} \xB7 \u2191\u2193 select \xB7 \u23CE job \xB7 t transcript \xB7 n record \xB7 1 overview \xB7 3 account \xB7 r refresh \xB7 q quit` : screen.kind === "account" ? "Account \xB7 n record \xB7 1 overview \xB7 2 jobs \xB7 r refresh \xB7 q quit" : `${position} \xB7 \u2191\u2193 scroll \xB7 \u23CE open \xB7 t transcript \xB7 n record \xB7 2 jobs \xB7 3 account \xB7 r refresh \xB7 q quit`;
|
|
2656
2716
|
return /* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", height: size.rows, paddingX: 1, children: [
|
|
2657
2717
|
/* @__PURE__ */ jsx18(Header, { active: tab }),
|
|
2658
2718
|
/* @__PURE__ */ jsxs15(Box16, { flexGrow: 1, flexDirection: "column", children: [
|
|
@@ -20959,7 +21019,7 @@ async function startRecordSessionOnce(opts) {
|
|
|
20959
21019
|
...opts.targetBundleId ? { targetBundleId: opts.targetBundleId } : {},
|
|
20960
21020
|
...opts.microphoneDeviceId ? { microphoneDeviceId: opts.microphoneDeviceId } : {},
|
|
20961
21021
|
liveCaptions: captionStreamEnabled,
|
|
20962
|
-
...opts.translationLanguage ? { translationLanguage: opts.translationLanguage } : {},
|
|
21022
|
+
...captionStreamEnabled && opts.translationLanguage ? { translationLanguage: opts.translationLanguage } : {},
|
|
20963
21023
|
...opts.transcriptionLanguage ? { transcriptionLanguage: opts.transcriptionLanguage } : {},
|
|
20964
21024
|
...opts.title ? { title: opts.title } : {}
|
|
20965
21025
|
};
|
|
@@ -21561,6 +21621,7 @@ async function runCli(deps = {}) {
|
|
|
21561
21621
|
hint: "Run recappi auth login, or import the Recappi Mini session with recappi auth import-macos."
|
|
21562
21622
|
});
|
|
21563
21623
|
}
|
|
21624
|
+
const translationLanguage = parsed.translationLanguage ?? (mode === "human" && isTTY ? "zh" : void 0);
|
|
21564
21625
|
const data = await recordViaSidecar({
|
|
21565
21626
|
account: {
|
|
21566
21627
|
backendOrigin: auth.origin,
|
|
@@ -21575,7 +21636,7 @@ async function runCli(deps = {}) {
|
|
|
21575
21636
|
live: parsed.live === true || mode === "human" && isTTY,
|
|
21576
21637
|
includeSystemAudio: parsed.includeSystemAudio,
|
|
21577
21638
|
includeMicrophone: parsed.includeMicrophone,
|
|
21578
|
-
translationLanguage
|
|
21639
|
+
translationLanguage,
|
|
21579
21640
|
transcriptionLanguage: parsed.transcriptionLanguage,
|
|
21580
21641
|
sidecarCommand: parsed.sidecarCommand,
|
|
21581
21642
|
renderLive: parsed.live === true && mode === "human" && isTTY,
|