@hasna/recordings 0.2.14 → 0.3.2
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/Dockerfile.package +4 -5
- package/README.md +113 -8
- package/bun.lock +2 -2
- package/dist/__tests__/helpers/installer-guard-execution.d.ts +22 -0
- package/dist/__tests__/helpers/installer-guard-execution.d.ts.map +1 -0
- package/dist/__tests__/helpers/installer-preflight.d.ts +22 -0
- package/dist/__tests__/helpers/installer-preflight.d.ts.map +1 -0
- package/dist/__tests__/helpers/native-fs-guard.d.ts.map +1 -1
- package/dist/__tests__/helpers/source-assertions.d.ts +169 -0
- package/dist/__tests__/helpers/source-assertions.d.ts.map +1 -0
- package/dist/__tests__/preload.d.ts +1 -4
- package/dist/__tests__/preload.d.ts.map +1 -1
- package/dist/cli/desktop-snapshot.d.ts +20 -0
- package/dist/cli/desktop-snapshot.d.ts.map +1 -0
- package/dist/cli/index.js +2094 -280
- package/dist/cli/macos-permissions.d.ts +72 -0
- package/dist/cli/macos-permissions.d.ts.map +1 -1
- package/dist/cli/macos-shortcut.d.ts +139 -0
- package/dist/cli/macos-shortcut.d.ts.map +1 -0
- package/dist/cli/trigger-probe.d.ts +172 -0
- package/dist/cli/trigger-probe.d.ts.map +1 -0
- package/dist/db/database.d.ts +9 -0
- package/dist/db/database.d.ts.map +1 -1
- package/dist/http/client.d.ts +19 -7
- package/dist/http/client.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +635 -50
- package/dist/lib/capture-probe.d.ts +216 -0
- package/dist/lib/capture-probe.d.ts.map +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/macos-bundle.d.ts +50 -0
- package/dist/lib/macos-bundle.d.ts.map +1 -0
- package/dist/lib/persistence-probe.d.ts +208 -0
- package/dist/lib/persistence-probe.d.ts.map +1 -0
- package/dist/lib/recorder.d.ts.map +1 -1
- package/dist/lib/retired-deployment-modes.d.ts +24 -0
- package/dist/lib/retired-deployment-modes.d.ts.map +1 -0
- package/dist/lib/transcriber.d.ts +60 -0
- package/dist/lib/transcriber.d.ts.map +1 -1
- package/dist/mcp/index.js +141 -57
- package/dist/server/cloud-config.d.ts +25 -3
- package/dist/server/cloud-config.d.ts.map +1 -1
- package/dist/server/cloud-readiness.d.ts.map +1 -1
- package/dist/server/cloud.d.ts +8 -7
- package/dist/server/cloud.d.ts.map +1 -1
- package/dist/server/index.js +188 -80
- package/dist/server/migrate-command.d.ts.map +1 -1
- package/dist/server/serve.d.ts.map +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +109 -50
- package/dist/store.d.ts +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/package.json +25 -6
- package/scripts/ci-linux-suite.ts +403 -0
- package/scripts/ci-native-build.ts +402 -0
- package/scripts/enforce_identity_migration.sh +110 -0
- package/scripts/generate-sdk.ts +1 -1
- package/scripts/install_macos_app.sh +192 -31
- package/scripts/macos_artifact.ts +323 -43
- package/scripts/native/realtime-settle-probe/README.md +39 -0
- package/scripts/native/realtime-settle-probe/main.swift +135 -0
- package/scripts/policy/local-only-approved-targets.txt +21 -0
- package/scripts/read_local_only_targets.sh +203 -0
- package/scripts/scan-artifact.ts +40 -0
- package/scripts/set-version.ts +145 -0
- package/scripts/smoke_macos_app.sh +62 -16
- package/scripts/vacuity-manifest-gen.ts +96 -0
- package/scripts/vacuity-manifests/enhancement-screen-mirror.tsv +44 -0
- package/scripts/vacuity-manifests/install-chain.tsv +13 -0
- package/scripts/vacuity-manifests/must-survive-controls.tsv +10 -0
- package/scripts/vacuity-manifests/reorder.tsv +4 -0
- package/scripts/vacuity-manifests/source-side.tsv +15 -0
- package/scripts/vacuity-manifests/variable-operands.tsv +16 -0
- package/scripts/vacuity-manifests/version-sites.tsv +61 -0
- package/scripts/vacuity-mutation-battery.ts +266 -0
- package/src/native/Recordings/App/MenuBarStatusView.swift +23 -11
- package/src/native/Recordings/App/RecordingsApp.swift +37 -1
- package/src/native/Recordings/App/RuntimeSmoke.swift +5 -1
- package/src/native/Recordings/App/SidebarView.swift +1 -1
- package/src/native/Recordings/Package.swift +24 -5
- package/src/native/Recordings/RecordingsLib/EnhancementScreen.swift +91 -0
- package/src/native/Recordings/RecordingsLib/FnKeyMonitor.swift +27 -4
- package/src/native/Recordings/RecordingsLib/Info.plist +2 -2
- package/src/native/Recordings/RecordingsLib/MenuBarPresentation.swift +56 -3
- package/src/native/Recordings/RecordingsLib/NativePCMRecorder.swift +13 -0
- package/src/native/Recordings/RecordingsLib/PasteDeliveryVerification.swift +460 -0
- package/src/native/Recordings/RecordingsLib/PermissionRequestLaunchPlan.swift +21 -1
- package/src/native/Recordings/RecordingsLib/RealtimeTranscriptionClient.swift +41 -7
- package/src/native/Recordings/RecordingsLib/RecordingAttemptAlert.swift +36 -0
- package/src/native/Recordings/RecordingsLib/RecordingEngine.swift +1071 -75
- package/src/native/Recordings/RecordingsLib/SettingsView.swift +47 -3
- package/src/native/Recordings/RecordingsLib/VoiceShortcuts.swift +11 -6
- package/src/native/Recordings/RecordingsTests/BarOnlyLaunchPlanTests.swift +99 -0
- package/src/native/Recordings/RecordingsTests/CLIRunnerTests.swift +3 -3
- package/src/native/Recordings/RecordingsTests/EnhancementScreenTests.swift +191 -0
- package/src/native/Recordings/RecordingsTests/MenuBarPresentationTests.swift +144 -4
- package/src/native/Recordings/RecordingsTests/PasteDeliveryVerificationTests.swift +463 -0
- package/src/native/Recordings/RecordingsTests/PasteTargetTests.swift +33 -20
- package/src/native/Recordings/RecordingsTests/ProjectStoreTests.swift +1 -1
- package/src/native/Recordings/RecordingsTests/RealtimeSettleBenchmark.swift +200 -0
- package/src/native/Recordings/RecordingsTests/RealtimeSettleBudgetTests.swift +80 -0
- package/src/native/Recordings/RecordingsTests/RealtimeTranscriptionTests.swift +22 -4
- package/src/native/Recordings/RecordingsTests/RecordingEngineDeliveryTests.swift +12 -6
- package/src/native/Recordings/RecordingsTests/RecordingEngineHomeIsolationTests.swift +67 -0
- package/src/native/Recordings/RecordingsTests/RecordingStartGateTests.swift +12 -3
- package/src/native/Recordings/RecordingsTests/RecordingStartTimingTests.swift +207 -11
- package/src/native/Recordings/RecordingsTests/SpeechIntentTests.swift +17 -6
- package/src/native/Recordings/RecordingsTests/TestHomeDirectory.swift +23 -0
- package/src/native/Recordings/Updater/Broker/ApplicationProcessQuiescence.swift +7 -1
- package/src/native/Recordings/Updater/Broker/AtomicActivation.swift +10 -10
- package/src/native/Recordings/Updater/Broker/BrokerMain.swift +5 -1
- package/src/native/Recordings/Updater/Broker/HostOSProductVersion.swift +1 -0
- package/src/native/Recordings/Updater/Broker/PeerIdentity.swift +59 -3
- package/src/native/Recordings/Updater/Protocol/UpdateProtocol.swift +21 -2
- package/src/native/Recordings/Updater/ProtocolTests/ExpectationIntegrityTests.swift +60 -0
- package/src/native/Recordings/Updater/ProtocolTests/UpdateXPCInterfaceTests.swift +113 -0
- package/src/native/Recordings/Updater/VerifierLauncher/RecordingsVerifierLauncher.c +106 -5
- package/src/native/Recordings/build.sh +226 -20
- package/scripts/native/prebuilds/darwin-universal/recordings_fs_guard.node +0 -0
|
@@ -294,7 +294,10 @@ public final class RealtimeTranscriptionClient: ObservableObject, @unchecked Sen
|
|
|
294
294
|
let sessionConfig = Self.transcriptionSessionUpdateEvent(transcription: transcription)
|
|
295
295
|
|
|
296
296
|
do {
|
|
297
|
-
try await sendEvent(
|
|
297
|
+
try await sendEvent(
|
|
298
|
+
sessionConfig,
|
|
299
|
+
timeoutMilliseconds: Self.configureSendTimeoutMilliseconds
|
|
300
|
+
)
|
|
298
301
|
isConfigured = true
|
|
299
302
|
flushPendingAudio()
|
|
300
303
|
} catch {
|
|
@@ -369,8 +372,11 @@ public final class RealtimeTranscriptionClient: ObservableObject, @unchecked Sen
|
|
|
369
372
|
}
|
|
370
373
|
|
|
371
374
|
/// Commit buffered input, wait briefly for a final completed event, then close.
|
|
375
|
+
/// The settlement budget is the caller's decision (`RecordingEngine` scales it with
|
|
376
|
+
/// captured audio length); there is deliberately no default so a new call site cannot
|
|
377
|
+
/// silently reintroduce the fixed 700 ms budget this parameter replaced.
|
|
372
378
|
public func finish(
|
|
373
|
-
timeoutMilliseconds: UInt64
|
|
379
|
+
timeoutMilliseconds: UInt64,
|
|
374
380
|
pipelineID: String? = nil,
|
|
375
381
|
pipelineStartedUptimeMilliseconds: UInt64? = nil
|
|
376
382
|
) async -> RealtimeFinishResult {
|
|
@@ -611,14 +617,42 @@ public final class RealtimeTranscriptionClient: ObservableObject, @unchecked Sen
|
|
|
611
617
|
}
|
|
612
618
|
}
|
|
613
619
|
|
|
614
|
-
|
|
615
|
-
|
|
620
|
+
/// Deadline for the session-configure send. This is the first frame on a
|
|
621
|
+
/// just-resumed socket, so it absorbs DNS + TCP + TLS + WebSocket upgrade on a
|
|
622
|
+
/// cold connection — measured 0.77-1.0 s from a fresh process against the live
|
|
623
|
+
/// endpoint. The old shared 500 ms deadline made a cold morning connection fail
|
|
624
|
+
/// configuration outright, poisoning the whole session and silently demoting
|
|
625
|
+
/// every recording to the batch path. The user is speaking while this runs
|
|
626
|
+
/// (audio buffers locally either way), so the larger budget costs nothing on
|
|
627
|
+
/// the delivery path.
|
|
628
|
+
nonisolated static let configureSendTimeoutMilliseconds: UInt64 = 3_000
|
|
629
|
+
/// Deadline for every send after configuration, riding the established
|
|
630
|
+
/// connection. A single send past this deadline records a transport failure,
|
|
631
|
+
/// which permanently vetoes the realtime fast path for the whole recording —
|
|
632
|
+
/// so the deadline must tolerate ordinary jitter, not just the median. At the
|
|
633
|
+
/// old 500 ms value, 3 of 5 two-minute streaming sessions against the live
|
|
634
|
+
/// endpoint were poisoned by one slow frame and demoted to the batch path.
|
|
635
|
+
/// True connection stalls are still detected structurally: the bounded
|
|
636
|
+
/// outbound queue (262,144 bytes of raw 24 kHz/16-bit PCM ≈ 5.5 s of audio,
|
|
637
|
+
/// 262,144 ÷ 48,000 bytes/s) overflows and fails the transport
|
|
638
|
+
/// if sends stop draining, and the settle budget bounds release latency
|
|
639
|
+
/// regardless of this deadline.
|
|
640
|
+
nonisolated static let outboundSendTimeoutMilliseconds: UInt64 = 2_500
|
|
641
|
+
|
|
642
|
+
private func sendEvent(
|
|
643
|
+
_ obj: [String: Any],
|
|
644
|
+
timeoutMilliseconds: UInt64 = RealtimeTranscriptionClient.outboundSendTimeoutMilliseconds
|
|
645
|
+
) async throws {
|
|
646
|
+
try await sendEncodedEvent(encodeJSON(obj), timeoutMilliseconds: timeoutMilliseconds)
|
|
616
647
|
}
|
|
617
648
|
|
|
618
|
-
private func sendEncodedEvent(
|
|
649
|
+
private func sendEncodedEvent(
|
|
650
|
+
_ text: String,
|
|
651
|
+
timeoutMilliseconds: UInt64 = RealtimeTranscriptionClient.outboundSendTimeoutMilliseconds
|
|
652
|
+
) async throws {
|
|
619
653
|
guard let ws else { throw URLError(.networkConnectionLost) }
|
|
620
654
|
try await Self.runOutboundOperationWithDeadline(
|
|
621
|
-
timeoutMilliseconds:
|
|
655
|
+
timeoutMilliseconds: timeoutMilliseconds,
|
|
622
656
|
operation: { try await ws.send(.string(text)) },
|
|
623
657
|
nowMilliseconds: Self.monotonicMilliseconds,
|
|
624
658
|
sleepMilliseconds: { milliseconds in
|
|
@@ -826,7 +860,7 @@ extension RealtimeTranscriptionClient {
|
|
|
826
860
|
_ operation: @escaping @MainActor @Sendable () async throws -> Void
|
|
827
861
|
) async -> Bool {
|
|
828
862
|
await enqueueOutboundOperationTestHelper(
|
|
829
|
-
timeoutMilliseconds:
|
|
863
|
+
timeoutMilliseconds: Self.outboundSendTimeoutMilliseconds,
|
|
830
864
|
operation: operation,
|
|
831
865
|
nowMilliseconds: Self.monotonicMilliseconds,
|
|
832
866
|
sleepMilliseconds: { milliseconds in
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// A recording attempt that produced nothing the user can see anywhere else.
|
|
4
|
+
///
|
|
5
|
+
/// Recordings is an `LSUIElement` app: its only always-on surface is the menu-bar glyph.
|
|
6
|
+
/// `statusMessage` and the Record pane both sit behind a click, so an outcome delivered only
|
|
7
|
+
/// there is invisible to someone who pressed the key while looking at their editor — which is
|
|
8
|
+
/// how a swallowed attempt reads as "the app is still broken" no matter what the log says.
|
|
9
|
+
///
|
|
10
|
+
/// This is a message vocabulary, not a surface. The engine discloses these through
|
|
11
|
+
/// `setBlockedReason(_:for: .pressConsumed)` — the single published `blockedReason` field, which
|
|
12
|
+
/// `MenuBarPresentation` already renders with its own icon and its own VoiceOver label, and which
|
|
13
|
+
/// `startRecording` already clears. A second published field for the same idea would undo the
|
|
14
|
+
/// collapse that field exists to be.
|
|
15
|
+
public enum RecordingAttemptAlert: Equatable, Sendable {
|
|
16
|
+
/// The trigger was released before the microphone delivered its first sample, so no audio
|
|
17
|
+
/// ever existed to transcribe.
|
|
18
|
+
case releasedBeforeAudio
|
|
19
|
+
/// Capture ran to completion but the microphone produced no audio at all.
|
|
20
|
+
case noAudioCaptured
|
|
21
|
+
|
|
22
|
+
/// Shown on the menu-bar status line and in the Record pane. Kept short enough to fit the
|
|
23
|
+
/// 260 pt popover without wrapping past two lines, and phrased as the corrective action
|
|
24
|
+
/// rather than a diagnosis.
|
|
25
|
+
///
|
|
26
|
+
/// Deliberately carries no millisecond figure. The hold a user has to manage is the cold
|
|
27
|
+
/// audio engine plus one input buffer period, and the buffer period is a property of
|
|
28
|
+
/// whichever device is selected — so any number printed here would be wrong on some
|
|
29
|
+
/// machines.
|
|
30
|
+
public var message: String {
|
|
31
|
+
switch self {
|
|
32
|
+
case .releasedBeforeAudio: "Released too soon — hold the key a moment longer"
|
|
33
|
+
case .noAudioCaptured: "No audio captured"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|