@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.
- package/dist/aiLive/provider.d.mts +20 -0
- package/dist/aiLive/provider.d.ts +20 -0
- package/dist/aiLive/provider.js +400 -0
- package/dist/aiLive/provider.js.map +1 -0
- package/dist/aiLive/provider.mjs +15 -0
- package/dist/aiLive/provider.mjs.map +1 -0
- package/dist/bootstrap.js +350 -3
- package/dist/bootstrap.js.map +1 -1
- package/dist/bootstrap.mjs +17 -12
- package/dist/bootstrap.mjs.map +1 -1
- package/dist/capabilities/index.d.mts +40 -1
- package/dist/capabilities/index.d.ts +40 -1
- package/dist/capabilities/index.js +50 -14
- package/dist/capabilities/index.js.map +1 -1
- package/dist/capabilities/index.mjs +49 -32
- package/dist/capabilities/index.mjs.map +1 -1
- package/dist/{chunk-42FP5DTO.mjs → chunk-2ZQEQJQ6.mjs} +1 -1
- package/dist/chunk-2ZQEQJQ6.mjs.map +1 -0
- package/dist/chunk-AE55BKYV.mjs +24 -0
- package/dist/chunk-AE55BKYV.mjs.map +1 -0
- package/dist/chunk-BAZFMTCC.mjs +815 -0
- package/dist/chunk-BAZFMTCC.mjs.map +1 -0
- package/dist/{chunk-Z5AI2SXX.mjs → chunk-C62NQA4F.mjs} +203 -1004
- package/dist/chunk-C62NQA4F.mjs.map +1 -0
- package/dist/{chunk-DE6Y4VRI.mjs → chunk-GA7DS3PA.mjs} +1 -1
- package/dist/{chunk-DE6Y4VRI.mjs.map → chunk-GA7DS3PA.mjs.map} +1 -1
- package/dist/chunk-GW7YGXOW.mjs +47 -0
- package/dist/chunk-GW7YGXOW.mjs.map +1 -0
- package/dist/chunk-JUBLG3PN.mjs +351 -0
- package/dist/chunk-JUBLG3PN.mjs.map +1 -0
- package/dist/{chunk-Z3P7RUCC.mjs → chunk-OEX4OKYQ.mjs} +13 -13
- package/dist/{chunk-6JX222YX.mjs → chunk-WQK6PUBN.mjs} +9 -2
- package/dist/chunk-WQK6PUBN.mjs.map +1 -0
- package/dist/device/createDeviceProvider.js.map +1 -1
- package/dist/device/createDeviceProvider.mjs +7 -6
- package/dist/device-bridge/index.mjs +8 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/push/index.d.mts +24 -0
- package/dist/push/index.d.ts +24 -0
- package/dist/push/index.js +224 -0
- package/dist/push/index.js.map +1 -0
- package/dist/push/index.mjs +174 -0
- package/dist/push/index.mjs.map +1 -0
- package/dist/push/silentSync.d.mts +8 -0
- package/dist/push/silentSync.d.ts +8 -0
- package/dist/push/silentSync.js +1075 -0
- package/dist/push/silentSync.js.map +1 -0
- package/dist/push/silentSync.mjs +67 -0
- package/dist/push/silentSync.mjs.map +1 -0
- package/dist/vision/index.d.mts +7 -1
- package/dist/vision/index.d.ts +7 -1
- package/dist/vision/index.js +8 -0
- package/dist/vision/index.js.map +1 -1
- package/dist/vision/index.mjs +3 -1
- package/ios/AdaVisionModule.swift +44 -1
- package/package.json +28 -6
- package/src/aiLive/provider.ts +242 -0
- package/src/aiLive/streamProtocol.ts +90 -0
- package/src/bootstrap.ts +7 -1
- package/src/capabilities/choices.ts +65 -0
- package/src/capabilities/config.ts +5 -4
- package/src/capabilities/index.ts +2 -0
- package/src/capabilities/picturesToAi.ts +40 -0
- package/src/capabilities/store.ts +38 -37
- package/src/index.ts +3 -0
- package/src/push/index.ts +18 -0
- package/src/push/messaging.ts +49 -0
- package/src/push/registration.ts +31 -0
- package/src/push/silentSync.ts +83 -0
- package/src/push/usePushNotifications.ts +224 -0
- package/src/vision/index.ts +14 -0
- package/dist/chunk-42FP5DTO.mjs.map +0 -1
- package/dist/chunk-6JX222YX.mjs.map +0 -1
- package/dist/chunk-Z5AI2SXX.mjs.map +0 -1
- /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-
|
|
11
|
+
} from "../chunk-GA7DS3PA.mjs";
|
|
5
12
|
import {
|
|
6
|
-
|
|
7
|
-
} from "../chunk-
|
|
13
|
+
DeviceBridge
|
|
14
|
+
} from "../chunk-BAZFMTCC.mjs";
|
|
8
15
|
import {
|
|
9
|
-
DeviceBridge,
|
|
10
16
|
capabilities_exports
|
|
11
|
-
} from "../chunk-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
|
154
|
-
|
|
155
|
-
|
|
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
|
|
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"]}
|