@openclaw/facetime 2026.9.6 → 2026.9.7
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/assets/icon.png +0 -0
- package/dist/.setup/{setup-DUgC9yE7.mjs → setup-CoxvlB5L.mjs} +91 -128
- package/dist/doctor-contract-api.js +189 -7
- package/dist/index.js +1 -1
- package/dist/runtime-api.js +197 -238
- package/node_modules/typebox/build/compile/code.mjs +1 -2
- package/node_modules/typebox/build/compile/validator.mjs +5 -1
- package/node_modules/typebox/build/format/iri.mjs +16 -9
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +7 -5
- package/node_modules/typebox/build/guard/guard.mjs +14 -9
- package/node_modules/typebox/build/guard/index.mjs +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
- package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
- package/node_modules/typebox/build/schema/build.mjs +2 -3
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
- package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
- package/node_modules/typebox/build/schema/parse.mjs +3 -0
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
- package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
- package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
- package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
- package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
- package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
- package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +3 -1
- package/package.json +5 -5
- package/src/audio-pump.ts +9 -16
- package/src/call-events.ts +12 -26
- package/src/call-lifecycle.ts +3 -19
- package/src/runtime-call-control.ts +3 -12
- package/src/runtime-call-events.ts +4 -9
- package/src/runtime-state.ts +0 -10
- package/src/setup.ts +96 -173
- package/src/talk-driver.ts +217 -242
- /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
|
@@ -25,12 +25,7 @@ import {
|
|
|
25
25
|
type PendingFaceTimeDial,
|
|
26
26
|
} from "./outbound-call.js";
|
|
27
27
|
import { retainHelperResultPeers } from "./runtime-helper-results.js";
|
|
28
|
-
import {
|
|
29
|
-
createManagedCall,
|
|
30
|
-
readCallUUID,
|
|
31
|
-
updateCallStatus,
|
|
32
|
-
type ActiveFaceTimeCall,
|
|
33
|
-
} from "./runtime-state.js";
|
|
28
|
+
import { ActiveFaceTimeCall, readCallUUID, updateCallStatus } from "./runtime-state.js";
|
|
34
29
|
|
|
35
30
|
type CallControl = {
|
|
36
31
|
activateCallTalk(call: ActiveFaceTimeCall, options: { unmute: boolean }): Promise<void>;
|
|
@@ -152,7 +147,7 @@ export function createFaceTimeCallEventHandler(params: {
|
|
|
152
147
|
params.logger.warn("[facetime] ignored incoming call; another FaceTime bridge is active");
|
|
153
148
|
return;
|
|
154
149
|
}
|
|
155
|
-
const call =
|
|
150
|
+
const call = new ActiveFaceTimeCall({
|
|
156
151
|
callUUID,
|
|
157
152
|
phase: "ringing",
|
|
158
153
|
owner,
|
|
@@ -216,7 +211,7 @@ export function createFaceTimeCallEventHandler(params: {
|
|
|
216
211
|
params.logger.warn("[facetime] ignored active call; another FaceTime bridge is active");
|
|
217
212
|
return;
|
|
218
213
|
}
|
|
219
|
-
call =
|
|
214
|
+
call = new ActiveFaceTimeCall({
|
|
220
215
|
callUUID,
|
|
221
216
|
phase: "active",
|
|
222
217
|
owner,
|
|
@@ -299,7 +294,7 @@ export function createFaceTimeCallEventHandler(params: {
|
|
|
299
294
|
}
|
|
300
295
|
let ringingCall = resolveEventCall(event);
|
|
301
296
|
if (!ringingCall && params.calls.size === 0) {
|
|
302
|
-
ringingCall =
|
|
297
|
+
ringingCall = new ActiveFaceTimeCall({
|
|
303
298
|
callUUID,
|
|
304
299
|
phase: "ringing",
|
|
305
300
|
owner,
|
package/src/runtime-state.ts
CHANGED
|
@@ -201,13 +201,3 @@ export function updateCallStatus(call: ActiveFaceTimeCall, event: FaceTimeCallSt
|
|
|
201
201
|
);
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
-
|
|
205
|
-
export function createManagedCall(params: {
|
|
206
|
-
callUUID: string;
|
|
207
|
-
phase: "ringing" | "active";
|
|
208
|
-
owner: AuthenticatedFaceTimeOwner;
|
|
209
|
-
handle?: string;
|
|
210
|
-
peer?: FaceTimeHelperPeer;
|
|
211
|
-
}): ActiveFaceTimeCall {
|
|
212
|
-
return new ActiveFaceTimeCall(params);
|
|
213
|
-
}
|
package/src/setup.ts
CHANGED
|
@@ -33,7 +33,7 @@ type FaceTimeSetupCheck = {
|
|
|
33
33
|
status: FaceTimeSetupCheckStatus;
|
|
34
34
|
required: boolean;
|
|
35
35
|
message: string;
|
|
36
|
-
actionId?:
|
|
36
|
+
actionId?: keyof typeof SETUP_ACTIONS;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
export type FaceTimeSetupReport = {
|
|
@@ -58,86 +58,123 @@ type SetupParams = {
|
|
|
58
58
|
const XCODE_APP = "/Applications/Xcode.app";
|
|
59
59
|
const XCODE_CLANG = `${XCODE_APP}/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang`;
|
|
60
60
|
const XCODE_MACOS_SDK = `${XCODE_APP}/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk`;
|
|
61
|
-
const
|
|
62
|
-
"
|
|
63
|
-
const NATIVE_PACKAGE_ACTION = {
|
|
64
|
-
id: "install-native-package",
|
|
65
|
-
kind: "command",
|
|
66
|
-
label: "Install or reinstall the FaceTime native package with Homebrew",
|
|
67
|
-
command: NATIVE_PACKAGE_COMMAND,
|
|
68
|
-
} as const satisfies FaceTimeSetupAction;
|
|
69
|
-
|
|
70
|
-
const PRECHECK_ACTIONS: Record<
|
|
71
|
-
string,
|
|
72
|
-
Pick<FaceTimeSetupAction, "id" | "kind" | "label" | "command" | "gatewayMethod" | "settingsPath">
|
|
73
|
-
> = {
|
|
74
|
-
"capture-binary": {
|
|
75
|
-
id: NATIVE_PACKAGE_ACTION.id,
|
|
61
|
+
const SETUP_ACTIONS = {
|
|
62
|
+
"install-native-package": {
|
|
76
63
|
kind: "command",
|
|
77
|
-
label:
|
|
78
|
-
command:
|
|
64
|
+
label: "Install or reinstall the FaceTime native package with Homebrew",
|
|
65
|
+
command:
|
|
66
|
+
"if brew list --versions openclaw-facetime >/dev/null 2>&1; then brew reinstall openclaw/tap/openclaw-facetime; else brew install openclaw/tap/openclaw-facetime; fi",
|
|
79
67
|
},
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
68
|
+
"install-xcode-tools": {
|
|
69
|
+
kind: "command",
|
|
70
|
+
label: "Install full Xcode in /Applications",
|
|
71
|
+
command: "open 'https://apps.apple.com/us/app/xcode/id497799835'",
|
|
72
|
+
},
|
|
73
|
+
"enable-developer-tools": {
|
|
74
|
+
kind: "command",
|
|
75
|
+
label: "Enable developer tools access",
|
|
76
|
+
command: "sudo /usr/sbin/DevToolsSecurity -enable",
|
|
77
|
+
},
|
|
78
|
+
"disable-sip-debugging": {
|
|
79
|
+
kind: "recovery",
|
|
80
|
+
label: "Disable SIP debugging restrictions from macOS Recovery, then reboot and rerun setup",
|
|
81
|
+
command: "csrutil enable --without debug",
|
|
82
|
+
settingsPath: "macOS Recovery > Utilities > Terminal",
|
|
83
|
+
},
|
|
84
|
+
"verify-sip-status": {
|
|
85
|
+
kind: "command",
|
|
86
|
+
label: "Verify SIP status, then rerun setup",
|
|
87
|
+
command: "/usr/bin/csrutil status",
|
|
88
|
+
},
|
|
89
|
+
"configure-owner-handles": {
|
|
90
|
+
kind: "command",
|
|
91
|
+
label: "Configure ownerHandles",
|
|
92
|
+
command: "openclaw configure",
|
|
93
|
+
},
|
|
94
|
+
"restart-gateway": {
|
|
95
|
+
kind: "command",
|
|
96
|
+
label: "Stop the stale gateway process, then restart OpenClaw",
|
|
97
|
+
command: "openclaw gateway restart",
|
|
98
|
+
},
|
|
99
|
+
"wait-for-helper": {
|
|
100
|
+
kind: "automatic",
|
|
101
|
+
label: "Wait for automatic helper injection to finish",
|
|
102
|
+
},
|
|
103
|
+
"restart-call-apps": {
|
|
104
|
+
kind: "manual-test",
|
|
105
|
+
label: "Quit and reopen FaceTime and Phone, then let OpenClaw reinject the helper",
|
|
85
106
|
},
|
|
86
|
-
"
|
|
87
|
-
id: "install-driver",
|
|
107
|
+
"install-driver": {
|
|
88
108
|
kind: "gateway",
|
|
89
109
|
label: "Install or update the paired FaceTime audio driver",
|
|
90
110
|
gatewayMethod: "facetime.installDriver",
|
|
91
111
|
},
|
|
92
|
-
"physical-output": {
|
|
93
|
-
id: "select-physical-output",
|
|
112
|
+
"select-physical-output": {
|
|
94
113
|
kind: "system-settings",
|
|
95
114
|
label: "Select MacBook Speakers or another physical output",
|
|
96
115
|
settingsPath: "System Settings > Sound > Output",
|
|
97
116
|
},
|
|
98
|
-
"
|
|
99
|
-
id: "grant-system-audio",
|
|
117
|
+
"grant-system-audio": {
|
|
100
118
|
kind: "system-settings",
|
|
101
119
|
label: "Allow OpenClaw to capture FaceTime app audio",
|
|
102
120
|
settingsPath: "System Settings > Privacy & Security > Screen & System Audio Recording",
|
|
103
121
|
},
|
|
104
|
-
"realtime-provider": {
|
|
105
|
-
id: "configure-realtime-provider",
|
|
122
|
+
"configure-realtime-provider": {
|
|
106
123
|
kind: "command",
|
|
107
124
|
label: "Configure authentication for a registered realtime voice provider",
|
|
108
125
|
command: "openclaw configure",
|
|
109
126
|
},
|
|
127
|
+
"verify-focus": {
|
|
128
|
+
kind: "system-settings",
|
|
129
|
+
label: "Verify Focus is off or allows the expected caller",
|
|
130
|
+
settingsPath: "Control Center > Focus",
|
|
131
|
+
},
|
|
132
|
+
"allow-sharing-notifications": {
|
|
133
|
+
kind: "system-settings",
|
|
134
|
+
label: "Allow notifications while mirroring or sharing the display",
|
|
135
|
+
settingsPath: "System Settings > Notifications",
|
|
136
|
+
},
|
|
137
|
+
"live-outbound-test": {
|
|
138
|
+
kind: "manual-test",
|
|
139
|
+
label: "Place one outbound FaceTime audio call with facetime.dial",
|
|
140
|
+
gatewayMethod: "facetime.dial",
|
|
141
|
+
},
|
|
142
|
+
"live-audio-test": {
|
|
143
|
+
kind: "manual-test",
|
|
144
|
+
label: "Run one inbound and one outbound FaceTime audio call",
|
|
145
|
+
},
|
|
146
|
+
"review-live-voicemail": {
|
|
147
|
+
kind: "system-settings",
|
|
148
|
+
label: "Review Live Voicemail if inbound audio calls are screened",
|
|
149
|
+
settingsPath: "Phone > Settings > Live Voicemail",
|
|
150
|
+
},
|
|
151
|
+
} satisfies Record<string, Omit<FaceTimeSetupAction, "id">>;
|
|
152
|
+
|
|
153
|
+
const PRECHECK_ACTIONS: Record<string, keyof typeof SETUP_ACTIONS> = {
|
|
154
|
+
"capture-binary": "install-native-package",
|
|
155
|
+
"paired-driver-mic": "install-driver",
|
|
156
|
+
"paired-driver-feed": "install-driver",
|
|
157
|
+
"physical-output": "select-physical-output",
|
|
158
|
+
"process-tap": "grant-system-audio",
|
|
159
|
+
"realtime-provider": "configure-realtime-provider",
|
|
110
160
|
};
|
|
111
161
|
|
|
112
162
|
function firstLine(value: unknown): string | undefined {
|
|
113
163
|
return typeof value === "string" ? value.trim().split(/\r?\n/u)[0] || undefined : undefined;
|
|
114
164
|
}
|
|
115
165
|
|
|
116
|
-
function
|
|
117
|
-
if (!actions.some((candidate) => candidate.id === action.id)) {
|
|
118
|
-
actions.push(action);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function addPreflightCheck(
|
|
123
|
-
checks: FaceTimeSetupCheck[],
|
|
124
|
-
actions: FaceTimeSetupAction[],
|
|
125
|
-
check: FaceTimePreflightCheck,
|
|
126
|
-
): void {
|
|
166
|
+
function addPreflightCheck(checks: FaceTimeSetupCheck[], check: FaceTimePreflightCheck): void {
|
|
127
167
|
if (check.id === "call-app-running") {
|
|
128
168
|
return;
|
|
129
169
|
}
|
|
130
|
-
const
|
|
131
|
-
if (!check.ok && action) {
|
|
132
|
-
addAction(actions, action);
|
|
133
|
-
}
|
|
170
|
+
const actionId = PRECHECK_ACTIONS[check.id];
|
|
134
171
|
checks.push({
|
|
135
172
|
id: check.id,
|
|
136
173
|
label: check.label,
|
|
137
174
|
status: check.ok ? "ready" : check.required ? "action-required" : "recommended",
|
|
138
175
|
required: check.required,
|
|
139
176
|
message: check.message ?? (check.ok ? "ready" : "not ready"),
|
|
140
|
-
...(!check.ok &&
|
|
177
|
+
...(!check.ok && actionId ? { actionId } : {}),
|
|
141
178
|
});
|
|
142
179
|
}
|
|
143
180
|
|
|
@@ -275,7 +312,6 @@ async function inspectDriver(params: SetupParams): Promise<{
|
|
|
275
312
|
|
|
276
313
|
export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSetupReport> {
|
|
277
314
|
const checks: FaceTimeSetupCheck[] = [];
|
|
278
|
-
const actions: FaceTimeSetupAction[] = [];
|
|
279
315
|
|
|
280
316
|
const [xcodeCompiler, xcodeSdk] = await Promise.all([
|
|
281
317
|
checkCommand(params.runCommandWithTimeout, ["/bin/test", "-x", XCODE_CLANG], () => XCODE_CLANG),
|
|
@@ -294,16 +330,6 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
294
330
|
: `Full Xcode is required at ${XCODE_APP}; Command Line Tools alone cannot perform protected-app injection or build the local audio driver`,
|
|
295
331
|
...(!xcodeReady ? { actionId: "install-xcode-tools" } : {}),
|
|
296
332
|
});
|
|
297
|
-
if (!xcodeReady) {
|
|
298
|
-
// Keep the established action id stable for setup-report consumers while
|
|
299
|
-
// directing operators to the full Xcode app required by the native setup boundary.
|
|
300
|
-
addAction(actions, {
|
|
301
|
-
id: "install-xcode-tools",
|
|
302
|
-
kind: "command",
|
|
303
|
-
label: "Install full Xcode in /Applications",
|
|
304
|
-
command: "open 'https://apps.apple.com/us/app/xcode/id497799835'",
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
333
|
|
|
308
334
|
const developerSecurity = await checkCommand(
|
|
309
335
|
params.runCommandWithTimeout,
|
|
@@ -322,14 +348,6 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
322
348
|
: "Developer tools access is disabled; helper injection cannot attach to FaceTime or Phone",
|
|
323
349
|
...(!developerSecurityEnabled ? { actionId: "enable-developer-tools" } : {}),
|
|
324
350
|
});
|
|
325
|
-
if (!developerSecurityEnabled) {
|
|
326
|
-
addAction(actions, {
|
|
327
|
-
id: "enable-developer-tools",
|
|
328
|
-
kind: "command",
|
|
329
|
-
label: "Enable developer tools access",
|
|
330
|
-
command: "sudo /usr/sbin/DevToolsSecurity -enable",
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
351
|
|
|
334
352
|
const sip = await checkCommand(
|
|
335
353
|
params.runCommandWithTimeout,
|
|
@@ -359,22 +377,6 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
359
377
|
: "Could not verify SIP debugging restrictions; run csrutil status before changing protection settings",
|
|
360
378
|
...(!debuggingRestrictionsDisabled ? { actionId: sipActionId } : {}),
|
|
361
379
|
});
|
|
362
|
-
if (!debuggingRestrictionsDisabled && debuggingRestrictionsEnabled) {
|
|
363
|
-
addAction(actions, {
|
|
364
|
-
id: "disable-sip-debugging",
|
|
365
|
-
kind: "recovery",
|
|
366
|
-
label: "Disable SIP debugging restrictions from macOS Recovery, then reboot and rerun setup",
|
|
367
|
-
command: "csrutil enable --without debug",
|
|
368
|
-
settingsPath: "macOS Recovery > Utilities > Terminal",
|
|
369
|
-
});
|
|
370
|
-
} else if (!debuggingRestrictionsDisabled) {
|
|
371
|
-
addAction(actions, {
|
|
372
|
-
id: "verify-sip-status",
|
|
373
|
-
kind: "command",
|
|
374
|
-
label: "Verify SIP status, then rerun setup",
|
|
375
|
-
command: "/usr/bin/csrutil status",
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
380
|
|
|
379
381
|
checks.push({
|
|
380
382
|
id: "owner-handles",
|
|
@@ -387,14 +389,6 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
387
389
|
: "Configure at least one owner email address or phone number",
|
|
388
390
|
...(params.config.ownerHandles.length === 0 ? { actionId: "configure-owner-handles" } : {}),
|
|
389
391
|
});
|
|
390
|
-
if (params.config.ownerHandles.length === 0) {
|
|
391
|
-
addAction(actions, {
|
|
392
|
-
id: "configure-owner-handles",
|
|
393
|
-
kind: "command",
|
|
394
|
-
label: "Configure ownerHandles",
|
|
395
|
-
command: "openclaw configure",
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
392
|
|
|
399
393
|
checks.push({
|
|
400
394
|
id: "native-package",
|
|
@@ -404,11 +398,8 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
404
398
|
message: params.nativePackageReady
|
|
405
399
|
? "Compatible FaceTime capture and helper artifacts are installed"
|
|
406
400
|
: "Compatible FaceTime native helpers are not installed",
|
|
407
|
-
...(!params.nativePackageReady ? { actionId:
|
|
401
|
+
...(!params.nativePackageReady ? { actionId: "install-native-package" } : {}),
|
|
408
402
|
});
|
|
409
|
-
if (!params.nativePackageReady) {
|
|
410
|
-
addAction(actions, NATIVE_PACKAGE_ACTION);
|
|
411
|
-
}
|
|
412
403
|
|
|
413
404
|
// The runtime can finish asynchronous helper injection while the static
|
|
414
405
|
// checks above run. Resolve its status only when composing the live checks
|
|
@@ -425,18 +416,10 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
425
416
|
: (params.runtimeError ?? "FaceTime runtime is not running"),
|
|
426
417
|
...(!runtimeStatus
|
|
427
418
|
? {
|
|
428
|
-
actionId: params.nativePackageReady ? "restart-gateway" :
|
|
419
|
+
actionId: params.nativePackageReady ? "restart-gateway" : "install-native-package",
|
|
429
420
|
}
|
|
430
421
|
: {}),
|
|
431
422
|
});
|
|
432
|
-
if (!runtimeStatus && params.nativePackageReady) {
|
|
433
|
-
addAction(actions, {
|
|
434
|
-
id: "restart-gateway",
|
|
435
|
-
kind: "command",
|
|
436
|
-
label: "Stop the stale gateway process, then restart OpenClaw",
|
|
437
|
-
command: "openclaw gateway restart",
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
423
|
|
|
441
424
|
if (runtimeStatus) {
|
|
442
425
|
for (const target of runtimeStatus.helperTargets) {
|
|
@@ -467,19 +450,6 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
467
450
|
? { actionId: "restart-call-apps" }
|
|
468
451
|
: {}),
|
|
469
452
|
});
|
|
470
|
-
if (status === "repairing") {
|
|
471
|
-
addAction(actions, {
|
|
472
|
-
id: "wait-for-helper",
|
|
473
|
-
kind: "automatic",
|
|
474
|
-
label: "Wait for automatic helper injection to finish",
|
|
475
|
-
});
|
|
476
|
-
} else if (status === "action-required") {
|
|
477
|
-
addAction(actions, {
|
|
478
|
-
id: "restart-call-apps",
|
|
479
|
-
kind: "manual-test",
|
|
480
|
-
label: "Quit and reopen FaceTime and Phone, then let OpenClaw reinject the helper",
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
453
|
}
|
|
484
454
|
}
|
|
485
455
|
|
|
@@ -499,18 +469,10 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
499
469
|
: `Driver status: ${driver.status ?? "unknown"}`,
|
|
500
470
|
...(!driverReady
|
|
501
471
|
? {
|
|
502
|
-
actionId: params.nativePackageReady ? "install-driver" :
|
|
472
|
+
actionId: params.nativePackageReady ? "install-driver" : "install-native-package",
|
|
503
473
|
}
|
|
504
474
|
: {}),
|
|
505
475
|
});
|
|
506
|
-
if (!driverReady && params.nativePackageReady) {
|
|
507
|
-
addAction(actions, {
|
|
508
|
-
id: "install-driver",
|
|
509
|
-
kind: "gateway",
|
|
510
|
-
label: "Install or update the paired FaceTime audio driver",
|
|
511
|
-
gatewayMethod: "facetime.installDriver",
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
476
|
|
|
515
477
|
if (params.preflight) {
|
|
516
478
|
const preflight = await params.preflight;
|
|
@@ -518,31 +480,12 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
518
480
|
if (check.id === "helper-connected" && runtimeStatus?.helperTargets.length) {
|
|
519
481
|
continue;
|
|
520
482
|
}
|
|
521
|
-
addPreflightCheck(checks,
|
|
483
|
+
addPreflightCheck(checks, check);
|
|
522
484
|
}
|
|
523
485
|
}
|
|
524
486
|
|
|
525
|
-
|
|
526
|
-
checks.push(
|
|
527
|
-
if (focus.status === "verify-on-call") {
|
|
528
|
-
addAction(actions, {
|
|
529
|
-
id: "verify-focus",
|
|
530
|
-
kind: "system-settings",
|
|
531
|
-
label: "Verify Focus is off or allows the expected caller",
|
|
532
|
-
settingsPath: "Control Center > Focus",
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
const sharingNotifications = await checkNotificationsDuringSharing(params.runCommandWithTimeout);
|
|
537
|
-
checks.push(sharingNotifications);
|
|
538
|
-
if (sharingNotifications.status === "action-required") {
|
|
539
|
-
addAction(actions, {
|
|
540
|
-
id: "allow-sharing-notifications",
|
|
541
|
-
kind: "system-settings",
|
|
542
|
-
label: "Allow notifications while mirroring or sharing the display",
|
|
543
|
-
settingsPath: "System Settings > Notifications",
|
|
544
|
-
});
|
|
545
|
-
}
|
|
487
|
+
checks.push(await checkFocusMode(params));
|
|
488
|
+
checks.push(await checkNotificationsDuringSharing(params.runCommandWithTimeout));
|
|
546
489
|
|
|
547
490
|
checks.push({
|
|
548
491
|
id: "facetime-sign-in",
|
|
@@ -553,12 +496,6 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
553
496
|
"macOS does not expose a supported sign-in readiness API; verify with one outbound call",
|
|
554
497
|
actionId: "live-outbound-test",
|
|
555
498
|
});
|
|
556
|
-
addAction(actions, {
|
|
557
|
-
id: "live-outbound-test",
|
|
558
|
-
kind: "manual-test",
|
|
559
|
-
label: "Place one outbound FaceTime audio call with facetime.dial",
|
|
560
|
-
gatewayMethod: "facetime.dial",
|
|
561
|
-
});
|
|
562
499
|
|
|
563
500
|
const internalMediaStage = runtimeStatus?.calls.find(
|
|
564
501
|
(call) =>
|
|
@@ -577,13 +514,6 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
577
514
|
: "Internal media stages require an active call; remote audibility still needs a separate live check",
|
|
578
515
|
...(!internalMediaStage ? { actionId: "live-audio-test" } : {}),
|
|
579
516
|
});
|
|
580
|
-
if (!internalMediaStage) {
|
|
581
|
-
addAction(actions, {
|
|
582
|
-
id: "live-audio-test",
|
|
583
|
-
kind: "manual-test",
|
|
584
|
-
label: "Run one inbound and one outbound FaceTime audio call",
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
517
|
|
|
588
518
|
checks.push({
|
|
589
519
|
id: "live-voicemail",
|
|
@@ -594,22 +524,15 @@ export async function runFaceTimeSetup(params: SetupParams): Promise<FaceTimeSet
|
|
|
594
524
|
"If incoming FaceTime Audio rings are intercepted, turn off Live Voicemail on this unattended Mac",
|
|
595
525
|
actionId: "review-live-voicemail",
|
|
596
526
|
});
|
|
597
|
-
addAction(actions, {
|
|
598
|
-
id: "review-live-voicemail",
|
|
599
|
-
kind: "system-settings",
|
|
600
|
-
label: "Review Live Voicemail if inbound audio calls are screened",
|
|
601
|
-
settingsPath: "Phone > Settings > Live Voicemail",
|
|
602
|
-
});
|
|
603
527
|
|
|
604
|
-
const
|
|
605
|
-
(check) => !check.required || check.status === "ready" || check.status === "repairing",
|
|
606
|
-
);
|
|
607
|
-
const repairsPending = checks.some((check) => check.required && check.status === "repairing");
|
|
528
|
+
const ready = checks.every((check) => !check.required || check.status === "ready");
|
|
608
529
|
return {
|
|
609
|
-
ok:
|
|
610
|
-
readyForTest:
|
|
530
|
+
ok: ready,
|
|
531
|
+
readyForTest: ready,
|
|
611
532
|
liveCallProofRequired: true,
|
|
612
533
|
checks,
|
|
613
|
-
actions
|
|
534
|
+
actions: [...new Set(checks.flatMap((check) => (check.actionId ? [check.actionId] : [])))].map(
|
|
535
|
+
(id) => Object.assign({ id }, SETUP_ACTIONS[id]),
|
|
536
|
+
),
|
|
614
537
|
};
|
|
615
538
|
}
|