@elizaos/app-core 2.0.0-beta.1 → 2.0.0-beta.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.
Files changed (43) hide show
  1. package/package.json +2 -2
  2. package/platforms/electrobun/native/macos/window-effects.mm +103 -0
  3. package/platforms/electrobun/package.json +9 -0
  4. package/platforms/electrobun/src/__stubs__/bun-ffi.ts +16 -0
  5. package/platforms/electrobun/src/libMacWindowEffects.dylib +0 -0
  6. package/platforms/electrobun/src/native/agent.ts +74 -3
  7. package/platforms/electrobun/src/native/desktop.ts +39 -6
  8. package/platforms/electrobun/src/native/mac-window-effects.ts +61 -1
  9. package/platforms/electrobun/src/native/permissions-shared.ts +3 -2
  10. package/platforms/electrobun/src/native/permissions.ts +11 -6
  11. package/platforms/electrobun/src/rpc-handlers.ts +7 -0
  12. package/platforms/electrobun/src/rpc-schema.ts +39 -4
  13. package/platforms/electrobun/src/runtime-permissions.ts +7 -1
  14. package/runtime/ensure-local-inference-handler.d.ts +1 -0
  15. package/runtime/ensure-local-inference-handler.d.ts.map +1 -1
  16. package/runtime/ensure-local-inference-handler.js +9 -0
  17. package/runtime/mode/remote-forwarder.d.ts.map +1 -1
  18. package/runtime/mode/remote-forwarder.js +1 -1
  19. package/runtime/mode/runtime-mode.d.ts +20 -2
  20. package/runtime/mode/runtime-mode.d.ts.map +1 -1
  21. package/runtime/mode/runtime-mode.js +69 -1
  22. package/scripts/aosp/stage-default-models.mjs +2 -2
  23. package/scripts/build-llama-cpp-dflash.mjs +75 -40
  24. package/scripts/kernel-patches/metal-kernels.mjs +357 -337
  25. package/scripts/lib/read-app-identity.mjs +5 -1
  26. package/services/local-inference/catalog.d.ts +2 -1
  27. package/services/local-inference/catalog.d.ts.map +1 -1
  28. package/services/local-inference/catalog.js +131 -12
  29. package/services/local-inference/downloader.d.ts +2 -0
  30. package/services/local-inference/downloader.d.ts.map +1 -1
  31. package/services/local-inference/downloader.js +300 -1
  32. package/services/local-inference/manifest/validator.d.ts.map +1 -1
  33. package/services/local-inference/manifest/validator.js +48 -0
  34. package/services/local-inference/providers.d.ts +1 -1
  35. package/services/local-inference/providers.js +6 -6
  36. package/services/local-inference/registry.d.ts.map +1 -1
  37. package/services/local-inference/registry.js +10 -1
  38. package/services/local-inference/types.d.ts +6 -0
  39. package/services/local-inference/types.d.ts.map +1 -1
  40. package/test/helpers/real-runtime.ts +21 -20
  41. package/platforms/electrobun/src/native/permissions-darwin.ts +0 -342
  42. package/platforms/electrobun/src/native/permissions-linux.ts +0 -34
  43. package/platforms/electrobun/src/native/permissions-win32.ts +0 -56
@@ -113,6 +113,54 @@ function collectContractErrors(m) {
113
113
  errors.push("evals.e2eLoopOk: false");
114
114
  if (!m.evals.thirtyTurnOk)
115
115
  errors.push("evals.thirtyTurnOk: false");
116
+ // Optional component slots must be internally consistent: a shipped
117
+ // component needs auditable lineage, and lineage may not point at a
118
+ // component absent from the bundle. Components that affect runtime quality
119
+ // also require their own publish gate to pass.
120
+ for (const slot of ["asr", "embedding", "vision", "vad", "wakeword"]) {
121
+ const files = m.files[slot] ?? [];
122
+ const lineage = m.lineage[slot];
123
+ if (files.length > 0 && !lineage) {
124
+ errors.push(`lineage.${slot}: required when files.${slot} is non-empty`);
125
+ }
126
+ if (lineage && files.length === 0) {
127
+ errors.push(`files.${slot}: required when lineage.${slot} is present`);
128
+ }
129
+ }
130
+ if ((m.files.asr ?? []).length > 0) {
131
+ if (!m.evals.asrWer) {
132
+ errors.push("evals.asrWer: required when files.asr is non-empty");
133
+ }
134
+ else if (!m.evals.asrWer.passed) {
135
+ errors.push("evals.asrWer.passed: false");
136
+ }
137
+ }
138
+ if ((m.files.embedding ?? []).length > 0) {
139
+ if (!m.evals.embedMteb) {
140
+ errors.push("evals.embedMteb: required when files.embedding is non-empty");
141
+ }
142
+ else if (!m.evals.embedMteb.passed) {
143
+ errors.push("evals.embedMteb.passed: false");
144
+ }
145
+ }
146
+ if ((m.files.vad ?? []).length > 0) {
147
+ if (!m.evals.vadLatencyMs) {
148
+ errors.push("evals.vadLatencyMs: required when files.vad is non-empty");
149
+ }
150
+ else if (!m.evals.vadLatencyMs.passed) {
151
+ errors.push("evals.vadLatencyMs.passed: false");
152
+ }
153
+ }
154
+ const expressiveVoice = m.voice?.capabilities.includes("emotion-tags") ||
155
+ m.voice?.capabilities.includes("singing");
156
+ if (expressiveVoice) {
157
+ if (!m.evals.expressive) {
158
+ errors.push("evals.expressive: required when voice capabilities include emotion-tags or singing");
159
+ }
160
+ else if (!m.evals.expressive.passed) {
161
+ errors.push("evals.expressive.passed: false");
162
+ }
163
+ }
116
164
  // The strongest claim: defaultEligible. If anything above failed, this
117
165
  // flag must be false. (Contract errors are already accumulated; we add
118
166
  // an explicit message so callers can identify the violation cleanly.)
@@ -2,7 +2,7 @@
2
2
  * Provider registry.
3
3
  *
4
4
  * Treats every inference source the same way — cloud subscription, cloud
5
- * API, local llama.cpp engine, paired-device bridge, Capacitor on-device
5
+ * API, Eliza-1 local runtime, paired-device bridge, Capacitor on-device
6
6
  * — each is a `ProviderDefinition` with an `id`, a human label, a set of
7
7
  * supported model slots, and a pluggable `getEnableState()` that inspects
8
8
  * whatever underlying gate controls it (API key presence, subscription
@@ -2,7 +2,7 @@
2
2
  * Provider registry.
3
3
  *
4
4
  * Treats every inference source the same way — cloud subscription, cloud
5
- * API, local llama.cpp engine, paired-device bridge, Capacitor on-device
5
+ * API, Eliza-1 local runtime, paired-device bridge, Capacitor on-device
6
6
  * — each is a `ProviderDefinition` with an `id`, a human label, a set of
7
7
  * supported model slots, and a pluggable `getEnableState()` that inspects
8
8
  * whatever underlying gate controls it (API key presence, subscription
@@ -34,9 +34,9 @@ export function getRegisteredSlotsForProvider(providerId) {
34
34
  // ── Built-in provider definitions ────────────────────────────────────
35
35
  const LOCAL_PROVIDER = {
36
36
  id: "eliza-local-inference",
37
- label: "Local llama.cpp",
37
+ label: "Eliza-1 local runtime",
38
38
  kind: "local",
39
- description: "On-device inference using node-llama-cpp, with DFlash llama-server acceleration when the managed binary and drafter companion are installed. The plugin-local-embedding companion serves the TEXT_EMBEDDING slot from the same node-llama-cpp runtime.",
39
+ description: "On-device Eliza-1 inference with the optimized local runtime when the managed binary and companion files are installed. The local embedding companion serves the TEXT_EMBEDDING slot from the same runtime.",
40
40
  // TEXT_EMBEDDING is served by the plugin-local-embedding plugin, which
41
41
  // registers its own model handler against the runtime. We advertise the
42
42
  // slot here so the providers panel reports it as supported by the local
@@ -56,7 +56,7 @@ const LOCAL_PROVIDER = {
56
56
  return { enabled: false, reason: "No local model installed" };
57
57
  const dflash = getDflashRuntimeStatus();
58
58
  return dflash.enabled
59
- ? { enabled: true, reason: "GGUF model installed; DFlash available" }
59
+ ? { enabled: true, reason: "Eliza-1 model installed; local acceleration available" }
60
60
  : { enabled: true, reason: "GGUF model installed" };
61
61
  }
62
62
  catch {
@@ -98,9 +98,9 @@ const DEVICE_BRIDGE_PROVIDER = {
98
98
  };
99
99
  const CAPACITOR_LLAMA_PROVIDER = {
100
100
  id: "capacitor-llama",
101
- label: "On-device llama.cpp (mobile)",
101
+ label: "Eliza-1 mobile runtime",
102
102
  kind: "local",
103
- description: "Runs llama.cpp natively on iOS or Android via Capacitor. Only available in mobile builds.",
103
+ description: "Runs Eliza-1 natively on iOS or Android via Capacitor. Only available in mobile builds.",
104
104
  supportedSlots: ["TEXT_SMALL", "TEXT_LARGE"],
105
105
  async getEnableState() {
106
106
  const cap = globalThis.Capacitor;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../../../src/services/local-inference/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAmC9C;;;;GAIG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAcrE;AAED,wEAAwE;AACxE,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAe3E;AAED,gEAAgE;AAChE,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/D;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;CACnC,CAAC,CAyBD"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../../../src/services/local-inference/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAmC9C;;;;GAIG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAcrE;AAED,wEAAwE;AACxE,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB3E;AAED,gEAAgE;AAChE,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/D;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;CACnC,CAAC,CA6BD"}
@@ -62,6 +62,12 @@ export async function upsertElizaModel(model) {
62
62
  if (!isWithinElizaRoot(model.path)) {
63
63
  throw new Error("[local-inference] Eliza-owned models must live under the local-inference root");
64
64
  }
65
+ if (model.bundleRoot && !isWithinElizaRoot(model.bundleRoot)) {
66
+ throw new Error("[local-inference] Eliza-owned bundle roots must live under the local-inference root");
67
+ }
68
+ if (model.manifestPath && !isWithinElizaRoot(model.manifestPath)) {
69
+ throw new Error("[local-inference] Eliza-owned manifests must live under the local-inference root");
70
+ }
65
71
  const owned = await readElizaOwned();
66
72
  const withoutCurrent = owned.filter((m) => m.id !== model.id);
67
73
  withoutCurrent.push(model);
@@ -97,8 +103,11 @@ export async function removeElizaModel(id) {
97
103
  if (!isWithinElizaRoot(target.path)) {
98
104
  return { removed: false, reason: "external" };
99
105
  }
106
+ const removePath = target.bundleRoot && isWithinElizaRoot(target.bundleRoot)
107
+ ? target.bundleRoot
108
+ : target.path;
100
109
  try {
101
- await fs.rm(target.path, { force: true });
110
+ await fs.rm(removePath, { recursive: true, force: true });
102
111
  }
103
112
  catch {
104
113
  // If the file was already gone we still want to clear the registry entry.
@@ -131,6 +131,12 @@ export interface CatalogModel {
131
131
  hfRepo: string;
132
132
  /** Exact GGUF filename in the repo. */
133
133
  ggufFile: string;
134
+ /**
135
+ * Optional Eliza-1 bundle manifest in the same HF repo. When present, the
136
+ * downloader installs every file listed in the manifest and uses
137
+ * `ggufFile` as the primary text GGUF inside that bundle.
138
+ */
139
+ bundleManifestFile?: string;
134
140
  params: "360M" | "1B" | "1.7B" | "2B" | "3B" | "4B" | "7B" | "8B" | "9B" | "14B" | "16B" | "22B" | "24B" | "27B" | "32B";
135
141
  quant: string;
136
142
  sizeGb: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/services/local-inference/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/services/local-inference/types.ts"],"names":[],"mappings":"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"}
@@ -317,26 +317,6 @@ export async function createRealTestRuntime(
317
317
  // Always register plugin-sql for PGLite database.
318
318
  await runtime.registerPlugin(await importPluginSql());
319
319
 
320
- if (
321
- options?.withLLM &&
322
- process.env.ELIZA_DISABLE_LOCAL_EMBEDDING_PLUGIN !== "1"
323
- ) {
324
- try {
325
- const { default: localEmbeddingPlugin } = await import(
326
- "@elizaos/plugin-local-embedding"
327
- );
328
- configureLocalEmbeddingPlugin(localEmbeddingPlugin as Plugin);
329
- await runtime.registerPlugin(localEmbeddingPlugin as Plugin);
330
- logger.info(
331
- "[real-runtime] Registered local embedding plugin for TEXT_EMBEDDING",
332
- );
333
- } catch (err) {
334
- logger.warn(
335
- `[real-runtime] Failed to register local embedding plugin: ${err}`,
336
- );
337
- }
338
- }
339
-
340
320
  // Register LLM plugin if requested
341
321
  let providerName: LiveProviderName | null = null;
342
322
  let providerConfig: LiveProviderConfig | null = null;
@@ -391,6 +371,27 @@ export async function createRealTestRuntime(
391
371
  }
392
372
  }
393
373
 
374
+ if (
375
+ options?.withLLM &&
376
+ !providerConfig &&
377
+ process.env.ELIZA_DISABLE_LOCAL_EMBEDDING_PLUGIN !== "1"
378
+ ) {
379
+ try {
380
+ const { default: localEmbeddingPlugin } = await import(
381
+ "@elizaos/plugin-local-embedding"
382
+ );
383
+ configureLocalEmbeddingPlugin(localEmbeddingPlugin as Plugin);
384
+ await runtime.registerPlugin(localEmbeddingPlugin as Plugin);
385
+ logger.info(
386
+ "[real-runtime] Registered local embedding plugin for TEXT_EMBEDDING",
387
+ );
388
+ } catch (err) {
389
+ logger.warn(
390
+ `[real-runtime] Failed to register local embedding plugin: ${err}`,
391
+ );
392
+ }
393
+ }
394
+
394
395
  // Register Discord plugin if requested and token available
395
396
  if (options?.withDiscord && process.env.DISCORD_BOT_TOKEN?.trim()) {
396
397
  try {
@@ -1,342 +0,0 @@
1
- import { dlopen, FFIType } from "bun:ffi";
2
- import { existsSync, readFileSync } from "node:fs";
3
- import os from "node:os";
4
- import path from "node:path";
5
- import { getBrandConfig } from "../brand-config";
6
-
7
- import type {
8
- PermissionCheckResult,
9
- PermissionStatus,
10
- SystemPermissionId,
11
- } from "./permissions-shared";
12
-
13
- interface NativePermissionsLib {
14
- requestAccessibilityPermission: () => boolean;
15
- checkAccessibilityPermission: () => boolean;
16
- requestScreenRecordingPermission: () => boolean;
17
- checkScreenRecordingPermission: () => boolean;
18
- checkMicrophonePermission: () => number;
19
- checkCameraPermission: () => number;
20
- requestCameraPermission: () => void;
21
- requestMicrophonePermission: () => void;
22
- }
23
-
24
- type TccPermissionService =
25
- | "kTCCServiceAccessibility"
26
- | "kTCCServiceScreenCapture";
27
-
28
- const DEFAULT_APP_BUNDLE_ID = getBrandConfig().appId;
29
- const sessionPromptedPermissions = new Set<SystemPermissionId>();
30
-
31
- let nativeLib: NativePermissionsLib | null = null;
32
- /** After the first load attempt (success or failure), do not call `dlopen` again. */
33
- let nativeLibResolved = false;
34
-
35
- function getNativeLib(): NativePermissionsLib | null {
36
- if (nativeLibResolved) {
37
- return nativeLib;
38
- }
39
- nativeLibResolved = true;
40
-
41
- const dylibPath = path.join(import.meta.dir, "../libMacWindowEffects.dylib");
42
- if (!existsSync(dylibPath)) {
43
- console.warn(
44
- `[Permissions] Native permission dylib missing at ${dylibPath}. Preflight uses safe fallbacks. Build with: (cd apps/app/electrobun && bun run build:native-effects)`,
45
- );
46
- return null;
47
- }
48
-
49
- try {
50
- const { symbols } = dlopen(dylibPath, {
51
- requestAccessibilityPermission: { args: [], returns: FFIType.bool },
52
- checkAccessibilityPermission: { args: [], returns: FFIType.bool },
53
- requestScreenRecordingPermission: { args: [], returns: FFIType.bool },
54
- checkScreenRecordingPermission: { args: [], returns: FFIType.bool },
55
- checkMicrophonePermission: { args: [], returns: FFIType.i32 },
56
- checkCameraPermission: { args: [], returns: FFIType.i32 },
57
- requestCameraPermission: { args: [], returns: FFIType.void },
58
- requestMicrophonePermission: { args: [], returns: FFIType.void },
59
- });
60
- nativeLib = symbols as NativePermissionsLib;
61
- return nativeLib;
62
- } catch (error) {
63
- console.warn("[Permissions] Failed to load native dylib:", error);
64
- return null;
65
- }
66
- }
67
-
68
- export function resetPermissionSessionState(): void {
69
- sessionPromptedPermissions.clear();
70
- }
71
-
72
- function markPermissionInteraction(id: SystemPermissionId): void {
73
- if (id === "accessibility" || id === "screen-recording") {
74
- sessionPromptedPermissions.add(id);
75
- }
76
- }
77
-
78
- export function mapAvAuthorizationStatus(value: number): PermissionStatus {
79
- if (value === 2) {
80
- return "granted";
81
- }
82
- if (value === 1) {
83
- return "denied";
84
- }
85
- if (value === 3) {
86
- return "restricted";
87
- }
88
- return "not-determined";
89
- }
90
-
91
- export function resolveSessionPermissionStatus(options: {
92
- granted: boolean;
93
- promptedThisSession: boolean;
94
- tccStatus?: PermissionStatus | null;
95
- }): PermissionStatus {
96
- if (options.granted || options.tccStatus === "granted") {
97
- return "granted";
98
- }
99
- if (options.tccStatus === "denied" || options.promptedThisSession) {
100
- return "denied";
101
- }
102
- return "not-determined";
103
- }
104
-
105
- export function shouldOpenSettingsAfterMediaRequest(
106
- status: PermissionStatus,
107
- ): boolean {
108
- return status !== "granted";
109
- }
110
-
111
- export function extractBundleIdentifierFromInfoPlist(
112
- infoPlistText: string,
113
- ): string | null {
114
- const match = infoPlistText.match(
115
- /<key>\s*CFBundleIdentifier\s*<\/key>\s*<string>([^<]+)<\/string>/s,
116
- );
117
- return match?.[1]?.trim() ?? null;
118
- }
119
-
120
- function resolveInfoPlistPath(execPath: string): string | null {
121
- const macOsDir = path.dirname(path.resolve(execPath));
122
- const contentsDir = path.resolve(macOsDir, "..");
123
- const infoPlistPath = path.join(contentsDir, "Info.plist");
124
-
125
- if (existsSync(infoPlistPath)) {
126
- return infoPlistPath;
127
- }
128
-
129
- return null;
130
- }
131
-
132
- export function resolveRuntimeBundleIdentifier(
133
- execPath = process.execPath,
134
- ): string {
135
- try {
136
- const infoPlistPath = resolveInfoPlistPath(execPath);
137
- if (!infoPlistPath) {
138
- return DEFAULT_APP_BUNDLE_ID;
139
- }
140
- const infoPlistText = readFileSync(infoPlistPath, "utf8");
141
- return (
142
- extractBundleIdentifierFromInfoPlist(infoPlistText) ??
143
- DEFAULT_APP_BUNDLE_ID
144
- );
145
- } catch {
146
- return DEFAULT_APP_BUNDLE_ID;
147
- }
148
- }
149
-
150
- async function queryTccPermissionStatus(
151
- service: TccPermissionService,
152
- bundleIdentifier: string,
153
- ): Promise<PermissionStatus | null> {
154
- try {
155
- const tccDb = path.join(
156
- os.homedir(),
157
- "Library/Application Support/com.apple.TCC/TCC.db",
158
- );
159
- if (!existsSync(tccDb)) {
160
- return null;
161
- }
162
-
163
- const proc = Bun.spawn(
164
- [
165
- "sqlite3",
166
- tccDb,
167
- `SELECT auth_value FROM access WHERE service='${service}' AND client='${bundleIdentifier}'`,
168
- ],
169
- { stdout: "pipe", stderr: "pipe" },
170
- );
171
-
172
- const [stdout, stderr, exitCode] = await Promise.all([
173
- new Response(proc.stdout).text(),
174
- new Response(proc.stderr).text(),
175
- proc.exited,
176
- ]);
177
-
178
- if (exitCode !== 0 || stderr.includes("authorization denied")) {
179
- return null;
180
- }
181
-
182
- const authValue = stdout.trim();
183
- if (authValue === "2") {
184
- return "granted";
185
- }
186
- if (authValue === "0") {
187
- return "denied";
188
- }
189
- return null;
190
- } catch {
191
- return null;
192
- }
193
- }
194
-
195
- async function checkSessionAwarePermission(args: {
196
- id: "accessibility" | "screen-recording";
197
- granted: boolean;
198
- service: TccPermissionService;
199
- }): Promise<PermissionCheckResult> {
200
- const bundleIdentifier = resolveRuntimeBundleIdentifier();
201
- const tccStatus = args.granted
202
- ? null
203
- : await queryTccPermissionStatus(args.service, bundleIdentifier);
204
- const status = resolveSessionPermissionStatus({
205
- granted: args.granted,
206
- promptedThisSession: sessionPromptedPermissions.has(args.id),
207
- tccStatus,
208
- });
209
-
210
- return {
211
- status,
212
- canRequest: status === "not-determined",
213
- };
214
- }
215
-
216
- export async function checkPermission(
217
- id: SystemPermissionId,
218
- ): Promise<PermissionCheckResult> {
219
- switch (id) {
220
- case "accessibility": {
221
- const granted = getNativeLib()?.checkAccessibilityPermission() ?? false;
222
- return checkSessionAwarePermission({
223
- id,
224
- granted,
225
- service: "kTCCServiceAccessibility",
226
- });
227
- }
228
-
229
- case "screen-recording": {
230
- const granted = getNativeLib()?.checkScreenRecordingPermission() ?? false;
231
- return checkSessionAwarePermission({
232
- id,
233
- granted,
234
- service: "kTCCServiceScreenCapture",
235
- });
236
- }
237
-
238
- case "microphone": {
239
- const status = mapAvAuthorizationStatus(
240
- getNativeLib()?.checkMicrophonePermission() ?? 0,
241
- );
242
- return {
243
- status,
244
- canRequest: status === "not-determined",
245
- };
246
- }
247
-
248
- case "camera": {
249
- const status = mapAvAuthorizationStatus(
250
- getNativeLib()?.checkCameraPermission() ?? 0,
251
- );
252
- return {
253
- status,
254
- canRequest: status === "not-determined",
255
- };
256
- }
257
-
258
- case "shell":
259
- return { status: "granted", canRequest: false };
260
-
261
- default:
262
- return { status: "not-applicable", canRequest: false };
263
- }
264
- }
265
-
266
- export async function requestPermission(
267
- id: SystemPermissionId,
268
- ): Promise<PermissionCheckResult> {
269
- switch (id) {
270
- case "accessibility": {
271
- markPermissionInteraction(id);
272
- const granted = getNativeLib()?.requestAccessibilityPermission() ?? false;
273
- if (!granted) {
274
- await openPrivacySettings(id);
275
- }
276
- return checkPermission(id);
277
- }
278
-
279
- case "screen-recording": {
280
- markPermissionInteraction(id);
281
- const granted =
282
- getNativeLib()?.requestScreenRecordingPermission() ?? false;
283
- if (!granted) {
284
- await openPrivacySettings(id);
285
- }
286
- return checkPermission(id);
287
- }
288
-
289
- case "camera":
290
- getNativeLib()?.requestCameraPermission();
291
- {
292
- const result = await checkPermission(id);
293
- if (shouldOpenSettingsAfterMediaRequest(result.status)) {
294
- await openPrivacySettings(id);
295
- return checkPermission(id);
296
- }
297
- return result;
298
- }
299
-
300
- case "microphone":
301
- getNativeLib()?.requestMicrophonePermission();
302
- {
303
- const result = await checkPermission(id);
304
- if (shouldOpenSettingsAfterMediaRequest(result.status)) {
305
- await openPrivacySettings(id);
306
- return checkPermission(id);
307
- }
308
- return result;
309
- }
310
-
311
- case "shell":
312
- return { status: "granted", canRequest: false };
313
-
314
- default:
315
- return { status: "not-applicable", canRequest: false };
316
- }
317
- }
318
-
319
- export async function openPrivacySettings(
320
- id: SystemPermissionId,
321
- ): Promise<void> {
322
- markPermissionInteraction(id);
323
-
324
- const paneMap: Partial<Record<SystemPermissionId, string>> = {
325
- accessibility:
326
- "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility",
327
- "screen-recording":
328
- "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture",
329
- microphone:
330
- "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone",
331
- camera:
332
- "x-apple.systempreferences:com.apple.preference.security?Privacy_Camera",
333
- };
334
-
335
- const url = paneMap[id];
336
- if (!url) {
337
- return;
338
- }
339
-
340
- const proc = Bun.spawn(["open", url], { stdout: "pipe", stderr: "pipe" });
341
- await proc.exited;
342
- }
@@ -1,34 +0,0 @@
1
- import type {
2
- PermissionCheckResult,
3
- SystemPermissionId,
4
- } from "./permissions-shared";
5
-
6
- export async function checkPermission(
7
- id: SystemPermissionId,
8
- ): Promise<PermissionCheckResult> {
9
- switch (id) {
10
- case "microphone":
11
- case "camera":
12
- case "shell":
13
- return { status: "granted", canRequest: false };
14
-
15
- case "accessibility":
16
- case "screen-recording":
17
- return { status: "not-applicable", canRequest: false };
18
-
19
- default:
20
- return { status: "not-applicable", canRequest: false };
21
- }
22
- }
23
-
24
- export async function requestPermission(
25
- id: SystemPermissionId,
26
- ): Promise<PermissionCheckResult> {
27
- return checkPermission(id);
28
- }
29
-
30
- export async function openPrivacySettings(
31
- _id: SystemPermissionId,
32
- ): Promise<void> {
33
- // No standard privacy settings on Linux
34
- }
@@ -1,56 +0,0 @@
1
- import type {
2
- PermissionCheckResult,
3
- SystemPermissionId,
4
- } from "./permissions-shared";
5
-
6
- export async function checkPermission(
7
- id: SystemPermissionId,
8
- ): Promise<PermissionCheckResult> {
9
- switch (id) {
10
- case "microphone":
11
- case "camera":
12
- // Windows desktop privacy state is not reliably observable here.
13
- // Report requestable until runtime capture actually proves access.
14
- return { status: "not-determined", canRequest: true };
15
-
16
- case "shell":
17
- return { status: "granted", canRequest: false };
18
-
19
- case "accessibility":
20
- case "screen-recording":
21
- return { status: "not-applicable", canRequest: false };
22
-
23
- default:
24
- return { status: "not-applicable", canRequest: false };
25
- }
26
- }
27
-
28
- export async function requestPermission(
29
- id: SystemPermissionId,
30
- ): Promise<PermissionCheckResult> {
31
- if (id === "microphone" || id === "camera") {
32
- await openPrivacySettings(id);
33
- }
34
- return checkPermission(id);
35
- }
36
-
37
- export async function openPrivacySettings(
38
- id: SystemPermissionId,
39
- ): Promise<void> {
40
- const settingsMap: Record<string, string> = {
41
- microphone: "ms-settings:privacy-microphone",
42
- camera: "ms-settings:privacy-webcam",
43
- };
44
-
45
- const uri = settingsMap[id];
46
- if (uri) {
47
- try {
48
- Bun.spawn(["cmd", "/c", "start", uri], {
49
- stdout: "ignore",
50
- stderr: "ignore",
51
- });
52
- } catch {
53
- // Settings unavailable
54
- }
55
- }
56
- }