@hasna/recordings 0.2.10 → 0.2.13

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 (167) hide show
  1. package/README.md +350 -35
  2. package/bun.lock +3 -0
  3. package/dist/__tests__/helpers/native-fs-guard.d.ts +2 -0
  4. package/dist/__tests__/helpers/native-fs-guard.d.ts.map +1 -0
  5. package/dist/cli/index.js +1728 -320
  6. package/dist/cli/macos-permissions.d.ts +13 -0
  7. package/dist/cli/macos-permissions.d.ts.map +1 -0
  8. package/dist/cli/options.d.ts +12 -0
  9. package/dist/cli/options.d.ts.map +1 -1
  10. package/dist/db/pg-migrations.d.ts.map +1 -1
  11. package/dist/db/recordings.d.ts +2 -1
  12. package/dist/db/recordings.d.ts.map +1 -1
  13. package/dist/db/remote-storage.d.ts +5 -1
  14. package/dist/db/remote-storage.d.ts.map +1 -1
  15. package/dist/index.d.ts +2 -2
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +628 -147
  18. package/dist/lib/bun-runtime.d.ts +11 -0
  19. package/dist/lib/bun-runtime.d.ts.map +1 -0
  20. package/dist/lib/config.d.ts +8 -1
  21. package/dist/lib/config.d.ts.map +1 -1
  22. package/dist/lib/enhancer.d.ts +10 -2
  23. package/dist/lib/enhancer.d.ts.map +1 -1
  24. package/dist/lib/install-maintenance.d.ts +24 -0
  25. package/dist/lib/install-maintenance.d.ts.map +1 -0
  26. package/dist/lib/machine.d.ts +2 -0
  27. package/dist/lib/machine.d.ts.map +1 -0
  28. package/dist/lib/recorder.d.ts +2 -1
  29. package/dist/lib/recorder.d.ts.map +1 -1
  30. package/dist/lib/recording-create-identity.d.ts +13 -0
  31. package/dist/lib/recording-create-identity.d.ts.map +1 -0
  32. package/dist/lib/release-install-policy.d.ts +31 -0
  33. package/dist/lib/release-install-policy.d.ts.map +1 -0
  34. package/dist/lib/transcriber.d.ts.map +1 -1
  35. package/dist/mcp/index.d.ts.map +1 -1
  36. package/dist/mcp/index.js +977 -194
  37. package/dist/sdk/index.js +5 -1
  38. package/dist/sdk/v1.generated.d.ts +4 -0
  39. package/dist/sdk/v1.generated.d.ts.map +1 -1
  40. package/dist/server/cloud-config.d.ts +9 -0
  41. package/dist/server/cloud-config.d.ts.map +1 -0
  42. package/dist/server/cloud-readiness.d.ts +10 -0
  43. package/dist/server/cloud-readiness.d.ts.map +1 -0
  44. package/dist/server/cloud.d.ts +9 -18
  45. package/dist/server/cloud.d.ts.map +1 -1
  46. package/dist/server/index.js +1654 -304
  47. package/dist/server/migrate-command.d.ts +11 -0
  48. package/dist/server/migrate-command.d.ts.map +1 -0
  49. package/dist/server/openapi.d.ts +22 -0
  50. package/dist/server/openapi.d.ts.map +1 -1
  51. package/dist/server/repo.d.ts +8 -1
  52. package/dist/server/repo.d.ts.map +1 -1
  53. package/dist/server/serve.d.ts +6 -1
  54. package/dist/server/serve.d.ts.map +1 -1
  55. package/dist/server/v1.d.ts.map +1 -1
  56. package/dist/storage.js +515 -80
  57. package/dist/store.d.ts +3 -1
  58. package/dist/store.d.ts.map +1 -1
  59. package/dist/types/index.d.ts +10 -0
  60. package/dist/types/index.d.ts.map +1 -1
  61. package/dist/version.d.ts +1 -1
  62. package/package.json +7 -4
  63. package/packaging/macos/Empty.entitlements +5 -0
  64. package/packaging/macos/Library/LaunchDaemons/com.hasna.recordings.updater.plist +34 -0
  65. package/packaging/macos/Verifier.entitlements +10 -0
  66. package/packaging/macos/artifact-verifier.sb +33 -0
  67. package/packaging/macos/build_release_pkg.sh +872 -0
  68. package/packaging/macos/managed_bootstrap.sh +623 -0
  69. package/packaging/macos/pkgutil_fingerprint.awk +37 -0
  70. package/packaging/macos/release_lifecycle.ts +463 -0
  71. package/packaging/macos/scripts/postinstall +565 -0
  72. package/packaging/macos/scripts/preinstall +297 -0
  73. package/scripts/build_companion_cli.sh +337 -0
  74. package/scripts/build_native_fs_guard.sh +59 -0
  75. package/scripts/generate-sdk.ts +19 -1
  76. package/scripts/install_macos_app.sh +1922 -77
  77. package/scripts/macos_artifact.ts +5316 -0
  78. package/scripts/migrate.ts +38 -10
  79. package/scripts/native/prebuilds/darwin-universal/recordings_fs_guard.node +0 -0
  80. package/scripts/native/recordings_fs_guard.c +1167 -0
  81. package/scripts/native_fs_guard.ts +158 -0
  82. package/scripts/release-guard.ts +20 -1
  83. package/scripts/resolve_tailscale_cli.sh +389 -0
  84. package/scripts/smoke_macos_app.sh +573 -0
  85. package/src/native/Recordings/App/ContentView.swift +83 -0
  86. package/src/native/Recordings/App/MenuBarStatusView.swift +102 -0
  87. package/src/native/Recordings/App/RecordWorkspaceView.swift +468 -0
  88. package/src/native/Recordings/App/RecordingDetailView.swift +138 -0
  89. package/src/native/Recordings/App/RecordingsApp.swift +367 -44
  90. package/src/native/Recordings/App/RecordingsListView.swift +130 -0
  91. package/src/native/Recordings/App/RecordingsStore.swift +206 -0
  92. package/src/native/Recordings/App/RuntimeSmoke.swift +158 -0
  93. package/src/native/Recordings/App/SidebarView.swift +212 -0
  94. package/src/native/Recordings/App/Theme.swift +87 -0
  95. package/src/native/Recordings/Package.resolved +5 -5
  96. package/src/native/Recordings/Package.swift +62 -2
  97. package/src/native/Recordings/RecordingsLib/AccessibilityPromptGate.swift +104 -0
  98. package/src/native/Recordings/RecordingsLib/BrandAssets.swift +0 -32
  99. package/src/native/Recordings/RecordingsLib/ChromeSurface.swift +17 -0
  100. package/src/native/Recordings/RecordingsLib/Info.plist +7 -3
  101. package/src/native/Recordings/RecordingsLib/MenuBarPresentation.swift +37 -0
  102. package/src/native/Recordings/RecordingsLib/NativeAppDiagnostics.swift +32 -2
  103. package/src/native/Recordings/RecordingsLib/NativeMachineIdentity.swift +24 -0
  104. package/src/native/Recordings/RecordingsLib/NativePCMRecorder.swift +262 -23
  105. package/src/native/Recordings/RecordingsLib/OpenAIAPIKeyStore.swift +56 -0
  106. package/src/native/Recordings/RecordingsLib/PermissionRequestLaunchPlan.swift +56 -0
  107. package/src/native/Recordings/RecordingsLib/ProjectStore.swift +321 -25
  108. package/src/native/Recordings/RecordingsLib/RealtimeTranscriptionClient.swift +605 -90
  109. package/src/native/Recordings/RecordingsLib/Recording.swift +141 -0
  110. package/src/native/Recordings/RecordingsLib/RecordingEngine.swift +3704 -376
  111. package/src/native/Recordings/RecordingsLib/RecordingStartControlPresentation.swift +29 -0
  112. package/src/native/Recordings/RecordingsLib/RecordingsCLI.entitlements +10 -0
  113. package/src/native/Recordings/RecordingsLib/RecordingsCLI.swift +222 -0
  114. package/src/native/Recordings/RecordingsLib/SettingsView.swift +45 -11
  115. package/src/native/Recordings/RecordingsLib/SpeechIntent.swift +331 -0
  116. package/src/native/Recordings/RecordingsLib/SpeechIntentClassifier.swift +232 -0
  117. package/src/native/Recordings/RecordingsLib/VoiceShortcuts.swift +17 -7
  118. package/src/native/Recordings/RecordingsTests/CLIRunnerTests.swift +1343 -0
  119. package/src/native/Recordings/RecordingsTests/MenuBarPresentationTests.swift +98 -0
  120. package/src/native/Recordings/RecordingsTests/NativeAppDiagnosticsTests.swift +20 -0
  121. package/src/native/Recordings/RecordingsTests/NativePCMRecorderTests.swift +370 -1
  122. package/src/native/Recordings/RecordingsTests/PasteTargetTests.swift +987 -1
  123. package/src/native/Recordings/RecordingsTests/ProjectStoreTests.swift +385 -0
  124. package/src/native/Recordings/RecordingsTests/RealtimeTranscriptionTests.swift +835 -8
  125. package/src/native/Recordings/RecordingsTests/RecordingBridgeTests.swift +180 -0
  126. package/src/native/Recordings/RecordingsTests/RecordingEngineDeliveryTests.swift +760 -0
  127. package/src/native/Recordings/RecordingsTests/RecordingStartControlPresentationTests.swift +42 -0
  128. package/src/native/Recordings/RecordingsTests/RecordingStartGateTests.swift +264 -0
  129. package/src/native/Recordings/RecordingsTests/RecordingStartTimingTests.swift +129 -0
  130. package/src/native/Recordings/RecordingsTests/SpeechIntentTests.swift +600 -0
  131. package/src/native/Recordings/RecordingsTests/TranscriptResolutionTests.swift +62 -1
  132. package/src/native/Recordings/RecordingsTests/TranscriptionResultIdentityTests.swift +21 -0
  133. package/src/native/Recordings/Updater/BootstrapPreflight/BootstrapPreflightMain.swift +739 -0
  134. package/src/native/Recordings/Updater/Broker/ActivationRecoveryPolicy.swift +254 -0
  135. package/src/native/Recordings/Updater/Broker/ApplicationNamespace.swift +463 -0
  136. package/src/native/Recordings/Updater/Broker/ApplicationProcessQuiescence.swift +55 -0
  137. package/src/native/Recordings/Updater/Broker/ArtifactIngest.swift +341 -0
  138. package/src/native/Recordings/Updater/Broker/AtomicActivation.swift +477 -0
  139. package/src/native/Recordings/Updater/Broker/BrokerMain.swift +624 -0
  140. package/src/native/Recordings/Updater/Broker/CanonicalTreeCopy.swift +63 -0
  141. package/src/native/Recordings/Updater/Broker/CodeValidation.swift +561 -0
  142. package/src/native/Recordings/Updater/Broker/DarwinACLValidator.swift +66 -0
  143. package/src/native/Recordings/Updater/Broker/HostOSProductVersion.swift +50 -0
  144. package/src/native/Recordings/Updater/Broker/InstallJournal.swift +362 -0
  145. package/src/native/Recordings/Updater/Broker/InstallRecovery.swift +662 -0
  146. package/src/native/Recordings/Updater/Broker/MonotonicState.swift +456 -0
  147. package/src/native/Recordings/Updater/Broker/PeerIdentity.swift +274 -0
  148. package/src/native/Recordings/Updater/Broker/VerifierRunner.swift +81 -0
  149. package/src/native/Recordings/Updater/BrokerTests/ActivationRecoveryPolicyTests.swift +259 -0
  150. package/src/native/Recordings/Updater/BrokerTests/CanonicalReleaseOrderTests.swift +21 -0
  151. package/src/native/Recordings/Updater/Client/ClientMain.swift +119 -0
  152. package/src/native/Recordings/Updater/Protocol/BoundedProcess.swift +159 -0
  153. package/src/native/Recordings/Updater/Protocol/CandidateMetadataPolicy.swift +214 -0
  154. package/src/native/Recordings/Updater/Protocol/HostOSVersionPolicy.swift +55 -0
  155. package/src/native/Recordings/Updater/Protocol/MonotonicReleasePolicy.swift +152 -0
  156. package/src/native/Recordings/Updater/Protocol/ReleaseEnvelope.swift +229 -0
  157. package/src/native/Recordings/Updater/Protocol/UpdateProtocol.swift +119 -0
  158. package/src/native/Recordings/Updater/ProtocolTests/BoundedProcessRunnerTests.swift +60 -0
  159. package/src/native/Recordings/Updater/ProtocolTests/CandidateMetadataPolicyTests.swift +168 -0
  160. package/src/native/Recordings/Updater/ProtocolTests/HostOSVersionPolicyTests.swift +62 -0
  161. package/src/native/Recordings/Updater/ProtocolTests/MonotonicReleasePolicyTests.swift +172 -0
  162. package/src/native/Recordings/Updater/ProtocolTests/ReleaseEnvelopeValidationTests.swift +65 -0
  163. package/src/native/Recordings/Updater/Signer/SignerMain.swift +210 -0
  164. package/src/native/Recordings/Updater/VerifierLauncher/RecordingsVerifierLauncher.c +725 -0
  165. package/src/native/Recordings/Updater/VerifierLauncher/include/RecordingsVerifierLauncher.h +33 -0
  166. package/src/native/Recordings/build.sh +1990 -29
  167. package/src/native/Recordings/RecordingsLib/MenuBarPopover.swift +0 -380
@@ -0,0 +1,141 @@
1
+ import Foundation
2
+
3
+ /// A persisted recording/transcript, decoded from the `recordings` CLI (`--json`).
4
+ /// This mirrors the TypeScript `Recording` shape so the macOS app reads the exact same
5
+ /// store the CLI/MCP write — no duplicated persistence logic.
6
+ public struct Recording: Identifiable, Codable, Sendable, Equatable {
7
+ public let id: String
8
+ public let audioPath: String?
9
+ public let rawText: String
10
+ public let processedText: String?
11
+ public let processingMode: String // "raw" | "enhanced"
12
+ public let modelUsed: String?
13
+ public let enhancementModel: String?
14
+ public let durationMs: Int
15
+ public let language: String?
16
+ public let tags: [String]
17
+ public let projectId: String?
18
+ public let machineId: String?
19
+ public let createdAt: String
20
+
21
+ enum CodingKeys: String, CodingKey {
22
+ case id
23
+ case audioPath = "audio_path"
24
+ case rawText = "raw_text"
25
+ case processedText = "processed_text"
26
+ case processingMode = "processing_mode"
27
+ case modelUsed = "model_used"
28
+ case enhancementModel = "enhancement_model"
29
+ case durationMs = "duration_ms"
30
+ case language
31
+ case tags
32
+ case projectId = "project_id"
33
+ case machineId = "machine_id"
34
+ case createdAt = "created_at"
35
+ }
36
+
37
+ public init(from decoder: Decoder) throws {
38
+ let c = try decoder.container(keyedBy: CodingKeys.self)
39
+ id = try c.decode(String.self, forKey: .id)
40
+ audioPath = try c.decodeIfPresent(String.self, forKey: .audioPath)
41
+ rawText = (try c.decodeIfPresent(String.self, forKey: .rawText)) ?? ""
42
+ processedText = try c.decodeIfPresent(String.self, forKey: .processedText)
43
+ processingMode = (try c.decodeIfPresent(String.self, forKey: .processingMode)) ?? "raw"
44
+ modelUsed = try c.decodeIfPresent(String.self, forKey: .modelUsed)
45
+ enhancementModel = try c.decodeIfPresent(String.self, forKey: .enhancementModel)
46
+ durationMs = (try c.decodeIfPresent(Int.self, forKey: .durationMs)) ?? 0
47
+ language = try c.decodeIfPresent(String.self, forKey: .language)
48
+ tags = (try c.decodeIfPresent([String].self, forKey: .tags)) ?? []
49
+ projectId = try c.decodeIfPresent(String.self, forKey: .projectId)
50
+ machineId = try c.decodeIfPresent(String.self, forKey: .machineId)
51
+ createdAt = (try c.decodeIfPresent(String.self, forKey: .createdAt)) ?? ""
52
+ }
53
+
54
+ // Memberwise init for tests / previews.
55
+ public init(id: String, audioPath: String? = nil, rawText: String, processedText: String? = nil,
56
+ processingMode: String = "raw", modelUsed: String? = nil, enhancementModel: String? = nil,
57
+ durationMs: Int = 0, language: String? = nil, tags: [String] = [],
58
+ projectId: String? = nil, machineId: String? = nil, createdAt: String = "") {
59
+ self.id = id
60
+ self.audioPath = audioPath
61
+ self.rawText = rawText
62
+ self.processedText = processedText
63
+ self.processingMode = processingMode
64
+ self.modelUsed = modelUsed
65
+ self.enhancementModel = enhancementModel
66
+ self.durationMs = durationMs
67
+ self.language = language
68
+ self.tags = tags
69
+ self.projectId = projectId
70
+ self.machineId = machineId
71
+ self.createdAt = createdAt
72
+ }
73
+
74
+ /// The user-facing text: enhanced output when available, otherwise the raw transcript.
75
+ public var displayText: String {
76
+ if let p = processedText, !p.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { return p }
77
+ return rawText
78
+ }
79
+
80
+ /// First line / short preview for list rows.
81
+ public var snippet: String {
82
+ let collapsed = displayText
83
+ .replacingOccurrences(of: "\n", with: " ")
84
+ .trimmingCharacters(in: .whitespacesAndNewlines)
85
+ if collapsed.isEmpty { return "No transcript" }
86
+ return collapsed.count > 140 ? String(collapsed.prefix(140)) + "…" : collapsed
87
+ }
88
+
89
+ public var isEnhanced: Bool { processingMode == "enhanced" }
90
+
91
+ public var durationSeconds: Double { Double(durationMs) / 1000.0 }
92
+
93
+ public var durationLabel: String {
94
+ let total = Int(durationSeconds.rounded())
95
+ let m = total / 60, s = total % 60
96
+ return m > 0 ? String(format: "%d:%02d", m, s) : "\(s)s"
97
+ }
98
+
99
+ public var createdDate: Date? { Recording.parseDate(createdAt) }
100
+
101
+ public static func parseDate(_ value: String) -> Date? {
102
+ guard !value.isEmpty else { return nil }
103
+ let withFrac = ISO8601DateFormatter()
104
+ withFrac.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
105
+ if let d = withFrac.date(from: value) { return d }
106
+ let plain = ISO8601DateFormatter()
107
+ plain.formatOptions = [.withInternetDateTime]
108
+ if let d = plain.date(from: value) { return d }
109
+ // SQLite "YYYY-MM-DD HH:MM:SS" fallback.
110
+ let df = DateFormatter()
111
+ df.locale = Locale(identifier: "en_US_POSIX")
112
+ df.timeZone = TimeZone(identifier: "UTC")
113
+ df.dateFormat = "yyyy-MM-dd HH:mm:ss"
114
+ return df.date(from: value)
115
+ }
116
+ }
117
+
118
+ /// Aggregate statistics (`recordings --json stats`).
119
+ public struct RecordingStats: Codable, Sendable {
120
+ public let total: Int
121
+ public let raw: Int
122
+ public let enhanced: Int
123
+ public let totalDurationMs: Int
124
+
125
+ enum CodingKeys: String, CodingKey {
126
+ case total, raw, enhanced
127
+ case totalDurationMs = "total_duration_ms"
128
+ }
129
+
130
+ public init(from decoder: Decoder) throws {
131
+ let c = try decoder.container(keyedBy: CodingKeys.self)
132
+ total = try c.decode(Int.self, forKey: .total)
133
+ raw = try c.decode(Int.self, forKey: .raw)
134
+ enhanced = try c.decode(Int.self, forKey: .enhanced)
135
+ totalDurationMs = try c.decode(Int.self, forKey: .totalDurationMs)
136
+ }
137
+
138
+ public init(total: Int, raw: Int, enhanced: Int, totalDurationMs: Int) {
139
+ self.total = total; self.raw = raw; self.enhanced = enhanced; self.totalDurationMs = totalDurationMs
140
+ }
141
+ }