@ateam-ai-mobile/expo 0.1.19 → 0.1.21

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 (76) hide show
  1. package/dist/aiLive/provider.d.mts +20 -0
  2. package/dist/aiLive/provider.d.ts +20 -0
  3. package/dist/aiLive/provider.js +400 -0
  4. package/dist/aiLive/provider.js.map +1 -0
  5. package/dist/aiLive/provider.mjs +15 -0
  6. package/dist/aiLive/provider.mjs.map +1 -0
  7. package/dist/bootstrap.js +350 -3
  8. package/dist/bootstrap.js.map +1 -1
  9. package/dist/bootstrap.mjs +17 -12
  10. package/dist/bootstrap.mjs.map +1 -1
  11. package/dist/capabilities/index.d.mts +40 -1
  12. package/dist/capabilities/index.d.ts +40 -1
  13. package/dist/capabilities/index.js +50 -14
  14. package/dist/capabilities/index.js.map +1 -1
  15. package/dist/capabilities/index.mjs +49 -32
  16. package/dist/capabilities/index.mjs.map +1 -1
  17. package/dist/{chunk-42FP5DTO.mjs → chunk-2ZQEQJQ6.mjs} +1 -1
  18. package/dist/chunk-2ZQEQJQ6.mjs.map +1 -0
  19. package/dist/chunk-AE55BKYV.mjs +24 -0
  20. package/dist/chunk-AE55BKYV.mjs.map +1 -0
  21. package/dist/chunk-BAZFMTCC.mjs +815 -0
  22. package/dist/chunk-BAZFMTCC.mjs.map +1 -0
  23. package/dist/{chunk-Z5AI2SXX.mjs → chunk-C62NQA4F.mjs} +203 -1004
  24. package/dist/chunk-C62NQA4F.mjs.map +1 -0
  25. package/dist/{chunk-DE6Y4VRI.mjs → chunk-GA7DS3PA.mjs} +1 -1
  26. package/dist/{chunk-DE6Y4VRI.mjs.map → chunk-GA7DS3PA.mjs.map} +1 -1
  27. package/dist/chunk-GW7YGXOW.mjs +47 -0
  28. package/dist/chunk-GW7YGXOW.mjs.map +1 -0
  29. package/dist/chunk-JUBLG3PN.mjs +351 -0
  30. package/dist/chunk-JUBLG3PN.mjs.map +1 -0
  31. package/dist/{chunk-Z3P7RUCC.mjs → chunk-OEX4OKYQ.mjs} +13 -13
  32. package/dist/{chunk-6JX222YX.mjs → chunk-WQK6PUBN.mjs} +9 -2
  33. package/dist/chunk-WQK6PUBN.mjs.map +1 -0
  34. package/dist/device/createDeviceProvider.js.map +1 -1
  35. package/dist/device/createDeviceProvider.mjs +7 -6
  36. package/dist/device-bridge/index.mjs +8 -6
  37. package/dist/index.js.map +1 -1
  38. package/dist/index.mjs +1 -1
  39. package/dist/push/index.d.mts +24 -0
  40. package/dist/push/index.d.ts +24 -0
  41. package/dist/push/index.js +224 -0
  42. package/dist/push/index.js.map +1 -0
  43. package/dist/push/index.mjs +174 -0
  44. package/dist/push/index.mjs.map +1 -0
  45. package/dist/push/silentSync.d.mts +8 -0
  46. package/dist/push/silentSync.d.ts +8 -0
  47. package/dist/push/silentSync.js +1075 -0
  48. package/dist/push/silentSync.js.map +1 -0
  49. package/dist/push/silentSync.mjs +67 -0
  50. package/dist/push/silentSync.mjs.map +1 -0
  51. package/dist/vision/index.d.mts +7 -1
  52. package/dist/vision/index.d.ts +7 -1
  53. package/dist/vision/index.js +8 -0
  54. package/dist/vision/index.js.map +1 -1
  55. package/dist/vision/index.mjs +3 -1
  56. package/ios/AdaVisionModule.swift +44 -1
  57. package/package.json +28 -6
  58. package/src/aiLive/provider.ts +242 -0
  59. package/src/aiLive/streamProtocol.ts +90 -0
  60. package/src/bootstrap.ts +7 -1
  61. package/src/capabilities/choices.ts +65 -0
  62. package/src/capabilities/config.ts +5 -4
  63. package/src/capabilities/index.ts +2 -0
  64. package/src/capabilities/picturesToAi.ts +40 -0
  65. package/src/capabilities/store.ts +38 -37
  66. package/src/index.ts +3 -0
  67. package/src/push/index.ts +18 -0
  68. package/src/push/messaging.ts +49 -0
  69. package/src/push/registration.ts +31 -0
  70. package/src/push/silentSync.ts +83 -0
  71. package/src/push/usePushNotifications.ts +224 -0
  72. package/src/vision/index.ts +14 -0
  73. package/dist/chunk-42FP5DTO.mjs.map +0 -1
  74. package/dist/chunk-6JX222YX.mjs.map +0 -1
  75. package/dist/chunk-Z5AI2SXX.mjs.map +0 -1
  76. /package/dist/{chunk-Z3P7RUCC.mjs.map → chunk-OEX4OKYQ.mjs.map} +0 -0
@@ -1,41 +1,50 @@
1
+ import {
2
+ HIDDEN_FROM_UI,
3
+ SETUP_KEY,
4
+ STORAGE_KEY,
5
+ isEnabled,
6
+ loadChoices
7
+ } from "../chunk-GW7YGXOW.mjs";
1
8
  import {
2
9
  configureDeviceSync,
3
10
  getDeviceSyncConfig
4
- } from "../chunk-DE6Y4VRI.mjs";
11
+ } from "../chunk-GA7DS3PA.mjs";
5
12
  import {
6
- getOrCreateDeviceId
7
- } from "../chunk-IJPR5ITF.mjs";
13
+ DeviceBridge
14
+ } from "../chunk-BAZFMTCC.mjs";
8
15
  import {
9
- DeviceBridge,
10
16
  capabilities_exports
11
- } from "../chunk-Z5AI2SXX.mjs";
12
- import "../chunk-KOXF2FZM.mjs";
17
+ } from "../chunk-C62NQA4F.mjs";
13
18
  import "../chunk-XQSY6MHP.mjs";
19
+ import "../chunk-KOXF2FZM.mjs";
14
20
  import "../chunk-7FWYEHN5.mjs";
15
21
  import "../chunk-J6XRNX7P.mjs";
22
+ import {
23
+ getOrCreateDeviceId
24
+ } from "../chunk-IJPR5ITF.mjs";
16
25
  import "../chunk-WMJKH4XE.mjs";
17
26
 
18
27
  // src/capabilities/store.ts
19
28
  import { create } from "zustand";
20
29
  import AsyncStorage from "@react-native-async-storage/async-storage";
21
30
  import { getTenant, getUser, onAppForeground } from "@ateam-ai-mobile/core";
22
- var STORAGE_KEY = "ateam.capabilities";
23
- var SETUP_KEY = "ateam.capabilities.setup";
24
- var DEFAULT_ENABLED = {
25
- calendar: true,
26
- contacts: true,
27
- location: true,
28
- battery: true,
29
- connectivity: true,
30
- health: true,
31
- mood: true,
32
- // Opt-IN: the camera is more invasive than the sync collectors and should not
33
- // prompt every user for camera access on first launch. It lights up only when
34
- // the user turns it on (which then requests the OS permission), so a solution
35
- // that wants a camera preview asks the user to enable it.
36
- camera: false
31
+ import { setPicturesToAiConsentProvider } from "@ateam-ai-mobile/plugin-runtime";
32
+
33
+ // src/capabilities/picturesToAi.ts
34
+ function picturesToAiAllowed(s) {
35
+ if (s.picturesToAi !== true) return false;
36
+ const camera = s.capabilities.find((c) => c.id === "camera");
37
+ return !!camera && camera.enabled === true && camera.osPermission === "granted";
38
+ }
39
+ var PICTURES_TO_AI_ASK = {
40
+ title: "Send camera pictures to AI?",
41
+ message: 'Solutions that ask for it may send pictures from your camera to an AI service (OpenAI or Anthropic) through A-Team, to understand what the camera sees. Only while such a solution is open, and "Sending to AI" shows while it does. You can turn this off here at any time.',
42
+ allow: "Allow",
43
+ cancel: "Not now"
37
44
  };
38
- var HIDDEN_FROM_UI = /* @__PURE__ */ new Set(["notifications"]);
45
+
46
+ // src/capabilities/store.ts
47
+ var PICTURES_TO_AI_KEY = "ateam.capabilities.picturesToAi";
39
48
  var bridge = null;
40
49
  var bridgeOwner = null;
41
50
  var startQueue = Promise.resolve();
@@ -130,12 +139,15 @@ var useCapabilitiesStore = create((set, get) => {
130
139
  };
131
140
  return {
132
141
  capabilities: [],
142
+ picturesToAi: false,
133
143
  hasCompletedSetup: false,
134
144
  isLoading: true,
135
145
  bridgeRunning: false,
136
146
  initialize: async () => {
137
147
  try {
138
148
  builtInCapabilities = capabilities_exports.allBuiltIn().filter((c) => !HIDDEN_FROM_UI.has(c.id));
149
+ const { setupDone, prefs } = await loadChoices();
150
+ const picturesToAi = await AsyncStorage.getItem(PICTURES_TO_AI_KEY) === "true";
139
151
  const capStates = builtInCapabilities.map((cap) => ({
140
152
  id: cap.id,
141
153
  name: cap.name,
@@ -143,21 +155,16 @@ var useCapabilitiesStore = create((set, get) => {
143
155
  reason: cap.reason,
144
156
  icon: cap.icon || cap.id,
145
157
  requiresPermission: cap.requiresPermission,
146
- enabled: DEFAULT_ENABLED[cap.id] ?? true,
158
+ enabled: isEnabled(cap.id, prefs),
147
159
  osPermission: cap.permissionState
148
160
  }));
149
- const setupDone = await AsyncStorage.getItem(SETUP_KEY);
150
- const saved = await AsyncStorage.getItem(STORAGE_KEY);
151
- const prefs = saved ? JSON.parse(saved) : {};
152
161
  set({
153
- capabilities: capStates.map((cap) => ({
154
- ...cap,
155
- enabled: prefs[cap.id] ?? cap.enabled
156
- })),
157
- hasCompletedSetup: setupDone === "true",
162
+ capabilities: capStates,
163
+ picturesToAi,
164
+ hasCompletedSetup: setupDone,
158
165
  isLoading: false
159
166
  });
160
- console.log(`[Capabilities] Initialized ${capStates.length} capabilities from device-bridge (setup ${setupDone === "true" ? "done" : "pending"})`);
167
+ console.log(`[Capabilities] Initialized ${capStates.length} capabilities from device-bridge (setup ${setupDone ? "done" : "pending"})`);
161
168
  } catch (err) {
162
169
  console.error("[Capabilities] Initialize failed:", err);
163
170
  set({ isLoading: false });
@@ -174,6 +181,9 @@ var useCapabilitiesStore = create((set, get) => {
174
181
  prefs[cap.id] = cap.id === id ? enabled : cap.enabled;
175
182
  }
176
183
  await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(prefs));
184
+ if (id === "camera" && !enabled && get().picturesToAi) {
185
+ await get().setPicturesToAi(false);
186
+ }
177
187
  if (bridge && get().bridgeRunning) {
178
188
  if (enabled) {
179
189
  const builtIn = builtInCapabilities.find((c) => c.id === id);
@@ -193,6 +203,10 @@ var useCapabilitiesStore = create((set, get) => {
193
203
  }
194
204
  }
195
205
  },
206
+ setPicturesToAi: async (on) => {
207
+ set({ picturesToAi: on });
208
+ await AsyncStorage.setItem(PICTURES_TO_AI_KEY, on ? "true" : "false");
209
+ },
196
210
  setOsPermission: (id, permState) => {
197
211
  set((s) => ({
198
212
  capabilities: s.capabilities.map(
@@ -244,6 +258,7 @@ var useCapabilitiesStore = create((set, get) => {
244
258
  }
245
259
  };
246
260
  });
261
+ setPicturesToAiConsentProvider(() => picturesToAiAllowed(useCapabilitiesStore.getState()));
247
262
 
248
263
  // src/capabilities/CapabilitiesSetup.tsx
249
264
  import { useState } from "react";
@@ -602,7 +617,9 @@ var styles2 = StyleSheet2.create({
602
617
  export {
603
618
  CapabilitiesSetup,
604
619
  CapabilityCard,
620
+ PICTURES_TO_AI_ASK,
605
621
  configureDeviceSync,
622
+ picturesToAiAllowed,
606
623
  useCapabilitiesStore
607
624
  };
608
625
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/capabilities/store.ts","../../src/capabilities/CapabilitiesSetup.tsx","../../src/capabilities/CapabilityCard.tsx"],"sourcesContent":["import { create } from 'zustand';\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport { getTenant, getUser, onAppForeground } from '@ateam-ai-mobile/core';\nimport { DeviceBridge, capabilities as capFactories } from '../device-bridge';\nimport type { Capability, PermissionState } from '../device-bridge/types';\nimport { getOrCreateDeviceId } from '../device-bridge/deviceId';\nimport { getDeviceSyncConfig } from './config';\n\n/**\n * Device permissions — the one source of truth for what this device shares.\n *\n * Owns the DeviceBridge instance. Capability definitions come FROM the device\n * bridge (allBuiltIn()), not hardcoded anywhere.\n *\n * Two levels of permission:\n * 1. User opt-in (a toggle in the host's UI) — saved in AsyncStorage\n * 2. OS permission (system dialog) — requested only AFTER the user opts in\n *\n * Flow:\n * App start → initialize() loads built-in caps + saved choices\n * Setup screen → user toggles → completeSetup()\n * Host sees signed in + hasCompletedSetup → startBridge()\n * startBridge() → registers enabled caps, requests OS perms, starts sync\n * Settings toggle → toggleCapability() → starts/stops sync on the fly\n *\n * Moved from ateam-mobile src/stores/capabilitiesStore.ts (2026-10-29). The\n * tenant and user are now read from the SDK session at start (never a stored\n * copy), the bridge no longer starts under a made-up 'default' user, and a\n * start after a team switch replaces the bridge that still synced to the old\n * team (the old switch-time stop went away with the app's switchTenant, df7f6f72).\n */\n\nexport interface CapabilityState {\n id: string;\n name: string;\n description: string;\n reason: string;\n icon: string;\n requiresPermission: boolean;\n /** User's choice in the host's UI */\n enabled: boolean;\n /** OS-level permission status */\n osPermission: PermissionState;\n}\n\ninterface CapabilitiesState {\n capabilities: CapabilityState[];\n hasCompletedSetup: boolean;\n isLoading: boolean;\n bridgeRunning: boolean;\n\n /** Initialize — load built-in capabilities from device-bridge + saved user preferences */\n initialize: () => Promise<void>;\n /** Toggle a capability on/off, persist, and update bridge if running */\n toggleCapability: (id: string, enabled: boolean) => Promise<void>;\n /** Update OS permission state for a capability */\n setOsPermission: (id: string, state: PermissionState) => void;\n /** Mark initial setup as complete */\n completeSetup: () => Promise<void>;\n /**\n * Start the device bridge for the signed-in user and team (call after setup is\n * done, and again whenever the team or user changes). Safe to call often: calls\n * run one at a time, a bridge already running for this session is kept, and one\n * running for another team or user is replaced.\n */\n startBridge: () => Promise<void>;\n /** Stop the device bridge (call on sign-out; a team switch is a startBridge() call) */\n stopBridge: () => void;\n /** Force an immediate sync of all permitted capabilities. */\n syncNow: () => Promise<{ ok: boolean; error?: string }>;\n}\n\n// The keys the app used before the SDK owned them — existing installs keep their choices.\nconst STORAGE_KEY = 'ateam.capabilities';\nconst SETUP_KEY = 'ateam.capabilities.setup';\n\n// Default enabled state per capability (first-time only)\nconst DEFAULT_ENABLED: Record<string, boolean> = {\n calendar: true,\n contacts: true,\n location: true,\n battery: true,\n connectivity: true,\n health: true,\n mood: true,\n // Opt-IN: the camera is more invasive than the sync collectors and should not\n // prompt every user for camera access on first launch. It lights up only when\n // the user turns it on (which then requests the OS permission), so a solution\n // that wants a camera preview asks the user to enable it.\n camera: false,\n};\n\n// Capabilities hidden from the user-facing list. The host's push-notifications\n// toggle is the single user control; the notifications collector is internal\n// plumbing and shouldn't surface as a separate switch.\nconst HIDDEN_FROM_UI = new Set(['notifications']);\n\n// Module-level bridge singleton — NOT in Zustand (it's a mutable object with timers)\nlet bridge: DeviceBridge | null = null;\n\n// Who the running bridge syncs as, so a start after a team switch replaces it.\nlet bridgeOwner: { tenant: string; actorId: string } | null = null;\n\n// Starts run one at a time (the host's effect and a toggle can ask together).\nlet startQueue: Promise<void> = Promise.resolve();\n\n// Bumped by stopBridge: a start that was waiting when the bridge stopped (sign-out\n// mid-start) gives up instead of syncing as the user who just left.\nlet startGeneration = 0;\n\n// Cache the built-in Capability objects (with collect/permission functions)\nlet builtInCapabilities: Capability[] = [];\n\n// The foreground battery-refresh is registered with the SDK's foreground\n// coordinator (onAppForeground) instead of a private AppState listener — one\n// signal, deliberate order. iOS pauses JS timers in the background, so the\n// periodic battery poll goes stale; pushing on foreground guarantees a fresh\n// reading the moment the user opens the app. Kept at module scope so stopBridge\n// can unsubscribe it cleanly.\nlet foregroundUnsub: (() => void) | null = null;\n\nexport const useCapabilitiesStore = create<CapabilitiesState>((set, get) => {\n const runStart = async (): Promise<void> => {\n // Tenant and user come from the SDK session — the token's claims, the same\n // ones every request acts on. No session, no sync: device data is scoped per\n // user on the relay, so it never goes under a guessed or shared name.\n const tenant = getTenant();\n const actorId = getUser()?.actorId;\n\n if (bridge) {\n if (bridgeOwner?.tenant === tenant && bridgeOwner?.actorId === actorId) {\n console.log('[Capabilities] Bridge already running');\n return;\n }\n console.log('[Capabilities] Team or user changed — restarting bridge');\n get().stopBridge();\n }\n\n const { capabilities: caps } = get();\n const enabledCaps = caps.filter(c => c.enabled);\n\n if (enabledCaps.length === 0) {\n console.log('[Capabilities] No capabilities enabled — bridge not started');\n return;\n }\n\n const config = getDeviceSyncConfig();\n if (!config) {\n console.error('[Capabilities] Bridge not started: device sync is not configured — pass deviceSync to bootstrapExpoAdas (or call configureDeviceSync)');\n return;\n }\n\n if (!tenant || !actorId) {\n console.error(`[Capabilities] Bridge not started: no signed-in ${!tenant ? 'tenant' : 'user'}`);\n return;\n }\n\n const generation = startGeneration;\n\n // Get or generate a persistent unique device ID for this install\n const deviceId = await getOrCreateDeviceId(config.secureStorage);\n if (generation !== startGeneration) return;\n\n console.log(`[Capabilities] Starting bridge for tenant=${tenant} actor=${actorId} device=${deviceId} with ${enabledCaps.length} capabilities: ${enabledCaps.map(c => c.id).join(', ')}`);\n\n const started = new DeviceBridge({\n relayUrl: config.relayUrl(),\n deviceId,\n tenant,\n actorId,\n // RelayClient sends `Authorization: Bearer <apiKey>` so the relay's\n // auth gate accepts the call. Empty string = misconfig → relay returns\n // 401, surfaced as a sync error in the UI.\n apiKey: config.relayKey,\n onStatusChange: (status) => {\n // Sync OS permission states back to store\n for (const capStatus of status.capabilities) {\n const current = get().capabilities.find(c => c.id === capStatus.id);\n if (current && current.osPermission !== capStatus.permission) {\n get().setOsPermission(capStatus.id, capStatus.permission);\n }\n }\n },\n onError: (err) => {\n console.warn(`[device-bridge] ${err.domain}: ${err.message}`);\n },\n });\n bridge = started;\n bridgeOwner = { tenant, actorId };\n\n try {\n // Register ONLY user-enabled capabilities\n const enabledIds = new Set(enabledCaps.map(c => c.id));\n const capsToRegister = builtInCapabilities.filter(c => enabledIds.has(c.id));\n started.registerAll(capsToRegister);\n\n // Request OS permissions for capabilities that need them\n await started.requestAllPermissions();\n if (generation !== startGeneration) return; // stopBridge already stopped it\n\n // Update OS permission states in store\n const statuses = started.listCapabilities();\n set(state => ({\n bridgeRunning: true,\n capabilities: state.capabilities.map(c => {\n const status = statuses.find(s => s.id === c.id);\n return status ? { ...c, osPermission: status.permission } : c;\n }),\n }));\n\n await started.startSync();\n if (generation !== startGeneration) {\n // Stopped while starting: stop again, in case sync started after that stop.\n started.stopSync();\n return;\n }\n console.log('[Capabilities] Bridge started and syncing');\n } catch (err) {\n // A failed start must not stay recorded as \"already running\" — the next\n // start would keep answering that and never retry.\n if (bridge === started) get().stopBridge();\n throw err;\n }\n\n // Foreground refresh: force an immediate battery sync when the app returns\n // to the foreground, so the relay reflects the real level instead of the\n // stale value the suspended polling timer left behind. Registered with the\n // SDK coordinator (fires after the ACS reconnect) — only once.\n if (!foregroundUnsub) {\n foregroundUnsub = onAppForeground(() => {\n bridge?.syncCapabilityNow('battery').catch((err) => {\n console.warn('[Capabilities] foreground battery sync failed:', err);\n });\n });\n }\n\n // The periodic background-fetch task is owned by the bridge itself —\n // DeviceBridge.startSync() registers it (from its own config) and stopSync()\n // UNREGISTERS it, so the OS task can't keep firing with a stale user's\n // config after logout/tenant-switch.\n };\n\n return {\n capabilities: [],\n hasCompletedSetup: false,\n isLoading: true,\n bridgeRunning: false,\n\n initialize: async () => {\n try {\n // Get capability definitions FROM device-bridge — single source of truth.\n // Filter out capabilities whose user toggle is owned by another screen\n // (e.g. notifications → the host's notification settings).\n builtInCapabilities = capFactories.allBuiltIn().filter(c => !HIDDEN_FROM_UI.has(c.id));\n\n // Map to UI state (no functions, just data + enabled flag)\n const capStates: CapabilityState[] = builtInCapabilities.map(cap => ({\n id: cap.id,\n name: cap.name,\n description: cap.description,\n reason: cap.reason,\n icon: cap.icon || cap.id,\n requiresPermission: cap.requiresPermission,\n enabled: DEFAULT_ENABLED[cap.id] ?? true,\n osPermission: cap.permissionState,\n }));\n\n // Load saved user preferences (overrides defaults for returning users)\n const setupDone = await AsyncStorage.getItem(SETUP_KEY);\n const saved = await AsyncStorage.getItem(STORAGE_KEY);\n const prefs: Record<string, boolean> = saved ? JSON.parse(saved) : {};\n\n set({\n capabilities: capStates.map(cap => ({\n ...cap,\n enabled: prefs[cap.id] ?? cap.enabled,\n })),\n hasCompletedSetup: setupDone === 'true',\n isLoading: false,\n });\n\n console.log(`[Capabilities] Initialized ${capStates.length} capabilities from device-bridge (setup ${setupDone === 'true' ? 'done' : 'pending'})`);\n } catch (err) {\n console.error('[Capabilities] Initialize failed:', err);\n set({ isLoading: false });\n }\n },\n\n toggleCapability: async (id: string, enabled: boolean) => {\n // Update UI state\n set(state => ({\n capabilities: state.capabilities.map(cap =>\n cap.id === id ? { ...cap, enabled } : cap\n ),\n }));\n\n // Persist all preferences\n const prefs: Record<string, boolean> = {};\n for (const cap of get().capabilities) {\n prefs[cap.id] = cap.id === id ? enabled : cap.enabled;\n }\n await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(prefs));\n\n // If bridge is running, dynamically update\n if (bridge && get().bridgeRunning) {\n if (enabled) {\n // Register + request permission for newly enabled capability\n const builtIn = builtInCapabilities.find(c => c.id === id);\n if (builtIn) {\n bridge.register(builtIn);\n const granted = await bridge.requestPermission(id);\n set(state => ({\n capabilities: state.capabilities.map(c =>\n c.id === id ? { ...c, osPermission: granted ? 'granted' : 'denied' } : c\n ),\n }));\n }\n } else {\n // Stop and restart bridge without this capability\n console.log(`[Capabilities] ${id} disabled — restarting bridge`);\n get().stopBridge();\n await get().startBridge();\n }\n }\n },\n\n setOsPermission: (id: string, permState: PermissionState) => {\n set(s => ({\n capabilities: s.capabilities.map(cap =>\n cap.id === id ? { ...cap, osPermission: permState } : cap\n ),\n }));\n },\n\n completeSetup: async () => {\n await AsyncStorage.setItem(SETUP_KEY, 'true');\n set({ hasCompletedSetup: true });\n },\n\n startBridge: () => {\n const run = startQueue.then(runStart);\n startQueue = run.catch((err) => {\n console.error('[Capabilities] Bridge start failed:', err);\n });\n return run;\n },\n\n stopBridge: () => {\n startGeneration++;\n if (bridge) {\n bridge.stopSync();\n bridge = null;\n bridgeOwner = null;\n set({ bridgeRunning: false });\n console.log('[Capabilities] Bridge stopped');\n }\n if (foregroundUnsub) {\n foregroundUnsub();\n foregroundUnsub = null;\n }\n },\n\n syncNow: async () => {\n if (!bridge) return { ok: false, error: 'bridge not running' };\n try {\n await bridge.syncNow();\n // bridge.syncNow uses Promise.allSettled internally so it never throws.\n // Read per-capability status to find any actual failures we should\n // surface — particularly for health, which pushes large bundles and\n // can time out / partial-fail without bubbling.\n const statuses = bridge.listCapabilities();\n const failed = statuses.filter(s =>\n s.sync?.state === 'error' || s.sync?.state === 'syncing',\n );\n if (failed.length > 0) {\n const summary = failed\n .map(s => `${s.id}:${s.sync?.state}${s.sync?.error ? `(${s.sync.error})` : ''}`)\n .join(', ');\n return { ok: false, error: summary };\n }\n return { ok: true };\n } catch (e: any) {\n return { ok: false, error: e?.message || String(e) };\n }\n },\n };\n});\n","import { useState, type ReactNode } from 'react';\nimport {\n View,\n Text,\n ScrollView,\n Pressable,\n StyleSheet,\n ActivityIndicator,\n SafeAreaView,\n Platform,\n} from 'react-native';\nimport { ada, borderRadius, fontSize, spacing } from '@ateam-ai-mobile/core';\nimport { useCapabilitiesStore } from './store';\nimport CapabilityCard from './CapabilityCard';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\nexport interface CapabilitiesSetupProps {\n /** Called after the user continues or skips; the choices are already saved. */\n onComplete: () => void;\n /** Drawn above the title — e.g. the host's logo. */\n header?: ReactNode;\n title?: string;\n subtitle?: string;\n /** Shown while the saved choices load. Default: a spinner. */\n loading?: ReactNode;\n}\n\n/**\n * Drop-in first-run screen: the user picks what this device shares, then\n * continues (or skips, which turns everything off). Reads and writes\n * useCapabilitiesStore; the host starts the bridge once setup is complete.\n */\nexport default function CapabilitiesSetup({\n onComplete,\n header,\n title = 'What can the assistant use?',\n subtitle = \"Choose what it can see on this device. You're in charge — change it anytime in settings.\",\n loading,\n}: CapabilitiesSetupProps) {\n const {\n capabilities,\n toggleCapability,\n completeSetup,\n isLoading,\n } = useCapabilitiesStore();\n\n const [requesting, setRequesting] = useState(false);\n\n const enabledCount = capabilities.filter(c => c.enabled).length;\n const permissionCount = capabilities.filter(c => c.enabled && c.requiresPermission).length;\n\n const handleContinue = async () => {\n setRequesting(true);\n await completeSetup();\n setRequesting(false);\n onComplete();\n };\n\n const handleSkip = async () => {\n for (const cap of capabilities) {\n if (cap.enabled) {\n await toggleCapability(cap.id, false);\n }\n }\n await completeSetup();\n onComplete();\n };\n\n if (isLoading) {\n return (\n <SafeAreaView style={styles.center}>\n {loading ?? <ActivityIndicator size=\"large\" color={ada.inkMuted} />}\n </SafeAreaView>\n );\n }\n\n return (\n <SafeAreaView style={styles.container}>\n <ScrollView contentContainerStyle={styles.content}>\n <View style={styles.header}>\n {header ? <View style={styles.heroRow}>{header}</View> : null}\n <Text style={styles.title}>{title}</Text>\n <Text style={styles.subtitle}>{subtitle}</Text>\n </View>\n\n <View style={styles.section}>\n <Text style={styles.sectionTitle}>NEEDS YOUR PERMISSION</Text>\n {capabilities.filter(c => c.requiresPermission).map(cap => (\n <CapabilityCard\n key={cap.id}\n capability={cap}\n onToggle={toggleCapability}\n />\n ))}\n </View>\n\n <View style={styles.section}>\n <Text style={styles.sectionTitle}>ALWAYS AVAILABLE</Text>\n {capabilities.filter(c => !c.requiresPermission).map(cap => (\n <CapabilityCard\n key={cap.id}\n capability={cap}\n onToggle={toggleCapability}\n />\n ))}\n </View>\n\n <View style={styles.summaryBox}>\n <Text style={styles.summaryText}>\n {enabledCount} of {capabilities.length} on\n {permissionCount > 0 && ` · ${permissionCount} will ask for permission`}\n </Text>\n </View>\n </ScrollView>\n\n <View style={styles.footer}>\n <Pressable\n style={[styles.continueBtn, requesting && styles.continueBtnDisabled]}\n onPress={handleContinue}\n disabled={requesting}\n >\n {requesting ? (\n <ActivityIndicator size=\"small\" color={ada.paper} />\n ) : (\n <Text style={styles.continueBtnText}>\n {enabledCount > 0 ? 'Continue' : 'Continue without these'}\n </Text>\n )}\n </Pressable>\n\n <Pressable style={styles.skipBtn} onPress={handleSkip}>\n <Text style={styles.skipBtnText}>Skip for now</Text>\n </Pressable>\n </View>\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n center: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: ada.paper,\n },\n content: {\n paddingBottom: 20,\n },\n header: {\n paddingHorizontal: spacing.xl,\n paddingTop: 20,\n paddingBottom: spacing.lg,\n },\n heroRow: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 10,\n marginBottom: spacing.lg,\n },\n title: {\n color: ada.ink,\n fontSize: 28,\n fontWeight: '700',\n letterSpacing: -0.5,\n marginBottom: 8,\n fontFamily: fontFam,\n },\n subtitle: {\n color: ada.inkSoft,\n fontSize: fontSize.md,\n lineHeight: 22,\n letterSpacing: -0.1,\n fontFamily: fontFam,\n },\n section: {\n paddingHorizontal: spacing.lg,\n marginBottom: spacing.lg,\n },\n sectionTitle: {\n color: ada.inkMuted,\n fontSize: 11,\n fontWeight: '700',\n letterSpacing: 1.4,\n marginBottom: spacing.sm,\n paddingHorizontal: 4,\n fontFamily: fontFam,\n },\n summaryBox: {\n marginHorizontal: spacing.lg,\n backgroundColor: ada.orangeSoft,\n borderRadius: borderRadius.md,\n padding: spacing.md,\n alignItems: 'center',\n },\n summaryText: {\n color: ada.orangeDeep,\n fontSize: fontSize.sm,\n fontWeight: '600',\n fontFamily: fontFam,\n letterSpacing: -0.1,\n },\n footer: {\n paddingHorizontal: spacing.lg,\n paddingVertical: spacing.lg,\n borderTopWidth: 1,\n borderTopColor: ada.border,\n gap: spacing.sm,\n },\n continueBtn: {\n backgroundColor: ada.ink,\n borderRadius: 999,\n paddingVertical: 16,\n alignItems: 'center',\n },\n continueBtnDisabled: {\n opacity: 0.6,\n },\n continueBtnText: {\n color: ada.paper,\n fontSize: fontSize.lg,\n fontWeight: '600',\n fontFamily: fontFam,\n letterSpacing: -0.2,\n },\n skipBtn: {\n paddingVertical: 12,\n alignItems: 'center',\n },\n skipBtnText: {\n color: ada.inkMuted,\n fontSize: fontSize.md,\n fontFamily: fontFam,\n },\n});\n","import { View, Text, Switch, Pressable, StyleSheet, Linking, Platform } from 'react-native';\nimport { ada, borderRadius, fontSize, spacing } from '@ateam-ai-mobile/core';\nimport type { CapabilityState } from './store';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\nconst ICONS: Record<string, string> = {\n calendar: '📅',\n contacts: '👥',\n location: '📍',\n battery: '🔋',\n wifi: '📶',\n notifications: '🔔',\n};\n\nexport interface CapabilityCardProps {\n capability: CapabilityState;\n onToggle: (id: string, enabled: boolean) => void;\n}\n\n/** One capability with its on/off switch and OS-permission badge. */\nexport default function CapabilityCard({ capability, onToggle }: CapabilityCardProps) {\n const { id, name, description, reason, icon, enabled, osPermission, requiresPermission } = capability;\n\n const isDenied = osPermission === 'denied';\n const isGranted = osPermission === 'granted' || osPermission === 'not_needed';\n\n const handleToggle = (value: boolean) => {\n if (isDenied && value) {\n Linking.openSettings();\n return;\n }\n onToggle(id, value);\n };\n\n return (\n <View style={[styles.card, enabled && styles.cardEnabled]}>\n <View style={styles.row}>\n <View style={[styles.iconBox, enabled && styles.iconBoxEnabled]}>\n <Text style={styles.iconText}>{ICONS[icon] || '⚙️'}</Text>\n </View>\n\n <View style={styles.info}>\n <Text style={styles.name}>{name}</Text>\n <Text style={styles.description}>{description}</Text>\n </View>\n\n <Switch\n value={enabled}\n onValueChange={handleToggle}\n trackColor={{ false: ada.border, true: ada.orange }}\n thumbColor=\"#fff\"\n ios_backgroundColor={ada.border}\n />\n </View>\n\n {enabled && (\n <Text style={styles.reason}>{reason}</Text>\n )}\n\n {enabled && requiresPermission && (\n <View style={styles.statusRow}>\n {isDenied ? (\n <Pressable onPress={() => Linking.openSettings()}>\n <View style={styles.deniedBadge}>\n <Text style={styles.deniedText}>Blocked — tap to open Settings</Text>\n </View>\n </Pressable>\n ) : isGranted ? (\n <View style={styles.grantedBadge}>\n <Text style={styles.grantedText}>Active</Text>\n </View>\n ) : (\n <View style={styles.pendingBadge}>\n <Text style={styles.pendingText}>Will ask permission</Text>\n </View>\n )}\n </View>\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n card: {\n backgroundColor: ada.paperSoft,\n borderRadius: borderRadius.lg,\n borderWidth: 1,\n borderColor: ada.border,\n padding: spacing.lg,\n marginBottom: spacing.md,\n },\n cardEnabled: {\n borderColor: ada.orange,\n borderWidth: 1.5,\n },\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: spacing.md,\n },\n iconBox: {\n width: 44,\n height: 44,\n borderRadius: 12,\n backgroundColor: ada.paperDeep,\n justifyContent: 'center',\n alignItems: 'center',\n },\n iconBoxEnabled: {\n backgroundColor: ada.orangeSoft,\n },\n iconText: {\n fontSize: 20,\n },\n info: {\n flex: 1,\n },\n name: {\n color: ada.ink,\n fontSize: fontSize.lg,\n fontWeight: '600',\n fontFamily: fontFam,\n letterSpacing: -0.2,\n },\n description: {\n color: ada.inkSoft,\n fontSize: fontSize.sm,\n marginTop: 2,\n lineHeight: 18,\n fontFamily: fontFam,\n letterSpacing: -0.05,\n },\n reason: {\n color: ada.inkMuted,\n fontSize: fontSize.xs,\n marginTop: spacing.sm,\n marginLeft: 44 + spacing.md,\n lineHeight: 16,\n fontFamily: fontFam,\n },\n statusRow: {\n marginTop: spacing.sm,\n marginLeft: 44 + spacing.md,\n },\n grantedBadge: {\n backgroundColor: 'rgba(90, 138, 92, 0.14)',\n borderRadius: borderRadius.sm,\n paddingHorizontal: spacing.sm,\n paddingVertical: 3,\n alignSelf: 'flex-start',\n },\n grantedText: {\n color: '#5A8A5C',\n fontSize: fontSize.xs,\n fontWeight: '700',\n fontFamily: fontFam,\n letterSpacing: 0.2,\n },\n pendingBadge: {\n backgroundColor: ada.orangeSoft,\n borderRadius: borderRadius.sm,\n paddingHorizontal: spacing.sm,\n paddingVertical: 3,\n alignSelf: 'flex-start',\n },\n pendingText: {\n color: ada.orangeDeep,\n fontSize: fontSize.xs,\n fontWeight: '700',\n fontFamily: fontFam,\n letterSpacing: 0.2,\n },\n deniedBadge: {\n backgroundColor: 'rgba(193, 85, 69, 0.14)',\n borderRadius: borderRadius.sm,\n paddingHorizontal: spacing.sm,\n paddingVertical: 3,\n alignSelf: 'flex-start',\n },\n deniedText: {\n color: '#C15545',\n fontSize: fontSize.xs,\n fontWeight: '700',\n fontFamily: fontFam,\n letterSpacing: 0.2,\n },\n});\n"],"mappings":"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","names":["View","Text","Pressable","StyleSheet","Platform","ada","borderRadius","fontSize","spacing","jsx","jsxs","fontFam","Platform","styles","ada","View","Text","Pressable","StyleSheet","spacing","fontSize","borderRadius"]}
1
+ {"version":3,"sources":["../../src/capabilities/store.ts","../../src/capabilities/picturesToAi.ts","../../src/capabilities/CapabilitiesSetup.tsx","../../src/capabilities/CapabilityCard.tsx"],"sourcesContent":["import { create } from 'zustand';\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport { getTenant, getUser, onAppForeground } from '@ateam-ai-mobile/core';\nimport { setPicturesToAiConsentProvider } from '@ateam-ai-mobile/plugin-runtime';\nimport { DeviceBridge, capabilities as capFactories } from '../device-bridge';\nimport type { Capability, PermissionState } from '../device-bridge/types';\nimport { getOrCreateDeviceId } from '../device-bridge/deviceId';\nimport { getDeviceSyncConfig } from './config';\nimport { STORAGE_KEY, SETUP_KEY, HIDDEN_FROM_UI, loadChoices, isEnabled } from './choices';\nimport { picturesToAiAllowed } from './picturesToAi';\n\n// The key the app used for this switch before the SDK owned it (branch pictures-to-ai-switch).\nconst PICTURES_TO_AI_KEY = 'ateam.capabilities.picturesToAi';\n\n/**\n * Device permissions — the one source of truth for what this device shares.\n *\n * Owns the DeviceBridge instance. Capability definitions come FROM the device\n * bridge (allBuiltIn()), not hardcoded anywhere.\n *\n * Two levels of permission:\n * 1. User opt-in (a toggle in the host's UI) — saved in AsyncStorage\n * 2. OS permission (system dialog) — requested only AFTER the user opts in\n *\n * Flow:\n * App start → initialize() loads built-in caps + saved choices\n * Setup screen → user toggles → completeSetup()\n * Host sees signed in + hasCompletedSetup → startBridge()\n * startBridge() → registers enabled caps, requests OS perms, starts sync\n * Settings toggle → toggleCapability() → starts/stops sync on the fly\n *\n * Moved from ateam-mobile src/stores/capabilitiesStore.ts (2026-10-29). The\n * tenant and user are now read from the SDK session at start (never a stored\n * copy), the bridge no longer starts under a made-up 'default' user, and a\n * start after a team switch replaces the bridge that still synced to the old\n * team (the old switch-time stop went away with the app's switchTenant, df7f6f72).\n */\n\nexport interface CapabilityState {\n id: string;\n name: string;\n description: string;\n reason: string;\n icon: string;\n requiresPermission: boolean;\n /** User's choice in the host's UI */\n enabled: boolean;\n /** OS-level permission status */\n osPermission: PermissionState;\n}\n\ninterface CapabilitiesState {\n capabilities: CapabilityState[];\n /** The \"Camera pictures to AI\" switch under Camera: the person's half of the\n * consent props.aiLive needs. Off until they turn it on (default no). */\n picturesToAi: boolean;\n hasCompletedSetup: boolean;\n isLoading: boolean;\n bridgeRunning: boolean;\n\n /** Initialize — load built-in capabilities from device-bridge + saved user preferences */\n initialize: () => Promise<void>;\n /** Toggle a capability on/off, persist, and update bridge if running */\n toggleCapability: (id: string, enabled: boolean) => Promise<void>;\n /** Set and persist \"Camera pictures to AI\". The host asks first (PICTURES_TO_AI_ASK). */\n setPicturesToAi: (on: boolean) => Promise<void>;\n /** Update OS permission state for a capability */\n setOsPermission: (id: string, state: PermissionState) => void;\n /** Mark initial setup as complete */\n completeSetup: () => Promise<void>;\n /**\n * Start the device bridge for the signed-in user and team (call after setup is\n * done, and again whenever the team or user changes). Safe to call often: calls\n * run one at a time, a bridge already running for this session is kept, and one\n * running for another team or user is replaced.\n */\n startBridge: () => Promise<void>;\n /** Stop the device bridge (call on sign-out; a team switch is a startBridge() call) */\n stopBridge: () => void;\n /** Force an immediate sync of all permitted capabilities. */\n syncNow: () => Promise<{ ok: boolean; error?: string }>;\n}\n\n// Module-level bridge singleton — NOT in Zustand (it's a mutable object with timers)\nlet bridge: DeviceBridge | null = null;\n\n// Who the running bridge syncs as, so a start after a team switch replaces it.\nlet bridgeOwner: { tenant: string; actorId: string } | null = null;\n\n// Starts run one at a time (the host's effect and a toggle can ask together).\nlet startQueue: Promise<void> = Promise.resolve();\n\n// Bumped by stopBridge: a start that was waiting when the bridge stopped (sign-out\n// mid-start) gives up instead of syncing as the user who just left.\nlet startGeneration = 0;\n\n// Cache the built-in Capability objects (with collect/permission functions)\nlet builtInCapabilities: Capability[] = [];\n\n// The foreground battery-refresh is registered with the SDK's foreground\n// coordinator (onAppForeground) instead of a private AppState listener — one\n// signal, deliberate order. iOS pauses JS timers in the background, so the\n// periodic battery poll goes stale; pushing on foreground guarantees a fresh\n// reading the moment the user opens the app. Kept at module scope so stopBridge\n// can unsubscribe it cleanly.\nlet foregroundUnsub: (() => void) | null = null;\n\nexport const useCapabilitiesStore = create<CapabilitiesState>((set, get) => {\n const runStart = async (): Promise<void> => {\n // Tenant and user come from the SDK session — the token's claims, the same\n // ones every request acts on. No session, no sync: device data is scoped per\n // user on the relay, so it never goes under a guessed or shared name.\n const tenant = getTenant();\n const actorId = getUser()?.actorId;\n\n if (bridge) {\n if (bridgeOwner?.tenant === tenant && bridgeOwner?.actorId === actorId) {\n console.log('[Capabilities] Bridge already running');\n return;\n }\n console.log('[Capabilities] Team or user changed — restarting bridge');\n get().stopBridge();\n }\n\n const { capabilities: caps } = get();\n const enabledCaps = caps.filter(c => c.enabled);\n\n if (enabledCaps.length === 0) {\n console.log('[Capabilities] No capabilities enabled — bridge not started');\n return;\n }\n\n const config = getDeviceSyncConfig();\n if (!config) {\n console.error('[Capabilities] Bridge not started: device sync is not configured — pass deviceSync to bootstrapExpoAdas (or call configureDeviceSync)');\n return;\n }\n\n if (!tenant || !actorId) {\n console.error(`[Capabilities] Bridge not started: no signed-in ${!tenant ? 'tenant' : 'user'}`);\n return;\n }\n\n const generation = startGeneration;\n\n // Get or generate a persistent unique device ID for this install\n const deviceId = await getOrCreateDeviceId(config.secureStorage);\n if (generation !== startGeneration) return;\n\n console.log(`[Capabilities] Starting bridge for tenant=${tenant} actor=${actorId} device=${deviceId} with ${enabledCaps.length} capabilities: ${enabledCaps.map(c => c.id).join(', ')}`);\n\n const started = new DeviceBridge({\n relayUrl: config.relayUrl(),\n deviceId,\n tenant,\n actorId,\n // RelayClient sends `Authorization: Bearer <apiKey>` so the relay's\n // auth gate accepts the call. Empty string = misconfig → relay returns\n // 401, surfaced as a sync error in the UI.\n apiKey: config.relayKey,\n onStatusChange: (status) => {\n // Sync OS permission states back to store\n for (const capStatus of status.capabilities) {\n const current = get().capabilities.find(c => c.id === capStatus.id);\n if (current && current.osPermission !== capStatus.permission) {\n get().setOsPermission(capStatus.id, capStatus.permission);\n }\n }\n },\n onError: (err) => {\n console.warn(`[device-bridge] ${err.domain}: ${err.message}`);\n },\n });\n bridge = started;\n bridgeOwner = { tenant, actorId };\n\n try {\n // Register ONLY user-enabled capabilities\n const enabledIds = new Set(enabledCaps.map(c => c.id));\n const capsToRegister = builtInCapabilities.filter(c => enabledIds.has(c.id));\n started.registerAll(capsToRegister);\n\n // Request OS permissions for capabilities that need them\n await started.requestAllPermissions();\n if (generation !== startGeneration) return; // stopBridge already stopped it\n\n // Update OS permission states in store\n const statuses = started.listCapabilities();\n set(state => ({\n bridgeRunning: true,\n capabilities: state.capabilities.map(c => {\n const status = statuses.find(s => s.id === c.id);\n return status ? { ...c, osPermission: status.permission } : c;\n }),\n }));\n\n await started.startSync();\n if (generation !== startGeneration) {\n // Stopped while starting: stop again, in case sync started after that stop.\n started.stopSync();\n return;\n }\n console.log('[Capabilities] Bridge started and syncing');\n } catch (err) {\n // A failed start must not stay recorded as \"already running\" — the next\n // start would keep answering that and never retry.\n if (bridge === started) get().stopBridge();\n throw err;\n }\n\n // Foreground refresh: force an immediate battery sync when the app returns\n // to the foreground, so the relay reflects the real level instead of the\n // stale value the suspended polling timer left behind. Registered with the\n // SDK coordinator (fires after the ACS reconnect) — only once.\n if (!foregroundUnsub) {\n foregroundUnsub = onAppForeground(() => {\n bridge?.syncCapabilityNow('battery').catch((err) => {\n console.warn('[Capabilities] foreground battery sync failed:', err);\n });\n });\n }\n\n // The periodic background-fetch task is owned by the bridge itself —\n // DeviceBridge.startSync() registers it (from its own config) and stopSync()\n // UNREGISTERS it, so the OS task can't keep firing with a stale user's\n // config after logout/tenant-switch.\n };\n\n return {\n capabilities: [],\n picturesToAi: false,\n hasCompletedSetup: false,\n isLoading: true,\n bridgeRunning: false,\n\n initialize: async () => {\n try {\n // Get capability definitions FROM device-bridge — single source of truth.\n // Filter out capabilities whose user toggle is owned by another screen\n // (e.g. notifications → the host's notification settings).\n builtInCapabilities = capFactories.allBuiltIn().filter(c => !HIDDEN_FROM_UI.has(c.id));\n\n // Saved user choices (override the defaults for returning users)\n const { setupDone, prefs } = await loadChoices();\n const picturesToAi = (await AsyncStorage.getItem(PICTURES_TO_AI_KEY)) === 'true';\n\n // Map to UI state (no functions, just data + enabled flag)\n const capStates: CapabilityState[] = builtInCapabilities.map(cap => ({\n id: cap.id,\n name: cap.name,\n description: cap.description,\n reason: cap.reason,\n icon: cap.icon || cap.id,\n requiresPermission: cap.requiresPermission,\n enabled: isEnabled(cap.id, prefs),\n osPermission: cap.permissionState,\n }));\n\n set({\n capabilities: capStates,\n picturesToAi,\n hasCompletedSetup: setupDone,\n isLoading: false,\n });\n\n console.log(`[Capabilities] Initialized ${capStates.length} capabilities from device-bridge (setup ${setupDone ? 'done' : 'pending'})`);\n } catch (err) {\n console.error('[Capabilities] Initialize failed:', err);\n set({ isLoading: false });\n }\n },\n\n toggleCapability: async (id: string, enabled: boolean) => {\n // Update UI state\n set(state => ({\n capabilities: state.capabilities.map(cap =>\n cap.id === id ? { ...cap, enabled } : cap\n ),\n }));\n\n // Persist all preferences\n const prefs: Record<string, boolean> = {};\n for (const cap of get().capabilities) {\n prefs[cap.id] = cap.id === id ? enabled : cap.enabled;\n }\n await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(prefs));\n\n // Turning the camera off also clears \"Camera pictures to AI\", so turning the\n // camera back on later never silently re-opens that door: the person is asked\n // again. (While the camera is off the consent already reads as no.)\n if (id === 'camera' && !enabled && get().picturesToAi) {\n await get().setPicturesToAi(false);\n }\n\n // If bridge is running, dynamically update\n if (bridge && get().bridgeRunning) {\n if (enabled) {\n // Register + request permission for newly enabled capability\n const builtIn = builtInCapabilities.find(c => c.id === id);\n if (builtIn) {\n bridge.register(builtIn);\n const granted = await bridge.requestPermission(id);\n set(state => ({\n capabilities: state.capabilities.map(c =>\n c.id === id ? { ...c, osPermission: granted ? 'granted' : 'denied' } : c\n ),\n }));\n }\n } else {\n // Stop and restart bridge without this capability\n console.log(`[Capabilities] ${id} disabled — restarting bridge`);\n get().stopBridge();\n await get().startBridge();\n }\n }\n },\n\n setPicturesToAi: async (on: boolean) => {\n set({ picturesToAi: on });\n await AsyncStorage.setItem(PICTURES_TO_AI_KEY, on ? 'true' : 'false');\n },\n\n setOsPermission: (id: string, permState: PermissionState) => {\n set(s => ({\n capabilities: s.capabilities.map(cap =>\n cap.id === id ? { ...cap, osPermission: permState } : cap\n ),\n }));\n },\n\n completeSetup: async () => {\n await AsyncStorage.setItem(SETUP_KEY, 'true');\n set({ hasCompletedSetup: true });\n },\n\n startBridge: () => {\n const run = startQueue.then(runStart);\n startQueue = run.catch((err) => {\n console.error('[Capabilities] Bridge start failed:', err);\n });\n return run;\n },\n\n stopBridge: () => {\n startGeneration++;\n if (bridge) {\n bridge.stopSync();\n bridge = null;\n bridgeOwner = null;\n set({ bridgeRunning: false });\n console.log('[Capabilities] Bridge stopped');\n }\n if (foregroundUnsub) {\n foregroundUnsub();\n foregroundUnsub = null;\n }\n },\n\n syncNow: async () => {\n if (!bridge) return { ok: false, error: 'bridge not running' };\n try {\n await bridge.syncNow();\n // bridge.syncNow uses Promise.allSettled internally so it never throws.\n // Read per-capability status to find any actual failures we should\n // surface — particularly for health, which pushes large bundles and\n // can time out / partial-fail without bubbling.\n const statuses = bridge.listCapabilities();\n const failed = statuses.filter(s =>\n s.sync?.state === 'error' || s.sync?.state === 'syncing',\n );\n if (failed.length > 0) {\n const summary = failed\n .map(s => `${s.id}:${s.sync?.state}${s.sync?.error ? `(${s.sync.error})` : ''}`)\n .join(', ');\n return { ok: false, error: summary };\n }\n return { ok: true };\n } catch (e: any) {\n return { ok: false, error: e?.message || String(e) };\n }\n },\n };\n});\n\n// The person's half of \"camera pictures to AI\", for plugin-runtime's mayPicturesLeavePhone():\n// read from this store at CALL time (derive, never store). A host that never loads this store\n// has no consent provider, and the answer is no.\nsetPicturesToAiConsentProvider(() => picturesToAiAllowed(useCapabilitiesStore.getState()));\n","/**\n * \"Camera pictures to AI\" — the phone owner's half of a two-sided consent\n * (owner decision 2026-10-25, amending \"frames never leave the phone\").\n *\n * A camera picture may go to an AI service off the phone only when the\n * solution's developer declared `picturesToAi` in its manifest AND the person on\n * this phone allowed it here. plugin-runtime's mayPicturesLeavePhone() checks\n * both; this half is installed as its consent provider by the capabilities store.\n *\n * Moved from ateam-mobile (branch pictures-to-ai-switch, 9541f22) into the SDK\n * with the store it belongs to. Pure, so tests run it under plain node.\n */\n\nexport interface PicturesToAiInputs {\n /** The switch under Camera in the host's \"What Ada can access\". */\n picturesToAi: boolean;\n capabilities: ReadonlyArray<{ id: string; enabled: boolean; osPermission: string }>;\n}\n\n/** Derived at read time, never stored: the switch is on AND the camera itself is\n * on and granted by the OS. Anything else answers no. */\nexport function picturesToAiAllowed(s: PicturesToAiInputs): boolean {\n if (s.picturesToAi !== true) return false;\n const camera = s.capabilities.find((c) => c.id === 'camera');\n return !!camera && camera.enabled === true && camera.osPermission === 'granted';\n}\n\n/** What the person is told before allowing it. Apple guideline 5.1.2(i): say\n * where personal data goes before sharing it with an outside AI, and get\n * explicit permission first. */\nexport const PICTURES_TO_AI_ASK = {\n title: 'Send camera pictures to AI?',\n message:\n 'Solutions that ask for it may send pictures from your camera to an AI service ' +\n '(OpenAI or Anthropic) through A-Team, to understand what the camera sees. ' +\n 'Only while such a solution is open, and \"Sending to AI\" shows while it does. ' +\n 'You can turn this off here at any time.',\n allow: 'Allow',\n cancel: 'Not now',\n} as const;\n","import { useState, type ReactNode } from 'react';\nimport {\n View,\n Text,\n ScrollView,\n Pressable,\n StyleSheet,\n ActivityIndicator,\n SafeAreaView,\n Platform,\n} from 'react-native';\nimport { ada, borderRadius, fontSize, spacing } from '@ateam-ai-mobile/core';\nimport { useCapabilitiesStore } from './store';\nimport CapabilityCard from './CapabilityCard';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\nexport interface CapabilitiesSetupProps {\n /** Called after the user continues or skips; the choices are already saved. */\n onComplete: () => void;\n /** Drawn above the title — e.g. the host's logo. */\n header?: ReactNode;\n title?: string;\n subtitle?: string;\n /** Shown while the saved choices load. Default: a spinner. */\n loading?: ReactNode;\n}\n\n/**\n * Drop-in first-run screen: the user picks what this device shares, then\n * continues (or skips, which turns everything off). Reads and writes\n * useCapabilitiesStore; the host starts the bridge once setup is complete.\n */\nexport default function CapabilitiesSetup({\n onComplete,\n header,\n title = 'What can the assistant use?',\n subtitle = \"Choose what it can see on this device. You're in charge — change it anytime in settings.\",\n loading,\n}: CapabilitiesSetupProps) {\n const {\n capabilities,\n toggleCapability,\n completeSetup,\n isLoading,\n } = useCapabilitiesStore();\n\n const [requesting, setRequesting] = useState(false);\n\n const enabledCount = capabilities.filter(c => c.enabled).length;\n const permissionCount = capabilities.filter(c => c.enabled && c.requiresPermission).length;\n\n const handleContinue = async () => {\n setRequesting(true);\n await completeSetup();\n setRequesting(false);\n onComplete();\n };\n\n const handleSkip = async () => {\n for (const cap of capabilities) {\n if (cap.enabled) {\n await toggleCapability(cap.id, false);\n }\n }\n await completeSetup();\n onComplete();\n };\n\n if (isLoading) {\n return (\n <SafeAreaView style={styles.center}>\n {loading ?? <ActivityIndicator size=\"large\" color={ada.inkMuted} />}\n </SafeAreaView>\n );\n }\n\n return (\n <SafeAreaView style={styles.container}>\n <ScrollView contentContainerStyle={styles.content}>\n <View style={styles.header}>\n {header ? <View style={styles.heroRow}>{header}</View> : null}\n <Text style={styles.title}>{title}</Text>\n <Text style={styles.subtitle}>{subtitle}</Text>\n </View>\n\n <View style={styles.section}>\n <Text style={styles.sectionTitle}>NEEDS YOUR PERMISSION</Text>\n {capabilities.filter(c => c.requiresPermission).map(cap => (\n <CapabilityCard\n key={cap.id}\n capability={cap}\n onToggle={toggleCapability}\n />\n ))}\n </View>\n\n <View style={styles.section}>\n <Text style={styles.sectionTitle}>ALWAYS AVAILABLE</Text>\n {capabilities.filter(c => !c.requiresPermission).map(cap => (\n <CapabilityCard\n key={cap.id}\n capability={cap}\n onToggle={toggleCapability}\n />\n ))}\n </View>\n\n <View style={styles.summaryBox}>\n <Text style={styles.summaryText}>\n {enabledCount} of {capabilities.length} on\n {permissionCount > 0 && ` · ${permissionCount} will ask for permission`}\n </Text>\n </View>\n </ScrollView>\n\n <View style={styles.footer}>\n <Pressable\n style={[styles.continueBtn, requesting && styles.continueBtnDisabled]}\n onPress={handleContinue}\n disabled={requesting}\n >\n {requesting ? (\n <ActivityIndicator size=\"small\" color={ada.paper} />\n ) : (\n <Text style={styles.continueBtnText}>\n {enabledCount > 0 ? 'Continue' : 'Continue without these'}\n </Text>\n )}\n </Pressable>\n\n <Pressable style={styles.skipBtn} onPress={handleSkip}>\n <Text style={styles.skipBtnText}>Skip for now</Text>\n </Pressable>\n </View>\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n center: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: ada.paper,\n },\n content: {\n paddingBottom: 20,\n },\n header: {\n paddingHorizontal: spacing.xl,\n paddingTop: 20,\n paddingBottom: spacing.lg,\n },\n heroRow: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 10,\n marginBottom: spacing.lg,\n },\n title: {\n color: ada.ink,\n fontSize: 28,\n fontWeight: '700',\n letterSpacing: -0.5,\n marginBottom: 8,\n fontFamily: fontFam,\n },\n subtitle: {\n color: ada.inkSoft,\n fontSize: fontSize.md,\n lineHeight: 22,\n letterSpacing: -0.1,\n fontFamily: fontFam,\n },\n section: {\n paddingHorizontal: spacing.lg,\n marginBottom: spacing.lg,\n },\n sectionTitle: {\n color: ada.inkMuted,\n fontSize: 11,\n fontWeight: '700',\n letterSpacing: 1.4,\n marginBottom: spacing.sm,\n paddingHorizontal: 4,\n fontFamily: fontFam,\n },\n summaryBox: {\n marginHorizontal: spacing.lg,\n backgroundColor: ada.orangeSoft,\n borderRadius: borderRadius.md,\n padding: spacing.md,\n alignItems: 'center',\n },\n summaryText: {\n color: ada.orangeDeep,\n fontSize: fontSize.sm,\n fontWeight: '600',\n fontFamily: fontFam,\n letterSpacing: -0.1,\n },\n footer: {\n paddingHorizontal: spacing.lg,\n paddingVertical: spacing.lg,\n borderTopWidth: 1,\n borderTopColor: ada.border,\n gap: spacing.sm,\n },\n continueBtn: {\n backgroundColor: ada.ink,\n borderRadius: 999,\n paddingVertical: 16,\n alignItems: 'center',\n },\n continueBtnDisabled: {\n opacity: 0.6,\n },\n continueBtnText: {\n color: ada.paper,\n fontSize: fontSize.lg,\n fontWeight: '600',\n fontFamily: fontFam,\n letterSpacing: -0.2,\n },\n skipBtn: {\n paddingVertical: 12,\n alignItems: 'center',\n },\n skipBtnText: {\n color: ada.inkMuted,\n fontSize: fontSize.md,\n fontFamily: fontFam,\n },\n});\n","import { View, Text, Switch, Pressable, StyleSheet, Linking, Platform } from 'react-native';\nimport { ada, borderRadius, fontSize, spacing } from '@ateam-ai-mobile/core';\nimport type { CapabilityState } from './store';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\nconst ICONS: Record<string, string> = {\n calendar: '📅',\n contacts: '👥',\n location: '📍',\n battery: '🔋',\n wifi: '📶',\n notifications: '🔔',\n};\n\nexport interface CapabilityCardProps {\n capability: CapabilityState;\n onToggle: (id: string, enabled: boolean) => void;\n}\n\n/** One capability with its on/off switch and OS-permission badge. */\nexport default function CapabilityCard({ capability, onToggle }: CapabilityCardProps) {\n const { id, name, description, reason, icon, enabled, osPermission, requiresPermission } = capability;\n\n const isDenied = osPermission === 'denied';\n const isGranted = osPermission === 'granted' || osPermission === 'not_needed';\n\n const handleToggle = (value: boolean) => {\n if (isDenied && value) {\n Linking.openSettings();\n return;\n }\n onToggle(id, value);\n };\n\n return (\n <View style={[styles.card, enabled && styles.cardEnabled]}>\n <View style={styles.row}>\n <View style={[styles.iconBox, enabled && styles.iconBoxEnabled]}>\n <Text style={styles.iconText}>{ICONS[icon] || '⚙️'}</Text>\n </View>\n\n <View style={styles.info}>\n <Text style={styles.name}>{name}</Text>\n <Text style={styles.description}>{description}</Text>\n </View>\n\n <Switch\n value={enabled}\n onValueChange={handleToggle}\n trackColor={{ false: ada.border, true: ada.orange }}\n thumbColor=\"#fff\"\n ios_backgroundColor={ada.border}\n />\n </View>\n\n {enabled && (\n <Text style={styles.reason}>{reason}</Text>\n )}\n\n {enabled && requiresPermission && (\n <View style={styles.statusRow}>\n {isDenied ? (\n <Pressable onPress={() => Linking.openSettings()}>\n <View style={styles.deniedBadge}>\n <Text style={styles.deniedText}>Blocked — tap to open Settings</Text>\n </View>\n </Pressable>\n ) : isGranted ? (\n <View style={styles.grantedBadge}>\n <Text style={styles.grantedText}>Active</Text>\n </View>\n ) : (\n <View style={styles.pendingBadge}>\n <Text style={styles.pendingText}>Will ask permission</Text>\n </View>\n )}\n </View>\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n card: {\n backgroundColor: ada.paperSoft,\n borderRadius: borderRadius.lg,\n borderWidth: 1,\n borderColor: ada.border,\n padding: spacing.lg,\n marginBottom: spacing.md,\n },\n cardEnabled: {\n borderColor: ada.orange,\n borderWidth: 1.5,\n },\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: spacing.md,\n },\n iconBox: {\n width: 44,\n height: 44,\n borderRadius: 12,\n backgroundColor: ada.paperDeep,\n justifyContent: 'center',\n alignItems: 'center',\n },\n iconBoxEnabled: {\n backgroundColor: ada.orangeSoft,\n },\n iconText: {\n fontSize: 20,\n },\n info: {\n flex: 1,\n },\n name: {\n color: ada.ink,\n fontSize: fontSize.lg,\n fontWeight: '600',\n fontFamily: fontFam,\n letterSpacing: -0.2,\n },\n description: {\n color: ada.inkSoft,\n fontSize: fontSize.sm,\n marginTop: 2,\n lineHeight: 18,\n fontFamily: fontFam,\n letterSpacing: -0.05,\n },\n reason: {\n color: ada.inkMuted,\n fontSize: fontSize.xs,\n marginTop: spacing.sm,\n marginLeft: 44 + spacing.md,\n lineHeight: 16,\n fontFamily: fontFam,\n },\n statusRow: {\n marginTop: spacing.sm,\n marginLeft: 44 + spacing.md,\n },\n grantedBadge: {\n backgroundColor: 'rgba(90, 138, 92, 0.14)',\n borderRadius: borderRadius.sm,\n paddingHorizontal: spacing.sm,\n paddingVertical: 3,\n alignSelf: 'flex-start',\n },\n grantedText: {\n color: '#5A8A5C',\n fontSize: fontSize.xs,\n fontWeight: '700',\n fontFamily: fontFam,\n letterSpacing: 0.2,\n },\n pendingBadge: {\n backgroundColor: ada.orangeSoft,\n borderRadius: borderRadius.sm,\n paddingHorizontal: spacing.sm,\n paddingVertical: 3,\n alignSelf: 'flex-start',\n },\n pendingText: {\n color: ada.orangeDeep,\n fontSize: fontSize.xs,\n fontWeight: '700',\n fontFamily: fontFam,\n letterSpacing: 0.2,\n },\n deniedBadge: {\n backgroundColor: 'rgba(193, 85, 69, 0.14)',\n borderRadius: borderRadius.sm,\n paddingHorizontal: spacing.sm,\n paddingVertical: 3,\n alignSelf: 'flex-start',\n },\n deniedText: {\n color: '#C15545',\n fontSize: fontSize.xs,\n fontWeight: '700',\n fontFamily: fontFam,\n letterSpacing: 0.2,\n },\n});\n"],"mappings":"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","names":["View","Text","Pressable","StyleSheet","Platform","ada","borderRadius","fontSize","spacing","jsx","jsxs","fontFam","Platform","styles","ada","View","Text","Pressable","StyleSheet","spacing","fontSize","borderRadius"]}
@@ -1807,4 +1807,4 @@ export {
1807
1807
  parseWalkJsonl,
1808
1808
  setupExpoProviders
1809
1809
  };
1810
- //# sourceMappingURL=chunk-42FP5DTO.mjs.map
1810
+ //# sourceMappingURL=chunk-2ZQEQJQ6.mjs.map