bleam 0.0.9 → 0.0.11
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/ai.cjs +608 -59
- package/dist/ai.d.cts +217 -89
- package/dist/ai.d.ts +217 -89
- package/dist/ai.js +601 -59
- package/dist/cli.cjs +142 -94
- package/dist/cli.d.cts +11 -27
- package/dist/cli.d.ts +11 -27
- package/dist/cli.js +143 -95
- package/dist/files.d.cts +1 -1
- package/dist/files.d.ts +1 -1
- package/dist/platform.cjs +1 -13
- package/dist/platform.d.cts +1 -26
- package/dist/platform.d.ts +1 -26
- package/dist/platform.js +1 -10
- package/dist/schema.d.cts +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/state.d.cts +1 -1
- package/dist/state.d.ts +1 -1
- package/dist/{ui-Bg11tvlc.d.ts → ui-CHc4xEs_.d.ts} +7 -7
- package/dist/ui.d.ts +1 -1
- package/dist/window.d.ts +1 -1
- package/package.json +2 -1
- package/templates/image-generation/app/index.tsx +3 -1
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/ModelRegistry.swift +1 -1
- package/templates/native/ios/Bleam/AI/Flux2/Pipeline/FluxImageRunner.swift +7 -2
- package/templates/native/ios/Bleam/AI/TextGeneration/Bonsai/BonsaiTextGenerator.swift +46 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Bonsai/BonsaiTextModel.swift +107 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Bonsai/BonsaiTextSnapshotValidator.swift +201 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Core/GenerationTypes.swift +85 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Core/ModelCapabilities.swift +21 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Core/TextKVCache.swift +23 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Core/TokenSampler.swift +79 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Qwen3/Qwen3CheckpointLoader.swift +161 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Qwen3/Qwen3Configuration.swift +119 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Qwen3/Qwen3InferenceSession.swift +84 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Qwen3/Qwen3Layers.swift +197 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Qwen3/Qwen3Model.swift +130 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Qwen35/Qwen35Checkpoint.swift +102 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Qwen35/Qwen35Configuration.swift +140 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Qwen35/Qwen35Model.swift +112 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/Qwen35/Qwen35Session.swift +121 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/QwenHybrid/QwenHybridCache.swift +42 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/QwenHybrid/QwenHybridFullAttention.swift +57 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/QwenHybrid/QwenHybridLayers.swift +58 -0
- package/templates/native/ios/Bleam/AI/TextGeneration/QwenHybrid/QwenHybridLinearAttention.swift +111 -0
- package/templates/native/ios/Bleam/AppDelegate.swift +0 -97
- package/templates/native/ios/Bleam.xcodeproj/project.pbxproj +128 -121
- package/templates/native/ios/GenerationService/BonsaiTextGenerationRunner.swift +103 -0
- package/templates/native/ios/GenerationService/ImageGenerationRunner.swift +19 -7
- package/templates/native/ios/GenerationService/main.swift +174 -48
- package/templates/native/ios/Shared/Generation/GenerationServiceProtocol.swift +3 -0
- package/templates/native/ios/Shared/Generation/GenerationWorkerProtocol.swift +44 -0
- package/templates/native/modules/bleam-runtime/ios/AIModule.swift +225 -5
- package/templates/native/modules/bleam-runtime/ios/GenerationContracts.swift +47 -0
- package/templates/native/modules/bleam-runtime/ios/PlatformModule.swift +0 -175
- package/templates/text-generation/app/index.tsx +93 -0
- package/templates/text-generation/app.config.ts +5 -0
- package/templates/updates/README.md +116 -0
- package/templates/updates/src/index.ts +292 -0
- package/templates/updates/src/schema.ts +230 -0
- package/templates/updates/tsconfig.json +12 -0
- package/templates/updates/wrangler.jsonc +19 -0
- package/templates/native/ios/PlatformHelper/Info.plist +0 -29
- package/templates/native/ios/PlatformHelper/main.swift +0 -335
- /package/dist/{files-DwA7pzr3.d.cts → files-4ZEoAWiv.d.ts} +0 -0
- /package/dist/{files-VrkQlKIT.d.ts → files-Dt5mbzLq.d.cts} +0 -0
- /package/dist/{schema-DOOjfXvs.d.ts → schema-CYh6n8GS.d.ts} +0 -0
- /package/dist/{schema-ENSMX_1t.d.cts → schema-oeOrd3i1.d.cts} +0 -0
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
import Foundation
|
|
2
|
-
import CryptoKit
|
|
3
|
-
import Security
|
|
4
|
-
import Darwin
|
|
5
|
-
|
|
6
|
-
@objc private protocol PlatformHelperProtocol {
|
|
7
|
-
func health(reply: @escaping (Data?) -> Void)
|
|
8
|
-
func downloadPlatformUpdate(requestData: Data, reply: @escaping (Data?) -> Void)
|
|
9
|
-
func applyPlatformUpdate(requestData: Data, reply: @escaping (Bool) -> Void)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
private struct DownloadRequest: Decodable {
|
|
13
|
-
let serviceURL: URL
|
|
14
|
-
let bundleIdentifier: String
|
|
15
|
-
let teamIdentifier: String
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
private struct ApplyRequest: Decodable {
|
|
19
|
-
let releaseId: String
|
|
20
|
-
let bundleIdentifier: String
|
|
21
|
-
let teamIdentifier: String
|
|
22
|
-
let installedAppPath: String
|
|
23
|
-
let appPID: Int32
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
private struct PlatformRelease: Decodable {
|
|
27
|
-
struct Artifact: Decodable {
|
|
28
|
-
let format: String
|
|
29
|
-
let url: URL
|
|
30
|
-
let sizeBytes: Int
|
|
31
|
-
let sha256: String
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let kind: String
|
|
35
|
-
let releaseId: String
|
|
36
|
-
let bundleIdentifier: String
|
|
37
|
-
let teamIdentifier: String
|
|
38
|
-
let appVersion: String
|
|
39
|
-
let buildNumber: String
|
|
40
|
-
let bleamPlatformVersion: String
|
|
41
|
-
let target: Target
|
|
42
|
-
let artifact: Artifact
|
|
43
|
-
|
|
44
|
-
struct Target: Decodable {
|
|
45
|
-
let minimumMacOSVersion: String
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private final class PlatformHelper: NSObject, PlatformHelperProtocol {
|
|
50
|
-
func health(reply: @escaping (Data?) -> Void) {
|
|
51
|
-
let response: [String: Any] = [
|
|
52
|
-
"healthy": true,
|
|
53
|
-
"protocolVersion": 1,
|
|
54
|
-
"helperVersion": Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "unknown",
|
|
55
|
-
"platformVersion": Bundle.main.object(forInfoDictionaryKey: "BleamPlatformVersion") as? String ?? "unknown",
|
|
56
|
-
"capabilities": ["platform-updates"],
|
|
57
|
-
]
|
|
58
|
-
reply(try? JSONSerialization.data(withJSONObject: response))
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
func downloadPlatformUpdate(requestData: Data, reply: @escaping (Data?) -> Void) {
|
|
62
|
-
guard
|
|
63
|
-
let request = try? JSONDecoder().decode(DownloadRequest.self, from: requestData),
|
|
64
|
-
let resolverURL = URL(
|
|
65
|
-
string: "/v1/apps/\(request.bundleIdentifier)/platform/macos-arm64",
|
|
66
|
-
relativeTo: request.serviceURL
|
|
67
|
-
)?.absoluteURL
|
|
68
|
-
else {
|
|
69
|
-
reply(nil)
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
URLSession.shared.dataTask(with: resolverURL) { data, response, _ in
|
|
74
|
-
guard
|
|
75
|
-
let data,
|
|
76
|
-
(response as? HTTPURLResponse)?.statusCode == 200,
|
|
77
|
-
let release = try? JSONDecoder().decode(PlatformRelease.self, from: data),
|
|
78
|
-
release.kind == "platform",
|
|
79
|
-
release.bundleIdentifier == request.bundleIdentifier,
|
|
80
|
-
release.teamIdentifier == request.teamIdentifier,
|
|
81
|
-
release.artifact.format == "bleam-macos-app-zip-v1",
|
|
82
|
-
release.releaseId.range(of: "^[a-z][a-z0-9_-]{2,127}$", options: .regularExpression) != nil
|
|
83
|
-
else {
|
|
84
|
-
reply(nil)
|
|
85
|
-
return
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
URLSession.shared.downloadTask(with: release.artifact.url) { temporaryURL, _, _ in
|
|
89
|
-
guard let temporaryURL else {
|
|
90
|
-
reply(nil)
|
|
91
|
-
return
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
do {
|
|
95
|
-
let cache = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
|
|
96
|
-
.appendingPathComponent("Bleam/Platform", isDirectory: true)
|
|
97
|
-
.appendingPathComponent(request.bundleIdentifier, isDirectory: true)
|
|
98
|
-
.appendingPathComponent(release.releaseId, isDirectory: true)
|
|
99
|
-
let completionReceipt = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)
|
|
100
|
-
.appendingPathComponent("Library/Application Support/Bleam/Updates", isDirectory: true)
|
|
101
|
-
.appendingPathComponent(request.bundleIdentifier, isDirectory: true)
|
|
102
|
-
.appendingPathComponent("\(release.releaseId).complete")
|
|
103
|
-
guard !FileManager.default.fileExists(atPath: completionReceipt.path) else {
|
|
104
|
-
reply(nil)
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
|
-
try FileManager.default.createDirectory(at: cache, withIntermediateDirectories: true)
|
|
108
|
-
let artifactURL = cache.appendingPathComponent("artifact.zip")
|
|
109
|
-
try? FileManager.default.removeItem(at: artifactURL)
|
|
110
|
-
try FileManager.default.moveItem(at: temporaryURL, to: artifactURL)
|
|
111
|
-
let appURL = try self.verify(
|
|
112
|
-
artifactURL: artifactURL,
|
|
113
|
-
release: release,
|
|
114
|
-
request: request,
|
|
115
|
-
cache: cache
|
|
116
|
-
)
|
|
117
|
-
let result: [String: Any] = [
|
|
118
|
-
"releaseId": release.releaseId,
|
|
119
|
-
"appVersion": release.appVersion,
|
|
120
|
-
"buildNumber": release.buildNumber,
|
|
121
|
-
"platformVersion": release.bleamPlatformVersion,
|
|
122
|
-
"artifactPath": artifactURL.path,
|
|
123
|
-
"appPath": appURL.path,
|
|
124
|
-
"sizeBytes": release.artifact.sizeBytes,
|
|
125
|
-
"sha256": release.artifact.sha256,
|
|
126
|
-
"verified": true,
|
|
127
|
-
]
|
|
128
|
-
let receipt: [String: Any] = [
|
|
129
|
-
"releaseId": release.releaseId,
|
|
130
|
-
"bundleIdentifier": request.bundleIdentifier,
|
|
131
|
-
"teamIdentifier": request.teamIdentifier,
|
|
132
|
-
"appPath": appURL.path,
|
|
133
|
-
]
|
|
134
|
-
let receiptData = try PropertyListSerialization.data(
|
|
135
|
-
fromPropertyList: receipt,
|
|
136
|
-
format: .binary,
|
|
137
|
-
options: 0
|
|
138
|
-
)
|
|
139
|
-
try receiptData.write(to: cache.appendingPathComponent("verified.plist"), options: .atomic)
|
|
140
|
-
reply(try? JSONSerialization.data(withJSONObject: result))
|
|
141
|
-
} catch {
|
|
142
|
-
reply(try? JSONSerialization.data(withJSONObject: [
|
|
143
|
-
"error": String(describing: error),
|
|
144
|
-
]))
|
|
145
|
-
}
|
|
146
|
-
}.resume()
|
|
147
|
-
}.resume()
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
func applyPlatformUpdate(requestData: Data, reply: @escaping (Bool) -> Void) {
|
|
151
|
-
guard
|
|
152
|
-
let request = try? JSONDecoder().decode(ApplyRequest.self, from: requestData),
|
|
153
|
-
let installedURL = supportedInstalledURL(path: request.installedAppPath),
|
|
154
|
-
let candidateURL = verifiedCandidate(request: request)
|
|
155
|
-
else {
|
|
156
|
-
reply(false)
|
|
157
|
-
return
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
reply(true)
|
|
161
|
-
let activity = ProcessInfo.processInfo.beginActivity(
|
|
162
|
-
options: [.userInitiated, .idleSystemSleepDisabled, .suddenTerminationDisabled],
|
|
163
|
-
reason: "Applying a verified Bleam platform update"
|
|
164
|
-
)
|
|
165
|
-
DispatchQueue.global(qos: .userInitiated).async {
|
|
166
|
-
defer { ProcessInfo.processInfo.endActivity(activity) }
|
|
167
|
-
for _ in 0..<50 where kill(request.appPID, 0) == 0 {
|
|
168
|
-
usleep(100_000)
|
|
169
|
-
}
|
|
170
|
-
if kill(request.appPID, 0) == 0 {
|
|
171
|
-
_ = kill(request.appPID, SIGTERM)
|
|
172
|
-
for _ in 0..<50 where kill(request.appPID, 0) == 0 {
|
|
173
|
-
usleep(100_000)
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
guard kill(request.appPID, 0) != 0 else {
|
|
177
|
-
NSLog("Bleam platform replacement failed: app did not terminate")
|
|
178
|
-
return
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
let releaseRoot = candidateURL
|
|
182
|
-
.deletingLastPathComponent().deletingLastPathComponent()
|
|
183
|
-
.deletingLastPathComponent()
|
|
184
|
-
let backupURL = releaseRoot.appendingPathComponent("previous.app")
|
|
185
|
-
do {
|
|
186
|
-
try? FileManager.default.removeItem(at: backupURL)
|
|
187
|
-
try FileManager.default.moveItem(at: installedURL, to: backupURL)
|
|
188
|
-
do {
|
|
189
|
-
try FileManager.default.moveItem(at: candidateURL, to: installedURL)
|
|
190
|
-
} catch {
|
|
191
|
-
try? FileManager.default.moveItem(at: backupURL, to: installedURL)
|
|
192
|
-
throw error
|
|
193
|
-
}
|
|
194
|
-
let receipts = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)
|
|
195
|
-
.appendingPathComponent("Library/Application Support/Bleam/Updates", isDirectory: true)
|
|
196
|
-
.appendingPathComponent(request.bundleIdentifier, isDirectory: true)
|
|
197
|
-
try FileManager.default.createDirectory(at: receipts, withIntermediateDirectories: true)
|
|
198
|
-
try Data().write(to: receipts.appendingPathComponent("\(request.releaseId).complete"))
|
|
199
|
-
_ = try self.run("/usr/bin/open", [installedURL.path])
|
|
200
|
-
} catch {
|
|
201
|
-
NSLog("Bleam platform replacement failed: %@", error.localizedDescription)
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
private func supportedInstalledURL(path: String) -> URL? {
|
|
207
|
-
let applications = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)
|
|
208
|
-
.appendingPathComponent("Applications", isDirectory: true).standardizedFileURL
|
|
209
|
-
let candidate = URL(fileURLWithPath: path, isDirectory: true).standardizedFileURL
|
|
210
|
-
guard
|
|
211
|
-
candidate.deletingLastPathComponent() == applications,
|
|
212
|
-
candidate.pathExtension == "app"
|
|
213
|
-
else { return nil }
|
|
214
|
-
return candidate
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
private func verifiedCandidate(request: ApplyRequest) -> URL? {
|
|
218
|
-
let root = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
|
|
219
|
-
.appendingPathComponent("Bleam/Platform", isDirectory: true)
|
|
220
|
-
.appendingPathComponent(request.bundleIdentifier, isDirectory: true)
|
|
221
|
-
.appendingPathComponent(request.releaseId, isDirectory: true)
|
|
222
|
-
let receiptURL = root.appendingPathComponent("verified.plist")
|
|
223
|
-
guard
|
|
224
|
-
let data = try? Data(contentsOf: receiptURL),
|
|
225
|
-
let receipt = try? PropertyListSerialization.propertyList(from: data, format: nil) as? [String: String],
|
|
226
|
-
receipt["releaseId"] == request.releaseId,
|
|
227
|
-
receipt["bundleIdentifier"] == request.bundleIdentifier,
|
|
228
|
-
receipt["teamIdentifier"] == request.teamIdentifier,
|
|
229
|
-
let path = receipt["appPath"]
|
|
230
|
-
else { return nil }
|
|
231
|
-
return URL(fileURLWithPath: path, isDirectory: true)
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
private func verify(
|
|
235
|
-
artifactURL: URL,
|
|
236
|
-
release: PlatformRelease,
|
|
237
|
-
request: DownloadRequest,
|
|
238
|
-
cache: URL
|
|
239
|
-
) throws -> URL {
|
|
240
|
-
let data = try Data(contentsOf: artifactURL, options: .mappedIfSafe)
|
|
241
|
-
guard
|
|
242
|
-
data.count == release.artifact.sizeBytes,
|
|
243
|
-
SHA256.hash(data: data).map({ String(format: "%02x", $0) }).joined() == release.artifact.sha256
|
|
244
|
-
else { throw VerificationError.invalidArtifact }
|
|
245
|
-
|
|
246
|
-
let entries = try run("/usr/bin/zipinfo", ["-1", artifactURL.path])
|
|
247
|
-
.split(separator: "\n").map(String.init)
|
|
248
|
-
guard !entries.isEmpty, entries.allSatisfy({ entry in
|
|
249
|
-
!entry.hasPrefix("/") && entry.split(separator: "/").allSatisfy { $0 != ".." }
|
|
250
|
-
}) else { throw VerificationError.unsafeArchivePath }
|
|
251
|
-
let appNames = Set(entries.compactMap { entry -> String? in
|
|
252
|
-
let parts = entry.split(separator: "/")
|
|
253
|
-
guard parts.count >= 2, parts[0] == "app", parts[1].hasSuffix(".app") else { return nil }
|
|
254
|
-
return String(parts[1])
|
|
255
|
-
})
|
|
256
|
-
guard
|
|
257
|
-
appNames.count == 1,
|
|
258
|
-
let appName = appNames.first,
|
|
259
|
-
entries.allSatisfy({ $0 == "app/" || $0.hasPrefix("app/\(appName)/") })
|
|
260
|
-
else { throw VerificationError.invalidArchiveLayout }
|
|
261
|
-
|
|
262
|
-
let extracted = cache.appendingPathComponent("extracted", isDirectory: true)
|
|
263
|
-
try? FileManager.default.removeItem(at: extracted)
|
|
264
|
-
try FileManager.default.createDirectory(at: extracted, withIntermediateDirectories: true)
|
|
265
|
-
_ = try run("/usr/bin/ditto", ["-x", "-k", artifactURL.path, extracted.path])
|
|
266
|
-
let appURL = extracted.appendingPathComponent("app/\(appName)")
|
|
267
|
-
guard
|
|
268
|
-
let info = NSDictionary(contentsOf: appURL.appendingPathComponent("Contents/Info.plist")),
|
|
269
|
-
info["CFBundleIdentifier"] as? String == request.bundleIdentifier,
|
|
270
|
-
info["CFBundleShortVersionString"] as? String == release.appVersion,
|
|
271
|
-
info["CFBundleVersion"] as? String == release.buildNumber,
|
|
272
|
-
let executable = info["CFBundleExecutable"] as? String
|
|
273
|
-
else { throw VerificationError.invalidIdentity }
|
|
274
|
-
|
|
275
|
-
var staticCode: SecStaticCode?
|
|
276
|
-
guard
|
|
277
|
-
SecStaticCodeCreateWithPath(appURL as CFURL, [], &staticCode) == errSecSuccess,
|
|
278
|
-
let staticCode,
|
|
279
|
-
SecStaticCodeCheckValidity(staticCode, SecCSFlags(rawValue: kSecCSStrictValidate), nil) == errSecSuccess
|
|
280
|
-
else { throw VerificationError.invalidSignature }
|
|
281
|
-
var signingInfo: CFDictionary?
|
|
282
|
-
guard
|
|
283
|
-
SecCodeCopySigningInformation(staticCode, SecCSFlags(rawValue: kSecCSSigningInformation), &signingInfo) == errSecSuccess,
|
|
284
|
-
(signingInfo as? [String: Any])?[kSecCodeInfoTeamIdentifier as String] as? String == request.teamIdentifier
|
|
285
|
-
else { throw VerificationError.invalidSignature }
|
|
286
|
-
|
|
287
|
-
let architectures = try run(
|
|
288
|
-
"/usr/bin/lipo",
|
|
289
|
-
["-archs", appURL.appendingPathComponent("Contents/MacOS/\(executable)").path]
|
|
290
|
-
).trimmingCharacters(in: .whitespacesAndNewlines)
|
|
291
|
-
guard architectures == "arm64" else { throw VerificationError.invalidArchitecture }
|
|
292
|
-
|
|
293
|
-
let required = release.target.minimumMacOSVersion.split(separator: ".").compactMap { Int($0) }
|
|
294
|
-
let current = ProcessInfo.processInfo.operatingSystemVersion
|
|
295
|
-
let installed = [current.majorVersion, current.minorVersion, current.patchVersion]
|
|
296
|
-
guard installed.lexicographicallyPrecedes(required) == false else {
|
|
297
|
-
throw VerificationError.unsupportedOS
|
|
298
|
-
}
|
|
299
|
-
return appURL
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
private func run(_ executable: String, _ arguments: [String]) throws -> String {
|
|
303
|
-
let process = Process()
|
|
304
|
-
let output = Pipe()
|
|
305
|
-
let errors = Pipe()
|
|
306
|
-
process.executableURL = URL(fileURLWithPath: executable)
|
|
307
|
-
process.arguments = arguments
|
|
308
|
-
process.standardOutput = output
|
|
309
|
-
process.standardError = errors
|
|
310
|
-
try process.run()
|
|
311
|
-
process.waitUntilExit()
|
|
312
|
-
guard process.terminationStatus == 0 else { throw VerificationError.commandFailed }
|
|
313
|
-
return String(decoding: output.fileHandleForReading.readDataToEndOfFile(), as: UTF8.self)
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
private enum VerificationError: Error {
|
|
318
|
-
case invalidArtifact, unsafeArchivePath, invalidArchiveLayout, invalidIdentity, invalidSignature
|
|
319
|
-
case invalidArchitecture, unsupportedOS, commandFailed
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
private final class PlatformHelperDelegate: NSObject, NSXPCListenerDelegate {
|
|
323
|
-
func listener(_ listener: NSXPCListener, shouldAcceptNewConnection connection: NSXPCConnection) -> Bool {
|
|
324
|
-
connection.exportedInterface = NSXPCInterface(with: PlatformHelperProtocol.self)
|
|
325
|
-
connection.exportedObject = PlatformHelper()
|
|
326
|
-
connection.resume()
|
|
327
|
-
return true
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
private let delegate = PlatformHelperDelegate()
|
|
332
|
-
private let listener = NSXPCListener.service()
|
|
333
|
-
listener.delegate = delegate
|
|
334
|
-
listener.resume()
|
|
335
|
-
RunLoop.main.run()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|