forked from Manuel/meeting-assistant
fix(macos): launch service with stable privacy identity
This commit is contained in:
@@ -30,6 +30,10 @@
|
||||
<MacOsMeetingIntegrationsSource>$(MSBuildProjectDirectory)/Native/MacOsMeetingIntegrations/main.swift</MacOsMeetingIntegrationsSource>
|
||||
<MacOsMeetingIntegrationsInfoPlist>$(MSBuildProjectDirectory)/Native/MacOsMeetingIntegrations/Info.plist</MacOsMeetingIntegrationsInfoPlist>
|
||||
<MacOsMeetingIntegrationsOutputPath>Native/macos-meeting-integrations</MacOsMeetingIntegrationsOutputPath>
|
||||
<MacOsLauncherSource>$(MSBuildProjectDirectory)/Native/MacOsLauncher/main.swift</MacOsLauncherSource>
|
||||
<MacOsLauncherInfoPlist>$(MSBuildProjectDirectory)/Native/MacOsLauncher/Info.plist</MacOsLauncherInfoPlist>
|
||||
<MacOsLauncherOutputPath>Native/macos-meeting-assistant-launcher</MacOsLauncherOutputPath>
|
||||
<MacOsApplicationBundlePath>MeetingAssistant.app</MacOsApplicationBundlePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -90,6 +94,26 @@
|
||||
<Exec Command="/usr/bin/codesign --force --deep --sign - "$(TargetDir)$(MacOsAudioCaptureBundlePath)"" />
|
||||
<Exec Command="/usr/bin/xcrun swiftc -parse-as-library -O -target $(MacOsAudioCaptureArchitecture)-apple-macos13.0 -framework AppKit -framework Carbon -framework WebKit "$(MacOsDesktopControlsSource)" -o "$(TargetDir)$(MacOsDesktopControlsOutputPath)"" />
|
||||
<Exec Command="/usr/bin/xcrun swiftc -parse-as-library -O -target $(MacOsAudioCaptureArchitecture)-apple-macos13.0 -framework AppKit -framework CoreGraphics -framework EventKit -framework ImageIO -framework UniformTypeIdentifiers -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __info_plist -Xlinker "$(MacOsMeetingIntegrationsInfoPlist)" "$(MacOsMeetingIntegrationsSource)" -o "$(TargetDir)$(MacOsMeetingIntegrationsOutputPath)"" />
|
||||
<Exec Command="/usr/bin/xcrun swiftc -parse-as-library -O -target $(MacOsAudioCaptureArchitecture)-apple-macos13.0 "$(MacOsLauncherSource)" -o "$(TargetDir)$(MacOsLauncherOutputPath)"" />
|
||||
</Target>
|
||||
|
||||
<Target
|
||||
Name="PackageMacOsApplication"
|
||||
AfterTargets="Publish"
|
||||
DependsOnTargets="CopyMeetingAssistantConfigToPublishRoot;CopyMacOsNativeHelpersToPublish"
|
||||
Condition="'$(MacOsNativeHelpersEnabled)' == 'true'">
|
||||
<RemoveDir Directories="$(PublishDir)$(MacOsApplicationBundlePath)" />
|
||||
<MakeDir Directories="$(PublishDir)$(MacOsApplicationBundlePath)/Contents/MacOS" />
|
||||
<MakeDir Directories="$(PublishDir)$(MacOsApplicationBundlePath)/Contents/Resources/app" />
|
||||
<ItemGroup>
|
||||
<MacOsPublishedRuntimeFiles Include="$(PublishDir)**/*" Exclude="$(PublishDir)$(MacOsApplicationBundlePath)/**/*" />
|
||||
</ItemGroup>
|
||||
<Copy
|
||||
SourceFiles="@(MacOsPublishedRuntimeFiles)"
|
||||
DestinationFiles="@(MacOsPublishedRuntimeFiles->'$(PublishDir)$(MacOsApplicationBundlePath)/Contents/Resources/app/%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||
<Copy SourceFiles="$(TargetDir)$(MacOsLauncherOutputPath)" DestinationFiles="$(PublishDir)$(MacOsApplicationBundlePath)/Contents/MacOS/MeetingAssistant" />
|
||||
<Copy SourceFiles="$(MacOsLauncherInfoPlist)" DestinationFiles="$(PublishDir)$(MacOsApplicationBundlePath)/Contents/Info.plist" />
|
||||
<Exec Command="/usr/bin/codesign --force --deep --sign - --requirements '=designated => identifier "cloud.schweigert.meeting-assistant"' "$(PublishDir)$(MacOsApplicationBundlePath)"" />
|
||||
</Target>
|
||||
|
||||
<Target
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>MeetingAssistant</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>cloud.schweigert.meeting-assistant</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Meeting Assistant</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
<key>NSCalendarsFullAccessUsageDescription</key>
|
||||
<string>Meeting Assistant reads calendar metadata for meeting notes and recording prompts.</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>Meeting Assistant records microphone audio for live meeting transcription.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,70 @@
|
||||
import Darwin
|
||||
import Dispatch
|
||||
import Foundation
|
||||
|
||||
@main
|
||||
private struct MeetingAssistantLauncher {
|
||||
private static let serviceDirectoryName = "MeetingAssistant"
|
||||
|
||||
static func main() {
|
||||
let runtimeDirectory = Bundle.main.bundleURL
|
||||
.appendingPathComponent("Contents/Resources/app", isDirectory: true)
|
||||
let assemblyPath = runtimeDirectory.appendingPathComponent("MeetingAssistant.dll").path
|
||||
let environmentFile = FileManager.default.homeDirectoryForCurrentUser
|
||||
.appendingPathComponent("Library/Application Support")
|
||||
.appendingPathComponent(serviceDirectoryName)
|
||||
.appendingPathComponent("config/meeting-assistant.env")
|
||||
|
||||
guard FileManager.default.fileExists(atPath: assemblyPath) else {
|
||||
fail("Meeting Assistant runtime not found at \(assemblyPath)")
|
||||
}
|
||||
|
||||
guard FileManager.default.fileExists(atPath: environmentFile.path) else {
|
||||
fail("Meeting Assistant environment file not found at \(environmentFile.path)")
|
||||
}
|
||||
|
||||
let process = Process()
|
||||
process.executableURL = URL(fileURLWithPath: "/bin/zsh")
|
||||
process.arguments = [
|
||||
"-c",
|
||||
"set -a; source \"$1\"; set +a; exec /usr/local/share/dotnet/dotnet \"$2\" --contentRoot \"$3\"",
|
||||
"meeting-assistant-launcher",
|
||||
environmentFile.path,
|
||||
assemblyPath,
|
||||
runtimeDirectory.path
|
||||
]
|
||||
process.currentDirectoryURL = runtimeDirectory
|
||||
|
||||
signal(SIGTERM, SIG_IGN)
|
||||
signal(SIGINT, SIG_IGN)
|
||||
|
||||
let terminationSignal = DispatchSource.makeSignalSource(signal: SIGTERM, queue: .global())
|
||||
terminationSignal.setEventHandler {
|
||||
if process.isRunning {
|
||||
process.terminate()
|
||||
}
|
||||
}
|
||||
terminationSignal.resume()
|
||||
|
||||
let interruptSignal = DispatchSource.makeSignalSource(signal: SIGINT, queue: .global())
|
||||
interruptSignal.setEventHandler {
|
||||
if process.isRunning {
|
||||
kill(process.processIdentifier, SIGINT)
|
||||
}
|
||||
}
|
||||
interruptSignal.resume()
|
||||
|
||||
do {
|
||||
try process.run()
|
||||
process.waitUntilExit()
|
||||
Darwin.exit(process.terminationStatus)
|
||||
} catch {
|
||||
fail("Meeting Assistant launcher failed: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private static func fail(_ message: String) -> Never {
|
||||
FileHandle.standardError.write(Data("\(message)\n".utf8))
|
||||
Darwin.exit(1)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user