@glassly/miniapp 0.3.0-dev.1

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 (312) hide show
  1. package/README.md +275 -0
  2. package/dist/background/index.d.ts +64 -0
  3. package/dist/background/index.d.ts.map +1 -0
  4. package/dist/background/index.js +26 -0
  5. package/dist/background/index.js.map +1 -0
  6. package/dist/background/register.d.ts +39 -0
  7. package/dist/background/register.d.ts.map +1 -0
  8. package/dist/background/register.js +72 -0
  9. package/dist/background/register.js.map +1 -0
  10. package/dist/dev-reload.d.ts +21 -0
  11. package/dist/dev-reload.d.ts.map +1 -0
  12. package/dist/dev-reload.js +60 -0
  13. package/dist/dev-reload.js.map +1 -0
  14. package/dist/envelope.d.ts +23 -0
  15. package/dist/envelope.d.ts.map +1 -0
  16. package/dist/envelope.js +47 -0
  17. package/dist/envelope.js.map +1 -0
  18. package/dist/globals.d.ts +54 -0
  19. package/dist/globals.d.ts.map +1 -0
  20. package/dist/globals.js +12 -0
  21. package/dist/globals.js.map +1 -0
  22. package/dist/hardware.d.ts +38 -0
  23. package/dist/hardware.d.ts.map +1 -0
  24. package/dist/hardware.js +31 -0
  25. package/dist/hardware.js.map +1 -0
  26. package/dist/index.d.ts +65 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +34 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/modules/actions.d.ts +81 -0
  31. package/dist/modules/actions.d.ts.map +1 -0
  32. package/dist/modules/actions.js +137 -0
  33. package/dist/modules/actions.js.map +1 -0
  34. package/dist/modules/ai.d.ts +211 -0
  35. package/dist/modules/ai.d.ts.map +1 -0
  36. package/dist/modules/ai.js +117 -0
  37. package/dist/modules/ai.js.map +1 -0
  38. package/dist/modules/auth.d.ts +25 -0
  39. package/dist/modules/auth.d.ts.map +1 -0
  40. package/dist/modules/auth.js +52 -0
  41. package/dist/modules/auth.js.map +1 -0
  42. package/dist/modules/base64.d.ts +16 -0
  43. package/dist/modules/base64.d.ts.map +1 -0
  44. package/dist/modules/base64.js +92 -0
  45. package/dist/modules/base64.js.map +1 -0
  46. package/dist/modules/blob.d.ts +161 -0
  47. package/dist/modules/blob.d.ts.map +1 -0
  48. package/dist/modules/blob.js +277 -0
  49. package/dist/modules/blob.js.map +1 -0
  50. package/dist/modules/camera.d.ts +183 -0
  51. package/dist/modules/camera.d.ts.map +1 -0
  52. package/dist/modules/camera.js +119 -0
  53. package/dist/modules/camera.js.map +1 -0
  54. package/dist/modules/cloud.d.ts +34 -0
  55. package/dist/modules/cloud.d.ts.map +1 -0
  56. package/dist/modules/cloud.js +70 -0
  57. package/dist/modules/cloud.js.map +1 -0
  58. package/dist/modules/dashboard.d.ts +24 -0
  59. package/dist/modules/dashboard.d.ts.map +1 -0
  60. package/dist/modules/dashboard.js +39 -0
  61. package/dist/modules/dashboard.js.map +1 -0
  62. package/dist/modules/display.d.ts +167 -0
  63. package/dist/modules/display.d.ts.map +1 -0
  64. package/dist/modules/display.js +83 -0
  65. package/dist/modules/display.js.map +1 -0
  66. package/dist/modules/events.d.ts +178 -0
  67. package/dist/modules/events.d.ts.map +1 -0
  68. package/dist/modules/events.js +168 -0
  69. package/dist/modules/events.js.map +1 -0
  70. package/dist/modules/glasses.d.ts +36 -0
  71. package/dist/modules/glasses.d.ts.map +1 -0
  72. package/dist/modules/glasses.js +52 -0
  73. package/dist/modules/glasses.js.map +1 -0
  74. package/dist/modules/heading.d.ts +16 -0
  75. package/dist/modules/heading.d.ts.map +1 -0
  76. package/dist/modules/heading.js +20 -0
  77. package/dist/modules/heading.js.map +1 -0
  78. package/dist/modules/imu.d.ts +31 -0
  79. package/dist/modules/imu.d.ts.map +1 -0
  80. package/dist/modules/imu.js +40 -0
  81. package/dist/modules/imu.js.map +1 -0
  82. package/dist/modules/input.d.ts +34 -0
  83. package/dist/modules/input.d.ts.map +1 -0
  84. package/dist/modules/input.js +50 -0
  85. package/dist/modules/input.js.map +1 -0
  86. package/dist/modules/keys.d.ts +30 -0
  87. package/dist/modules/keys.d.ts.map +1 -0
  88. package/dist/modules/keys.js +37 -0
  89. package/dist/modules/keys.js.map +1 -0
  90. package/dist/modules/languages.d.ts +42 -0
  91. package/dist/modules/languages.d.ts.map +1 -0
  92. package/dist/modules/languages.js +57 -0
  93. package/dist/modules/languages.js.map +1 -0
  94. package/dist/modules/led.d.ts +35 -0
  95. package/dist/modules/led.d.ts.map +1 -0
  96. package/dist/modules/led.js +39 -0
  97. package/dist/modules/led.js.map +1 -0
  98. package/dist/modules/location.d.ts +27 -0
  99. package/dist/modules/location.d.ts.map +1 -0
  100. package/dist/modules/location.js +35 -0
  101. package/dist/modules/location.js.map +1 -0
  102. package/dist/modules/memory.d.ts +126 -0
  103. package/dist/modules/memory.d.ts.map +1 -0
  104. package/dist/modules/memory.js +141 -0
  105. package/dist/modules/memory.js.map +1 -0
  106. package/dist/modules/mic.d.ts +61 -0
  107. package/dist/modules/mic.d.ts.map +1 -0
  108. package/dist/modules/mic.js +94 -0
  109. package/dist/modules/mic.js.map +1 -0
  110. package/dist/modules/miniapps.d.ts +82 -0
  111. package/dist/modules/miniapps.d.ts.map +1 -0
  112. package/dist/modules/miniapps.js +58 -0
  113. package/dist/modules/miniapps.js.map +1 -0
  114. package/dist/modules/navigation.d.ts +332 -0
  115. package/dist/modules/navigation.d.ts.map +1 -0
  116. package/dist/modules/navigation.js +387 -0
  117. package/dist/modules/navigation.js.map +1 -0
  118. package/dist/modules/permissions.d.ts +58 -0
  119. package/dist/modules/permissions.d.ts.map +1 -0
  120. package/dist/modules/permissions.js +66 -0
  121. package/dist/modules/permissions.js.map +1 -0
  122. package/dist/modules/phone.d.ts +95 -0
  123. package/dist/modules/phone.d.ts.map +1 -0
  124. package/dist/modules/phone.js +110 -0
  125. package/dist/modules/phone.js.map +1 -0
  126. package/dist/modules/pivots/engine.d.ts +169 -0
  127. package/dist/modules/pivots/engine.d.ts.map +1 -0
  128. package/dist/modules/pivots/engine.js +778 -0
  129. package/dist/modules/pivots/engine.js.map +1 -0
  130. package/dist/modules/pivots/geometry.d.ts +84 -0
  131. package/dist/modules/pivots/geometry.d.ts.map +1 -0
  132. package/dist/modules/pivots/geometry.js +371 -0
  133. package/dist/modules/pivots/geometry.js.map +1 -0
  134. package/dist/modules/pivots/instructions.d.ts +139 -0
  135. package/dist/modules/pivots/instructions.d.ts.map +1 -0
  136. package/dist/modules/pivots/instructions.js +281 -0
  137. package/dist/modules/pivots/instructions.js.map +1 -0
  138. package/dist/modules/speaker.d.ts +175 -0
  139. package/dist/modules/speaker.d.ts.map +1 -0
  140. package/dist/modules/speaker.js +249 -0
  141. package/dist/modules/speaker.js.map +1 -0
  142. package/dist/modules/speakers.d.ts +29 -0
  143. package/dist/modules/speakers.d.ts.map +1 -0
  144. package/dist/modules/speakers.js +38 -0
  145. package/dist/modules/speakers.js.map +1 -0
  146. package/dist/modules/storage.d.ts +50 -0
  147. package/dist/modules/storage.d.ts.map +1 -0
  148. package/dist/modules/storage.js +99 -0
  149. package/dist/modules/storage.js.map +1 -0
  150. package/dist/modules/stream.d.ts +133 -0
  151. package/dist/modules/stream.d.ts.map +1 -0
  152. package/dist/modules/stream.js +53 -0
  153. package/dist/modules/stream.js.map +1 -0
  154. package/dist/modules/system.d.ts +71 -0
  155. package/dist/modules/system.d.ts.map +1 -0
  156. package/dist/modules/system.js +65 -0
  157. package/dist/modules/system.js.map +1 -0
  158. package/dist/modules/transcription.d.ts +99 -0
  159. package/dist/modules/transcription.d.ts.map +1 -0
  160. package/dist/modules/transcription.js +126 -0
  161. package/dist/modules/transcription.js.map +1 -0
  162. package/dist/modules/translation.d.ts +65 -0
  163. package/dist/modules/translation.d.ts.map +1 -0
  164. package/dist/modules/translation.js +121 -0
  165. package/dist/modules/translation.js.map +1 -0
  166. package/dist/modules/ui.d.ts +186 -0
  167. package/dist/modules/ui.d.ts.map +1 -0
  168. package/dist/modules/ui.js +289 -0
  169. package/dist/modules/ui.js.map +1 -0
  170. package/dist/protocol.d.ts +384 -0
  171. package/dist/protocol.d.ts.map +1 -0
  172. package/dist/protocol.js +413 -0
  173. package/dist/protocol.js.map +1 -0
  174. package/dist/react/MiniappHeader.d.ts +44 -0
  175. package/dist/react/MiniappHeader.d.ts.map +1 -0
  176. package/dist/react/MiniappHeader.js +32 -0
  177. package/dist/react/MiniappHeader.js.map +1 -0
  178. package/dist/react/MiniappProvider.d.ts +33 -0
  179. package/dist/react/MiniappProvider.d.ts.map +1 -0
  180. package/dist/react/MiniappProvider.js +15 -0
  181. package/dist/react/MiniappProvider.js.map +1 -0
  182. package/dist/react/capsuleHeaderLayout.d.ts +3 -0
  183. package/dist/react/capsuleHeaderLayout.d.ts.map +1 -0
  184. package/dist/react/capsuleHeaderLayout.js +5 -0
  185. package/dist/react/capsuleHeaderLayout.js.map +1 -0
  186. package/dist/react/index.d.ts +13 -0
  187. package/dist/react/index.d.ts.map +1 -0
  188. package/dist/react/index.js +9 -0
  189. package/dist/react/index.js.map +1 -0
  190. package/dist/react/useCapabilities.d.ts +26 -0
  191. package/dist/react/useCapabilities.d.ts.map +1 -0
  192. package/dist/react/useCapabilities.js +27 -0
  193. package/dist/react/useCapabilities.js.map +1 -0
  194. package/dist/react/useCapsuleHeaderStyle.d.ts +27 -0
  195. package/dist/react/useCapsuleHeaderStyle.d.ts.map +1 -0
  196. package/dist/react/useCapsuleHeaderStyle.js +39 -0
  197. package/dist/react/useCapsuleHeaderStyle.js.map +1 -0
  198. package/dist/react/useColorScheme.d.ts +18 -0
  199. package/dist/react/useColorScheme.d.ts.map +1 -0
  200. package/dist/react/useColorScheme.js +24 -0
  201. package/dist/react/useColorScheme.js.map +1 -0
  202. package/dist/react/useConnected.d.ts +17 -0
  203. package/dist/react/useConnected.d.ts.map +1 -0
  204. package/dist/react/useConnected.js +39 -0
  205. package/dist/react/useConnected.js.map +1 -0
  206. package/dist/react/useRpc.d.ts +29 -0
  207. package/dist/react/useRpc.d.ts.map +1 -0
  208. package/dist/react/useRpc.js +82 -0
  209. package/dist/react/useRpc.js.map +1 -0
  210. package/dist/react/useSafeArea.d.ts +21 -0
  211. package/dist/react/useSafeArea.d.ts.map +1 -0
  212. package/dist/react/useSafeArea.js +22 -0
  213. package/dist/react/useSafeArea.js.map +1 -0
  214. package/dist/session.d.ts +355 -0
  215. package/dist/session.d.ts.map +1 -0
  216. package/dist/session.js +688 -0
  217. package/dist/session.js.map +1 -0
  218. package/dist/sub-path-types.test-d.d.ts +40 -0
  219. package/dist/sub-path-types.test-d.d.ts.map +1 -0
  220. package/dist/sub-path-types.test-d.js +37 -0
  221. package/dist/sub-path-types.test-d.js.map +1 -0
  222. package/dist/transport/auto.d.ts +35 -0
  223. package/dist/transport/auto.d.ts.map +1 -0
  224. package/dist/transport/auto.js +124 -0
  225. package/dist/transport/auto.js.map +1 -0
  226. package/dist/transport/dispatch.d.ts +43 -0
  227. package/dist/transport/dispatch.d.ts.map +1 -0
  228. package/dist/transport/dispatch.js +91 -0
  229. package/dist/transport/dispatch.js.map +1 -0
  230. package/dist/transport/local-socket.d.ts +28 -0
  231. package/dist/transport/local-socket.d.ts.map +1 -0
  232. package/dist/transport/local-socket.js +80 -0
  233. package/dist/transport/local-socket.js.map +1 -0
  234. package/dist/transport/mock.d.ts +54 -0
  235. package/dist/transport/mock.d.ts.map +1 -0
  236. package/dist/transport/mock.js +210 -0
  237. package/dist/transport/mock.js.map +1 -0
  238. package/dist/transport/postmessage.d.ts +36 -0
  239. package/dist/transport/postmessage.d.ts.map +1 -0
  240. package/dist/transport/postmessage.js +78 -0
  241. package/dist/transport/postmessage.js.map +1 -0
  242. package/dist/transport/types.d.ts +25 -0
  243. package/dist/transport/types.d.ts.map +1 -0
  244. package/dist/transport/types.js +11 -0
  245. package/dist/transport/types.js.map +1 -0
  246. package/dist/ui/index.d.ts +107 -0
  247. package/dist/ui/index.d.ts.map +1 -0
  248. package/dist/ui/index.js +32 -0
  249. package/dist/ui/index.js.map +1 -0
  250. package/package.json +84 -0
  251. package/src/background/index.ts +177 -0
  252. package/src/background/register.ts +89 -0
  253. package/src/dev-reload.ts +59 -0
  254. package/src/envelope.ts +54 -0
  255. package/src/globals.ts +62 -0
  256. package/src/hardware.ts +40 -0
  257. package/src/index.ts +216 -0
  258. package/src/modules/actions.ts +189 -0
  259. package/src/modules/ai.ts +281 -0
  260. package/src/modules/auth.ts +68 -0
  261. package/src/modules/base64.ts +87 -0
  262. package/src/modules/blob.ts +341 -0
  263. package/src/modules/camera.ts +258 -0
  264. package/src/modules/cloud.ts +94 -0
  265. package/src/modules/dashboard.ts +51 -0
  266. package/src/modules/display.ts +207 -0
  267. package/src/modules/events.ts +318 -0
  268. package/src/modules/glasses.ts +58 -0
  269. package/src/modules/heading.ts +23 -0
  270. package/src/modules/imu.ts +44 -0
  271. package/src/modules/input.ts +66 -0
  272. package/src/modules/keys.ts +46 -0
  273. package/src/modules/languages.ts +72 -0
  274. package/src/modules/led.ts +61 -0
  275. package/src/modules/location.ts +39 -0
  276. package/src/modules/memory.ts +224 -0
  277. package/src/modules/mic.ts +103 -0
  278. package/src/modules/miniapps.ts +103 -0
  279. package/src/modules/navigation.ts +674 -0
  280. package/src/modules/permissions.ts +83 -0
  281. package/src/modules/phone.ts +155 -0
  282. package/src/modules/pivots/engine.ts +863 -0
  283. package/src/modules/pivots/geometry.ts +409 -0
  284. package/src/modules/pivots/instructions.ts +341 -0
  285. package/src/modules/speaker.ts +347 -0
  286. package/src/modules/speakers.ts +40 -0
  287. package/src/modules/storage.ts +109 -0
  288. package/src/modules/stream.ts +168 -0
  289. package/src/modules/system.ts +113 -0
  290. package/src/modules/transcription.ts +180 -0
  291. package/src/modules/translation.ts +156 -0
  292. package/src/modules/ui.ts +481 -0
  293. package/src/protocol.ts +475 -0
  294. package/src/react/MiniappHeader.tsx +114 -0
  295. package/src/react/MiniappProvider.tsx +50 -0
  296. package/src/react/capsuleHeaderLayout.ts +11 -0
  297. package/src/react/index.ts +12 -0
  298. package/src/react/useCapabilities.ts +29 -0
  299. package/src/react/useCapsuleHeaderStyle.ts +55 -0
  300. package/src/react/useColorScheme.ts +26 -0
  301. package/src/react/useConnected.ts +47 -0
  302. package/src/react/useRpc.ts +103 -0
  303. package/src/react/useSafeArea.ts +36 -0
  304. package/src/session.ts +969 -0
  305. package/src/sub-path-types.test-d.ts +60 -0
  306. package/src/transport/auto.ts +143 -0
  307. package/src/transport/dispatch.ts +106 -0
  308. package/src/transport/local-socket.ts +91 -0
  309. package/src/transport/mock.ts +255 -0
  310. package/src/transport/postmessage.ts +95 -0
  311. package/src/transport/types.ts +26 -0
  312. package/src/ui/index.ts +129 -0
package/src/index.ts ADDED
@@ -0,0 +1,216 @@
1
+ /**
2
+ * @glassly/miniapp — SDK for building Glassly local miniapps.
3
+ *
4
+ * Public entry point. Consumers do:
5
+ *
6
+ * import {MiniappSession} from "@glassly/miniapp" // background JSContext
7
+ * import {useColorScheme} from "@glassly/miniapp/react" // UI WebView hooks
8
+ * import {MiniappRequestType} from "@glassly/miniapp/protocol"
9
+ */
10
+
11
+ import {installDevReloadListenerIfDevMode} from "./dev-reload"
12
+
13
+ // Auto-install the dev-reload listener on module import so authors get live
14
+ // reload for free in dev builds. No-op in production (gated on
15
+ // window.Glassly.miniappDeveloperMode).
16
+ installDevReloadListenerIfDevMode()
17
+
18
+ export {MiniappSession, NotConnectedError} from "./session"
19
+ export type {
20
+ AuthUpdatePayload,
21
+ ConnectAckPayload,
22
+ DisplayCapabilities,
23
+ GlassesCapabilities,
24
+ MiniappAuthState,
25
+ MiniappRequestError,
26
+ MiniappSessionOptions,
27
+ MiniappVisibility,
28
+ } from "./session"
29
+ export type {AuthFetchOptions, AuthModule} from "./modules/auth"
30
+
31
+ export {makeRequestId, parseEnvelope, serializeEnvelope} from "./envelope"
32
+ export type {MiniappEnvelope} from "./envelope"
33
+
34
+ export {getGlasslyGlobals} from "./globals"
35
+ export type {GlasslyGlobals, MiniappCapsuleMenuRect, MiniappColorScheme, MiniappSafeAreaInsets} from "./globals"
36
+
37
+ export {MiniappErrorCode, MiniappRequestType, MiniappResponseType, MiniappStreamType} from "./protocol"
38
+ export {CLOUD_STATUS_STREAM} from "./modules/cloud"
39
+
40
+ // Language registry (issue 021): canonical language types + the validation
41
+ // error the typed transcription/translation surfaces throw.
42
+ export {
43
+ MiniappValidationError,
44
+ SUPPORTED_LANGUAGE_HINTS,
45
+ SUPPORTED_TRANSCRIPTION_LANGUAGES,
46
+ isTranscriptionLanguage,
47
+ } from "./modules/languages"
48
+ export type {LanguageHint, TranscriptionLanguage} from "./modules/languages"
49
+ export type {CloudClientAudioTransport, CloudClientConnectionStatus, CloudClientStatus} from "./modules/cloud"
50
+
51
+ // Hardware requirement types — canonical defs live in ./hardware; miniapp
52
+ // authors type their miniapp.json manifest with these, and @glassly/engine
53
+ // re-exports them. Keep explicit exports (enums as value, interfaces as
54
+ // type) for Bun compat.
55
+ export {HardwareType, HardwareRequirementLevel} from "./hardware"
56
+ export type {HardwareRequirement} from "./hardware"
57
+
58
+ // Transports — exported for advanced uses (forced transport injection, tests)
59
+ export {createTransport} from "./transport/auto"
60
+ export type {CreateTransportOptions} from "./transport/auto"
61
+ export {PostMessageTransport} from "./transport/postmessage"
62
+ export {LocalSocketTransport} from "./transport/local-socket"
63
+ export type {LocalSocketTransportOptions} from "./transport/local-socket"
64
+ export {MockTransport, isMockExplicitlyRequested} from "./transport/mock"
65
+ export type {MockTransportOptions} from "./transport/mock"
66
+ export type {Transport, TransportDisconnectHandler, TransportMessageHandler} from "./transport/types"
67
+
68
+ // Module types — useful for typing handlers in consumer code
69
+ export type {
70
+ DisplayBreakMode,
71
+ NativeNavInfo,
72
+ NativeNavResult,
73
+ RenderBox,
74
+ RenderElement,
75
+ RenderOptions,
76
+ RenderRectStyle,
77
+ RenderResult,
78
+ RenderTextStyle,
79
+ ViewType,
80
+ } from "./modules/display"
81
+ export type {
82
+ AccelData,
83
+ AudioChunkData,
84
+ BatteryData,
85
+ ButtonPressData,
86
+ ConnectionData,
87
+ HeadingData,
88
+ HeadPositionData,
89
+ LocationData,
90
+ NotificationDismissedData,
91
+ PhoneNotificationData,
92
+ TouchData,
93
+ TranscriptionData,
94
+ TranslationData,
95
+ UnsubscribeFn,
96
+ VadData,
97
+ WifiData,
98
+ } from "./modules/events"
99
+ export type {CalendarEvent, CalendarListOptions, CalendarListResult} from "./modules/phone"
100
+ export type {
101
+ PlayAudioOptions,
102
+ SpeakOptions,
103
+ SpeakResult,
104
+ SpeakerState,
105
+ SpeakerStateEvent,
106
+ SpeakerStreamOptions,
107
+ SpeakerStreamSampleRate,
108
+ SpeakerStreamWriteResult,
109
+ } from "./modules/speaker"
110
+ export {SpeakerStreamWriter, SPEAKER_STREAM_MAX_BUFFERED_MS, SPEAKER_WRITE_CHUNK_BYTES} from "./modules/speaker"
111
+ export type {
112
+ CameraFovPreset,
113
+ CameraFovRequest,
114
+ CameraFovResult,
115
+ CameraRoiPosition,
116
+ PhotoTaken,
117
+ SetCameraFovOptions,
118
+ StartVideoRecordingOptions,
119
+ StopVideoRecordingOptions,
120
+ TakePhotoOptions,
121
+ VideoRecordingStarted,
122
+ } from "./modules/camera"
123
+ export type {DashboardMode, ShowNativeDashboardResult} from "./modules/dashboard"
124
+ export type {CloudModule} from "./modules/cloud"
125
+ export type {LedColor, LedControlOptions} from "./modules/led"
126
+ export type {
127
+ RestreamDestination,
128
+ StartStreamOptions,
129
+ StreamAudioConfig,
130
+ StreamResolvedConfig,
131
+ StreamResult,
132
+ StreamStatus,
133
+ StreamVideoConfig,
134
+ } from "./modules/stream"
135
+ export type {
136
+ ShareOptions,
137
+ ShareResult,
138
+ DownloadOptions,
139
+ DownloadResult,
140
+ ScanQrOptions,
141
+ ScanQrResult,
142
+ } from "./modules/system"
143
+ export type {MiniappInfo, MiniappActionInfo, MiniappCompatibility, ListMiniappsOptions} from "./modules/miniapps"
144
+ export type {ActionContext, ActionDescriptor, ActionHandler, InvokeOptions} from "./modules/actions"
145
+
146
+ // Domain module types — exported so consumers can type module references
147
+ // (rare; most authors interact via session.<module>.<method> directly).
148
+ export type {DisplayManager} from "./modules/display"
149
+ export type {MiniappsModule} from "./modules/miniapps"
150
+ export type {ActionsModule} from "./modules/actions"
151
+ export type {GlassesModule} from "./modules/glasses"
152
+ export type {HeadingModule} from "./modules/heading"
153
+ export type {
154
+ AiModule,
155
+ AiProvider,
156
+ AiTier,
157
+ AiTool,
158
+ AiToolCall,
159
+ AiToolResult,
160
+ AiMessage,
161
+ AiCompleteRequest,
162
+ AiCompleteResult,
163
+ AiStopReason,
164
+ AiUsage,
165
+ } from "./modules/ai"
166
+ export type {ImuModule} from "./modules/imu"
167
+ export type {InputModule} from "./modules/input"
168
+ export type {KeysModule, ApiKeyProvider} from "./modules/keys"
169
+ export type {LocationModule} from "./modules/location"
170
+ export type {
171
+ MemoryModule,
172
+ MemoryEntry,
173
+ MemoryEntryKind,
174
+ MemoryNoteSource,
175
+ MemoryQuery,
176
+ MemorySearchResult,
177
+ MemorySession,
178
+ MemorySummary,
179
+ } from "./modules/memory"
180
+ export type {SpeakersModule} from "./modules/speakers"
181
+ export type {MicModule} from "./modules/mic"
182
+ export type {
183
+ ComputedRoute,
184
+ ComputedRouteStep,
185
+ ComputeRouteOptions,
186
+ ComputeRouteResult,
187
+ LatLng,
188
+ NavArrived,
189
+ NavCancelled,
190
+ NavError,
191
+ NavigationModule,
192
+ NavManeuver,
193
+ NavOffRoute,
194
+ NavPermissionResult,
195
+ NavPlaceDetails,
196
+ NavPlaceSuggestion,
197
+ NavRerouting,
198
+ NavRoute,
199
+ NavState,
200
+ NavStep,
201
+ NavUpdate,
202
+ Pivot,
203
+ PivotEvent,
204
+ PivotOptions,
205
+ RouteAvoidances,
206
+ StartNavigationOptions,
207
+ TravelMode,
208
+ } from "./modules/navigation"
209
+ export type {PermissionsModule, PermissionErrorEvent} from "./modules/permissions"
210
+ export type {PhoneModule, PhoneNotificationsModule, PhoneCalendarModule} from "./modules/phone"
211
+ export type {TranscriptionModule, TranscriptionConfig, TranscriptionOptions} from "./modules/transcription"
212
+ export type {TranslationModule} from "./modules/translation"
213
+ export type {SpeakerModule} from "./modules/speaker"
214
+
215
+ // Permission types
216
+ export type {PermissionType, PermissionRecord} from "./session"
@@ -0,0 +1,189 @@
1
+ /**
2
+ * @fileoverview ActionsModule — `session.actions`.
3
+ *
4
+ * The MCP-shaped capability layer (miniapp tools), all three directions:
5
+ * - `list()` — discover every action the caller may invoke across installed
6
+ * miniapps (the MCP tools/list analog).
7
+ * - `invoke(pkg, actionId, params)` — call another miniapp's declared action.
8
+ * Open to all miniapps; headless-wakes the target if it's stopped. Actions
9
+ * declared with `visibility: "system"` stay restricted to system apps.
10
+ * - `handle(actionId, fn)` — expose one of your own actions. Mirrors
11
+ * `session.ui.handle` (one handler per id, throws on double-register,
12
+ * errors propagate to the caller).
13
+ *
14
+ * `invoke` ↔ `handle` are the two ends of one wire (keyed by `actionId`), which
15
+ * is why they share this namespace rather than being split across
16
+ * `session.miniapps` (whose lifecycle surface stays SYSTEM-only).
17
+ */
18
+
19
+ import {MiniappErrorCode, MiniappRequestType} from "../protocol"
20
+ import {MiniappSession} from "../session"
21
+
22
+ /** Context handed to an action handler. `callerPackageName` is host-stamped. */
23
+ export interface ActionContext {
24
+ /** The package that invoked this action (trustworthy — set by the host). */
25
+ callerPackageName: string
26
+ }
27
+
28
+ export type ActionHandler = (params: Record<string, unknown>, ctx: ActionContext) => unknown | Promise<unknown>
29
+
30
+ export interface InvokeOptions {
31
+ /** Overall timeout in ms (default 30s, max 120s — host-enforced). */
32
+ timeoutMs?: number
33
+ }
34
+
35
+ /**
36
+ * One invokable action surfaced by {@link ActionsModule.list}. Maps 1:1 onto
37
+ * an MCP tool: `id`→name, `description`, `parameters`→inputSchema.
38
+ */
39
+ export interface ActionDescriptor {
40
+ /** The miniapp that declares (and handles) the action. */
41
+ packageName: string
42
+ /** Human-readable name of that miniapp. */
43
+ appName: string
44
+ id: string
45
+ description: string
46
+ /** JSON-Schema input descriptor (the MCP-compatible subset). */
47
+ parameters?: Record<string, unknown>
48
+ /** JSON-Schema descriptor for the structured result. */
49
+ outputSchema?: Record<string, unknown>
50
+ }
51
+
52
+ interface BufferedCall {
53
+ callId: string
54
+ params: Record<string, unknown>
55
+ ctx: ActionContext
56
+ timer: ReturnType<typeof setTimeout>
57
+ }
58
+
59
+ /**
60
+ * How long the SDK holds an inbound ACTION_CALL waiting for its handler to
61
+ * register (a just-woken miniapp registers handlers a beat after CONNECT).
62
+ * If no handler appears in this window the call is failed with
63
+ * NO_ACTION_HANDLER. Mirrors the UI bus's pre-handler buffering.
64
+ */
65
+ const HANDLER_WAIT_MS = 5_000
66
+
67
+ export class ActionsModule {
68
+ private readonly handlers = new Map<string, ActionHandler>()
69
+ /** Inbound calls buffered until their handler registers, keyed by actionId. */
70
+ private readonly buffered = new Map<string, BufferedCall[]>()
71
+
72
+ constructor(private readonly session: MiniappSession) {}
73
+
74
+ /**
75
+ * List every action this miniapp may invoke across installed miniapps.
76
+ * Incompatible apps and the caller's own actions are excluded; actions
77
+ * declared `visibility: "system"` only appear for system callers.
78
+ */
79
+ list(): Promise<ActionDescriptor[]> {
80
+ return this.session.sendRequest<ActionDescriptor[]>({
81
+ type: MiniappRequestType.ACTIONS_LIST,
82
+ })
83
+ }
84
+
85
+ /**
86
+ * Invoke a declared action on another miniapp. Resolves with the handler's
87
+ * return value, rejects with a MiniappRequestError (NOT_PERMITTED,
88
+ * APP_NOT_FOUND, ACTION_NOT_FOUND, WAKE_FAILED, NO_ACTION_HANDLER,
89
+ * ACTION_TIMEOUT, PAYLOAD_TOO_LARGE, or the handler's own error). Open to
90
+ * all miniapps; the target keeps running after the call — a target that
91
+ * wants to shut down when done can call `session.system.exit()` itself.
92
+ */
93
+ invoke<TResult = unknown>(
94
+ packageName: string,
95
+ actionId: string,
96
+ params?: Record<string, unknown>,
97
+ opts?: InvokeOptions,
98
+ ): Promise<TResult> {
99
+ return this.session.sendRequest<TResult>({
100
+ type: MiniappRequestType.ACTION_INVOKE,
101
+ targetPackageName: packageName,
102
+ actionId,
103
+ params: params ?? {},
104
+ ...(opts?.timeoutMs != null ? {timeoutMs: opts.timeoutMs} : {}),
105
+ })
106
+ }
107
+
108
+ /**
109
+ * Register a handler for one of this miniapp's declared actions. One handler
110
+ * per actionId — throws synchronously on double-register. The returned
111
+ * function unregisters. Declare the action in `miniapp.json` for it to be
112
+ * invokable; an undeclared id still registers but the host never routes to it.
113
+ */
114
+ handle(actionId: string, handler: ActionHandler): () => void {
115
+ if (this.handlers.has(actionId)) {
116
+ throw new Error(`session.actions.handle: a handler is already registered for "${actionId}"`)
117
+ }
118
+ this.handlers.set(actionId, handler)
119
+
120
+ // Flush any calls that arrived before this handler registered.
121
+ const waiting = this.buffered.get(actionId)
122
+ if (waiting) {
123
+ this.buffered.delete(actionId)
124
+ for (const call of waiting) {
125
+ clearTimeout(call.timer)
126
+ void this.dispatch(call.callId, actionId, call.params, call.ctx)
127
+ }
128
+ }
129
+
130
+ return () => {
131
+ if (this.handlers.get(actionId) === handler) this.handlers.delete(actionId)
132
+ }
133
+ }
134
+
135
+ /**
136
+ * @internal — called by MiniappSession.handleIncoming on an ACTION_CALL.
137
+ * Routes to the registered handler, or buffers briefly for one to appear.
138
+ */
139
+ _deliver(callId: string, actionId: string, params: Record<string, unknown>, ctx: ActionContext): void {
140
+ if (this.handlers.has(actionId)) {
141
+ void this.dispatch(callId, actionId, params, ctx)
142
+ return
143
+ }
144
+ // No handler yet — buffer, and fail with NO_ACTION_HANDLER if none registers.
145
+ const timer = setTimeout(() => {
146
+ const arr = this.buffered.get(actionId)
147
+ if (arr) {
148
+ const idx = arr.findIndex((c) => c.callId === callId)
149
+ if (idx >= 0) arr.splice(idx, 1)
150
+ if (arr.length === 0) this.buffered.delete(actionId)
151
+ }
152
+ this.sendResult(callId, false, undefined, {
153
+ code: MiniappErrorCode.NO_ACTION_HANDLER,
154
+ message: `No handler registered for action "${actionId}"`,
155
+ })
156
+ }, HANDLER_WAIT_MS)
157
+ const arr = this.buffered.get(actionId) ?? []
158
+ arr.push({callId, params, ctx, timer})
159
+ this.buffered.set(actionId, arr)
160
+ }
161
+
162
+ private async dispatch(
163
+ callId: string,
164
+ actionId: string,
165
+ params: Record<string, unknown>,
166
+ ctx: ActionContext,
167
+ ): Promise<void> {
168
+ const handler = this.handlers.get(actionId)
169
+ if (!handler) return
170
+ try {
171
+ const result = await handler(params, ctx)
172
+ this.sendResult(callId, true, result ?? null)
173
+ } catch (e) {
174
+ this.sendResult(callId, false, undefined, {
175
+ code: MiniappErrorCode.INTERNAL,
176
+ message: (e as Error)?.message ?? "action handler threw",
177
+ })
178
+ }
179
+ }
180
+
181
+ private sendResult(callId: string, ok: boolean, result?: unknown, error?: {code: string; message: string}): void {
182
+ this.session.sendOneShot({
183
+ type: MiniappRequestType.ACTION_RESULT,
184
+ callId,
185
+ ok,
186
+ ...(ok ? {result} : {error}),
187
+ })
188
+ }
189
+ }
@@ -0,0 +1,281 @@
1
+ /**
2
+ * @fileoverview AiModule — run LLM completions through the platform.
3
+ *
4
+ * A miniapp that declares the AI permission in miniapp.json can call
5
+ * {@link AiModule.complete}; the phone runtime rejects with
6
+ * PERMISSION_NOT_DECLARED otherwise.
7
+ *
8
+ * WHY GO THROUGH THE PLATFORM instead of calling a provider directly with a key
9
+ * from `session.keys.get()`: the miniapp ships no API key, the platform picks
10
+ * and pays for the provider, and usage is metered so it can count against a
11
+ * plan. When the user HAS saved their own key for the resolved provider the
12
+ * platform uses that instead and the call is not metered — `billedToUserKey`
13
+ * on the result says which happened.
14
+ *
15
+ * PROVIDER-NEUTRAL — deliberately more so than before: a miniapp cannot name a
16
+ * provider or model at all. It states how much model the call deserves via
17
+ * `tier`, and the HOST resolves that to a provider+model (the user's per-tier
18
+ * dropdown in Settings > AI Models, or an automatic pick from whichever keys
19
+ * they saved). Vendor differences (system prompt placement, JSON mode,
20
+ * tool-schema dialect, tool-call ids) are absorbed below the session API.
21
+ *
22
+ * DELIBERATELY NOT SUPPORTED on complete(): streaming, and provider
23
+ * server-side tools other than web search (Anthropic `code_execution` /
24
+ * Files API) — complete() stays provider-neutral. Web search IS supported,
25
+ * as the single neutral `webSearch` flag: a capability grant the serving
26
+ * provider maps to its own search tool (or ignores when it has none — see
27
+ * the field's doc).
28
+ *
29
+ * generate() is the one sanctioned exception: an agentic visual-generation
30
+ * call where the CLOUD runs a provider loop with server-side tools (web
31
+ * search, code execution, file retrieval) and returns text plus rendered
32
+ * images. Anthropic-only by design, long-running (up to ~2.5 min), and
33
+ * markedly more expensive than a completion — call it deliberately.
34
+ */
35
+
36
+ import {MiniappRequestType} from "../protocol"
37
+ import {MiniappSession} from "../session"
38
+
39
+ /** Providers the platform can route to. Reported on results; never requested. */
40
+ export type AiProvider = "anthropic" | "gemini" | "openai"
41
+
42
+ /**
43
+ * How much model a call deserves. The host maps each tier to a concrete
44
+ * provider+model (Settings > AI Models); a miniapp never names either.
45
+ * - quick: high-volume gating/classification where latency and cost dominate.
46
+ * - balanced: routine generation (summaries, extraction).
47
+ * - frontier: the user-facing answer where quality dominates.
48
+ */
49
+ export type AiTier = "quick" | "balanced" | "frontier"
50
+
51
+ /** A tool the MINIAPP executes. The platform never runs these. */
52
+ export interface AiTool {
53
+ name: string
54
+ description: string
55
+ /**
56
+ * JSON Schema for the arguments, lowercase dialect (`"object"`, `"string"`).
57
+ * Gemini's uppercase OpenAPI dialect is translated server-side.
58
+ */
59
+ inputSchema: Record<string, unknown>
60
+ }
61
+
62
+ /** A model-issued tool call for the miniapp to execute. */
63
+ export interface AiToolCall {
64
+ /** Echo this back verbatim on the matching result — never reorder or invent ids. */
65
+ id: string
66
+ name: string
67
+ input: Record<string, unknown>
68
+ }
69
+
70
+ /** The miniapp's answer to one {@link AiToolCall}. */
71
+ export interface AiToolResult {
72
+ toolCallId: string
73
+ /** Serialized result — JSON.stringify structured data yourself. */
74
+ content: string
75
+ /** True when the tool failed, so the model can recover rather than hang. */
76
+ isError?: boolean
77
+ }
78
+
79
+ /** One conversation turn. */
80
+ export interface AiMessage {
81
+ role: "user" | "assistant"
82
+ content: string
83
+ /** Present on an assistant turn the model paused on to call tools. */
84
+ toolCalls?: AiToolCall[]
85
+ /** Present on a user turn answering those calls. */
86
+ toolResults?: AiToolResult[]
87
+ }
88
+
89
+ export interface AiCompleteRequest {
90
+ messages: AiMessage[]
91
+ system?: string
92
+ /** Model tier for this call. Omitted means "balanced". */
93
+ tier?: AiTier
94
+ maxTokens?: number
95
+ /** Advisory: providers whose current models reject sampling params drop it. */
96
+ temperature?: number
97
+ /** Ask for a JSON object back. You still parse and validate the text. */
98
+ jsonMode?: boolean
99
+ tools?: AiTool[]
100
+ /**
101
+ * Let the model search the web when live data would help. A GRANT, not a
102
+ * command: the model may answer from knowledge, and providers without a
103
+ * server-side search tool (currently OpenAI) ignore the flag. Searches run
104
+ * inside the same call — no extra round-trip, no tool loop on your side —
105
+ * and `webSearchCount` on the result reports how many actually ran.
106
+ * Platform-funded searches cost a small per-search surcharge on top of
107
+ * tokens.
108
+ */
109
+ webSearch?: boolean
110
+ }
111
+
112
+ /**
113
+ * Why the model stopped. `refusal` is a SUCCESSFUL result (the model declined),
114
+ * not an error — check it before trusting `text`.
115
+ */
116
+ export type AiStopReason = "end_turn" | "tool_use" | "max_tokens" | "refusal"
117
+
118
+ export interface AiUsage {
119
+ inputTokens: number
120
+ outputTokens: number
121
+ }
122
+
123
+ export interface AiCompleteResult {
124
+ /** Concatenated text. Empty when the model only called tools. */
125
+ text: string
126
+ stopReason: AiStopReason
127
+ /** Populated iff `stopReason === "tool_use"`. */
128
+ toolCalls?: AiToolCall[]
129
+ usage: AiUsage
130
+ provider: AiProvider
131
+ model: string
132
+ /** True when the user's own key paid for this call, so it wasn't metered. */
133
+ billedToUserKey: boolean
134
+ /**
135
+ * Server-side web searches the model ran (see `webSearch` on the request).
136
+ * Absent/0 when search wasn't granted, the provider has none, or the model
137
+ * answered from knowledge.
138
+ */
139
+ webSearchCount?: number
140
+ }
141
+
142
+ /** Internal event stream carrying generate() progress ticks from the host. */
143
+ const AI_GENERATE_PROGRESS_STREAM = "_ai_generate_progress"
144
+
145
+ /** LLM calls take far longer than the 60s default request timeout. */
146
+ const AI_REQUEST_TIMEOUT_MS = 120_000
147
+ /** Generation runs an agentic loop server-side (~150s wall-clock budget). */
148
+ const AI_GENERATE_TIMEOUT_MS = 180_000
149
+
150
+ /** Request for one agentic visual-generation run. One shot — no conversation. */
151
+ export interface AiGenerateRequest {
152
+ /** The task. Include any data and display constraints the artist needs. */
153
+ prompt: string
154
+ /** Extra system guidance appended to the platform's base artist prompt. */
155
+ system?: string
156
+ /** Provider-specific model id. Omit for the platform's generate default. */
157
+ model?: string
158
+ maxTokens?: number
159
+ /** Agentic round budget; the platform clamps to its own ceiling. */
160
+ maxRounds?: number
161
+ }
162
+
163
+ /**
164
+ * A coarse progress tick from a running generate() call. `activity` is one of
165
+ * "thinking" | "searching" | "drawing" | "finishing" today, but treat unknown
166
+ * values as "thinking" — the platform may refine labels without a new SDK.
167
+ */
168
+ export interface AiGenerateProgress {
169
+ activity: string
170
+ }
171
+
172
+ /** One rendered image, ready for `session.display.render`-style consumption. */
173
+ export interface AiGeneratedImage {
174
+ /** Base64 image bytes (no data: prefix). */
175
+ data: string
176
+ mimeType: string
177
+ width?: number
178
+ height?: number
179
+ }
180
+
181
+ export interface AiGenerateResult {
182
+ /** Final text (caption/answer). May be empty if the model only drew. */
183
+ text: string
184
+ images: AiGeneratedImage[]
185
+ stopReason: AiStopReason
186
+ usage: AiUsage & {rounds: number}
187
+ provider: AiProvider
188
+ model: string
189
+ billedToUserKey: boolean
190
+ }
191
+
192
+ export class AiModule {
193
+ constructor(private readonly session: MiniappSession) {}
194
+
195
+ /** True iff `AI` is declared in the miniapp's manifest. */
196
+ get hasPermission(): boolean {
197
+ return this.session._hasManifestPermission("AI")
198
+ }
199
+
200
+ /**
201
+ * Run one completion turn.
202
+ *
203
+ * For a tool loop: call, and if `stopReason === "tool_use"`, append an
204
+ * assistant turn carrying `toolCalls` plus a user turn carrying your
205
+ * `toolResults`, then call again. Bound your own loop — the platform holds no
206
+ * conversation state, so nothing else will stop a runaway.
207
+ */
208
+ async complete(request: AiCompleteRequest): Promise<AiCompleteResult> {
209
+ return this.session.sendRequest<AiCompleteResult>(
210
+ {type: MiniappRequestType.AI_COMPLETE, ...request},
211
+ {timeoutMs: AI_REQUEST_TIMEOUT_MS},
212
+ )
213
+ }
214
+
215
+ /**
216
+ * Run one agentic visual-generation call. The cloud drives a provider loop
217
+ * with server-side web search + code execution and returns text plus any
218
+ * rendered images. Expect tens of seconds of latency — show progress UI.
219
+ * Rejects with QUOTA_EXCEEDED when the account's AI credit is spent, and
220
+ * with INTERNAL naming an HTTP status when the host predates this request
221
+ * type or the cloud has the surface disabled.
222
+ *
223
+ * `onProgress` receives coarse activity ticks ("searching", "drawing", …)
224
+ * while the run is in flight, so a caller can keep a wait card honest.
225
+ * Best-effort: hosts/clouds that predate the progress surface complete the
226
+ * call normally and just never tick.
227
+ */
228
+ async generate(
229
+ request: AiGenerateRequest,
230
+ opts: {onProgress?: (progress: AiGenerateProgress) => void} = {},
231
+ ): Promise<AiGenerateResult> {
232
+ const onProgress = opts.onProgress
233
+ if (!onProgress) {
234
+ return this.session.sendRequest<AiGenerateResult>(
235
+ {type: MiniappRequestType.AI_GENERATE, ...request},
236
+ {timeoutMs: AI_GENERATE_TIMEOUT_MS},
237
+ )
238
+ }
239
+
240
+ // Correlate progress events to THIS call via a caller-minted token the
241
+ // host echoes back on the internal `_ai_generate_progress` stream —
242
+ // internal streams ride the local fan-out and never hit SUBSCRIBE.
243
+ const progressToken = `gen-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`
244
+ const unsubscribe = this.session.events.subscribe(AI_GENERATE_PROGRESS_STREAM, (data) => {
245
+ const tick = data as {progressToken?: string; activity?: string} | undefined
246
+ if (tick?.progressToken !== progressToken || typeof tick.activity !== "string") return
247
+ try {
248
+ onProgress({activity: tick.activity})
249
+ } catch {
250
+ // A throwing listener must not break the generation promise chain.
251
+ }
252
+ })
253
+ try {
254
+ return await this.session.sendRequest<AiGenerateResult>(
255
+ {type: MiniappRequestType.AI_GENERATE, ...request, progressToken},
256
+ {timeoutMs: AI_GENERATE_TIMEOUT_MS},
257
+ )
258
+ } finally {
259
+ unsubscribe()
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Convenience for the common single-shot case: one prompt in, text out.
265
+ * Throws when the model refused, so callers that just want a string don't
266
+ * have to remember that a refusal arrives as a success.
267
+ */
268
+ async prompt(
269
+ prompt: string,
270
+ opts: {system?: string; maxTokens?: number; jsonMode?: boolean; tier?: AiTier} = {},
271
+ ): Promise<string> {
272
+ const result = await this.complete({
273
+ messages: [{role: "user", content: prompt}],
274
+ ...opts,
275
+ })
276
+ if (result.stopReason === "refusal") {
277
+ throw new Error("the model declined to answer this prompt")
278
+ }
279
+ return result.text
280
+ }
281
+ }