@threadbase-sh/streamer 1.63.0 → 1.65.0

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 (300) hide show
  1. package/dist/agent/agent-client.d.ts +14 -0
  2. package/dist/agent/agent-client.d.ts.map +1 -0
  3. package/dist/agent/agent-config.d.ts +24 -0
  4. package/dist/agent/agent-config.d.ts.map +1 -0
  5. package/dist/agent/conversation-writer.d.ts +13 -0
  6. package/dist/agent/conversation-writer.d.ts.map +1 -0
  7. package/dist/agent/dedupe.d.ts +6 -0
  8. package/dist/agent/dedupe.d.ts.map +1 -0
  9. package/dist/agent/errors.d.ts +23 -0
  10. package/dist/agent/errors.d.ts.map +1 -0
  11. package/dist/agent/handle-send-agent-input.d.ts +21 -0
  12. package/dist/agent/handle-send-agent-input.d.ts.map +1 -0
  13. package/dist/agent/handle-start-agent-session.d.ts +21 -0
  14. package/dist/agent/handle-start-agent-session.d.ts.map +1 -0
  15. package/dist/agent/history-mapper.d.ts +4 -0
  16. package/dist/agent/history-mapper.d.ts.map +1 -0
  17. package/dist/agent/payload-guard.d.ts +29 -0
  18. package/dist/agent/payload-guard.d.ts.map +1 -0
  19. package/dist/api/app.d.ts +28 -0
  20. package/dist/api/app.d.ts.map +1 -0
  21. package/dist/api/handlers/conversations.handlers.d.ts +69 -0
  22. package/dist/api/handlers/conversations.handlers.d.ts.map +1 -0
  23. package/dist/api/handlers/http-helpers.d.ts +50 -0
  24. package/dist/api/handlers/http-helpers.d.ts.map +1 -0
  25. package/dist/api/handlers/sessions.handlers.d.ts +236 -0
  26. package/dist/api/handlers/sessions.handlers.d.ts.map +1 -0
  27. package/dist/api/middleware/auth.middleware.d.ts +5 -0
  28. package/dist/api/middleware/auth.middleware.d.ts.map +1 -0
  29. package/dist/api/middleware/cors.middleware.d.ts +5 -0
  30. package/dist/api/middleware/cors.middleware.d.ts.map +1 -0
  31. package/dist/api/middleware/error.middleware.d.ts +4 -0
  32. package/dist/api/middleware/error.middleware.d.ts.map +1 -0
  33. package/dist/api/routes/backup.routes.d.ts +5 -0
  34. package/dist/api/routes/backup.routes.d.ts.map +1 -0
  35. package/dist/api/routes/browse.routes.d.ts +5 -0
  36. package/dist/api/routes/browse.routes.d.ts.map +1 -0
  37. package/dist/api/routes/cacheAlert.routes.d.ts +5 -0
  38. package/dist/api/routes/cacheAlert.routes.d.ts.map +1 -0
  39. package/dist/api/routes/config.routes.d.ts +5 -0
  40. package/dist/api/routes/config.routes.d.ts.map +1 -0
  41. package/dist/api/routes/conversations.routes.d.ts +5 -0
  42. package/dist/api/routes/conversations.routes.d.ts.map +1 -0
  43. package/dist/api/routes/devices.routes.d.ts +17 -0
  44. package/dist/api/routes/devices.routes.d.ts.map +1 -0
  45. package/dist/api/routes/diagnostics.routes.d.ts +5 -0
  46. package/dist/api/routes/diagnostics.routes.d.ts.map +1 -0
  47. package/dist/api/routes/health.routes.d.ts +5 -0
  48. package/dist/api/routes/health.routes.d.ts.map +1 -0
  49. package/dist/api/routes/logs.routes.d.ts +3 -0
  50. package/dist/api/routes/logs.routes.d.ts.map +1 -0
  51. package/dist/api/routes/misc.routes.d.ts +77 -0
  52. package/dist/api/routes/misc.routes.d.ts.map +1 -0
  53. package/dist/api/routes/pair.routes.d.ts +5 -0
  54. package/dist/api/routes/pair.routes.d.ts.map +1 -0
  55. package/dist/api/routes/progress.routes.d.ts +39 -0
  56. package/dist/api/routes/progress.routes.d.ts.map +1 -0
  57. package/dist/api/routes/projects.routes.d.ts +5 -0
  58. package/dist/api/routes/projects.routes.d.ts.map +1 -0
  59. package/dist/api/routes/providers.routes.d.ts +19 -0
  60. package/dist/api/routes/providers.routes.d.ts.map +1 -0
  61. package/dist/api/routes/scanner.routes.d.ts +5 -0
  62. package/dist/api/routes/scanner.routes.d.ts.map +1 -0
  63. package/dist/api/routes/sessions.routes.d.ts +6 -0
  64. package/dist/api/routes/sessions.routes.d.ts.map +1 -0
  65. package/dist/api/routes/ws.routes.d.ts +7 -0
  66. package/dist/api/routes/ws.routes.d.ts.map +1 -0
  67. package/dist/api/types/api-deps.d.ts +114 -0
  68. package/dist/api/types/api-deps.d.ts.map +1 -0
  69. package/dist/auth.d.ts +81 -0
  70. package/dist/auth.d.ts.map +1 -0
  71. package/dist/browse.d.ts +17 -0
  72. package/dist/browse.d.ts.map +1 -0
  73. package/dist/claude-flags.d.ts +76 -0
  74. package/dist/claude-flags.d.ts.map +1 -0
  75. package/dist/cli.cjs +121 -7
  76. package/dist/cli.cjs.map +1 -1
  77. package/dist/codex-pty-runner.d.ts +90 -0
  78. package/dist/codex-pty-runner.d.ts.map +1 -0
  79. package/dist/config/update-config.d.ts +13 -0
  80. package/dist/config/update-config.d.ts.map +1 -0
  81. package/dist/conversation-cache.d.ts +336 -0
  82. package/dist/conversation-cache.d.ts.map +1 -0
  83. package/dist/db/config.d.ts +11 -0
  84. package/dist/db/config.d.ts.map +1 -0
  85. package/dist/db/index.d.ts +5 -0
  86. package/dist/db/index.d.ts.map +1 -0
  87. package/dist/db/migrations.d.ts +3 -0
  88. package/dist/db/migrations.d.ts.map +1 -0
  89. package/dist/db/pool.d.ts +5 -0
  90. package/dist/db/pool.d.ts.map +1 -0
  91. package/dist/db/query-timing.d.ts +52 -0
  92. package/dist/db/query-timing.d.ts.map +1 -0
  93. package/dist/db/repositories/cacheMetadata.repository.d.ts +12 -0
  94. package/dist/db/repositories/cacheMetadata.repository.d.ts.map +1 -0
  95. package/dist/db/repositories/conversations.repository.d.ts +27 -0
  96. package/dist/db/repositories/conversations.repository.d.ts.map +1 -0
  97. package/dist/db/repositories/devices.repository.d.ts +137 -0
  98. package/dist/db/repositories/devices.repository.d.ts.map +1 -0
  99. package/dist/db/repositories/managed-sessions.repository.d.ts +127 -0
  100. package/dist/db/repositories/managed-sessions.repository.d.ts.map +1 -0
  101. package/dist/db/repositories/projects.repository.d.ts +28 -0
  102. package/dist/db/repositories/projects.repository.d.ts.map +1 -0
  103. package/dist/db/repositories/push.repository.d.ts +186 -0
  104. package/dist/db/repositories/push.repository.d.ts.map +1 -0
  105. package/dist/db/repositories/sessions.repository.d.ts +16 -0
  106. package/dist/db/repositories/sessions.repository.d.ts.map +1 -0
  107. package/dist/db/runtime-store.d.ts +80 -0
  108. package/dist/db/runtime-store.d.ts.map +1 -0
  109. package/dist/db/sqlite-migrate.d.ts +13 -0
  110. package/dist/db/sqlite-migrate.d.ts.map +1 -0
  111. package/dist/db/upload-records.d.ts +11 -0
  112. package/dist/db/upload-records.d.ts.map +1 -0
  113. package/dist/e2ee/noise.d.ts +261 -0
  114. package/dist/e2ee/noise.d.ts.map +1 -0
  115. package/dist/e2ee/pair-payload.d.ts +60 -0
  116. package/dist/e2ee/pair-payload.d.ts.map +1 -0
  117. package/dist/e2ee/pair-request.d.ts +24 -0
  118. package/dist/e2ee/pair-request.d.ts.map +1 -0
  119. package/dist/external-tails.d.ts +91 -0
  120. package/dist/external-tails.d.ts.map +1 -0
  121. package/dist/feature-flags.d.ts +212 -0
  122. package/dist/feature-flags.d.ts.map +1 -0
  123. package/dist/handlers/handleListProjects.d.ts +3 -0
  124. package/dist/handlers/handleListProjects.d.ts.map +1 -0
  125. package/dist/index.cjs +101 -2
  126. package/dist/index.cjs.map +1 -1
  127. package/dist/index.d.ts +18 -2571
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +101 -2
  130. package/dist/index.js.map +1 -1
  131. package/dist/lifecycle/constants.d.ts +21 -0
  132. package/dist/lifecycle/constants.d.ts.map +1 -0
  133. package/dist/lifecycle/process-liveness.d.ts +7 -0
  134. package/dist/lifecycle/process-liveness.d.ts.map +1 -0
  135. package/dist/live-session-manager.d.ts +59 -0
  136. package/dist/live-session-manager.d.ts.map +1 -0
  137. package/dist/logger.d.ts +14 -0
  138. package/dist/logger.d.ts.map +1 -0
  139. package/dist/pair-store.d.ts +60 -0
  140. package/dist/pair-store.d.ts.map +1 -0
  141. package/dist/platform.d.ts +25 -0
  142. package/dist/platform.d.ts.map +1 -0
  143. package/dist/process-discovery.d.ts +35 -0
  144. package/dist/process-discovery.d.ts.map +1 -0
  145. package/dist/providers.d.ts +7 -0
  146. package/dist/providers.d.ts.map +1 -0
  147. package/dist/pty-host/protocol.d.ts +270 -0
  148. package/dist/pty-host/protocol.d.ts.map +1 -0
  149. package/dist/pty-host/remote-session-runner.d.ts +133 -0
  150. package/dist/pty-host/remote-session-runner.d.ts.map +1 -0
  151. package/dist/pty-host/socket.d.ts +54 -0
  152. package/dist/pty-host/socket.d.ts.map +1 -0
  153. package/dist/pty-host/spawn-host.d.ts +30 -0
  154. package/dist/pty-host/spawn-host.d.ts.map +1 -0
  155. package/dist/pty-manager.d.ts +65 -0
  156. package/dist/pty-manager.d.ts.map +1 -0
  157. package/dist/pty-shared.d.ts +27 -0
  158. package/dist/pty-shared.d.ts.map +1 -0
  159. package/dist/scanner-manager.d.ts +126 -0
  160. package/dist/scanner-manager.d.ts.map +1 -0
  161. package/dist/schemas/cacheAlert.schema.d.ts +14 -0
  162. package/dist/schemas/cacheAlert.schema.d.ts.map +1 -0
  163. package/dist/schemas/claudeFlags.schema.d.ts +7 -0
  164. package/dist/schemas/claudeFlags.schema.d.ts.map +1 -0
  165. package/dist/schemas/project.schema.d.ts +18 -0
  166. package/dist/schemas/project.schema.d.ts.map +1 -0
  167. package/dist/schemas/updateConfig.schema.d.ts +19 -0
  168. package/dist/schemas/updateConfig.schema.d.ts.map +1 -0
  169. package/dist/seal.d.ts +14 -0
  170. package/dist/seal.d.ts.map +1 -0
  171. package/dist/server-identity.d.ts +43 -0
  172. package/dist/server-identity.d.ts.map +1 -0
  173. package/dist/server-wiring.d.ts +189 -0
  174. package/dist/server-wiring.d.ts.map +1 -0
  175. package/dist/server.d.ts +404 -0
  176. package/dist/server.d.ts.map +1 -0
  177. package/dist/services/backup/backup.d.ts +103 -0
  178. package/dist/services/backup/backup.d.ts.map +1 -0
  179. package/dist/services/cache/cacheMetadata.d.ts +8 -0
  180. package/dist/services/cache/cacheMetadata.d.ts.map +1 -0
  181. package/dist/services/cache-integrity/alertStore.d.ts +24 -0
  182. package/dist/services/cache-integrity/alertStore.d.ts.map +1 -0
  183. package/dist/services/cache-integrity/backup.d.ts +8 -0
  184. package/dist/services/cache-integrity/backup.d.ts.map +1 -0
  185. package/dist/services/cache-integrity/cacheIntegrityMonitor.d.ts +71 -0
  186. package/dist/services/cache-integrity/cacheIntegrityMonitor.d.ts.map +1 -0
  187. package/dist/services/conversations/conversationWatcher.d.ts +99 -0
  188. package/dist/services/conversations/conversationWatcher.d.ts.map +1 -0
  189. package/dist/services/conversations/findSearchTarget.d.ts +30 -0
  190. package/dist/services/conversations/findSearchTarget.d.ts.map +1 -0
  191. package/dist/services/conversations/isAgentConversation.d.ts +8 -0
  192. package/dist/services/conversations/isAgentConversation.d.ts.map +1 -0
  193. package/dist/services/conversations/pruneAgentConversations.d.ts +8 -0
  194. package/dist/services/conversations/pruneAgentConversations.d.ts.map +1 -0
  195. package/dist/services/conversations/refreshConversationCache.d.ts +27 -0
  196. package/dist/services/conversations/refreshConversationCache.d.ts.map +1 -0
  197. package/dist/services/conversations/shouldRefreshProjectsFromHdd.d.ts +33 -0
  198. package/dist/services/conversations/shouldRefreshProjectsFromHdd.d.ts.map +1 -0
  199. package/dist/services/diagnostics/diagnostics.d.ts +66 -0
  200. package/dist/services/diagnostics/diagnostics.d.ts.map +1 -0
  201. package/dist/services/projectChats/deriveProjectChatTitle.d.ts +15 -0
  202. package/dist/services/projectChats/deriveProjectChatTitle.d.ts.map +1 -0
  203. package/dist/services/projects/ensureProjectsForConversations.d.ts +15 -0
  204. package/dist/services/projects/ensureProjectsForConversations.d.ts.map +1 -0
  205. package/dist/services/providers/capabilities.d.ts +105 -0
  206. package/dist/services/providers/capabilities.d.ts.map +1 -0
  207. package/dist/services/providers/providerHealth.d.ts +72 -0
  208. package/dist/services/providers/providerHealth.d.ts.map +1 -0
  209. package/dist/services/push/apnsClient.d.ts +105 -0
  210. package/dist/services/push/apnsClient.d.ts.map +1 -0
  211. package/dist/services/push/expoPushSender.d.ts +37 -0
  212. package/dist/services/push/expoPushSender.d.ts.map +1 -0
  213. package/dist/services/push/liveActivityContentState.d.ts +60 -0
  214. package/dist/services/push/liveActivityContentState.d.ts.map +1 -0
  215. package/dist/services/push/liveActivityNotifier.d.ts +49 -0
  216. package/dist/services/push/liveActivityNotifier.d.ts.map +1 -0
  217. package/dist/services/push/liveActivityRenewal.d.ts +63 -0
  218. package/dist/services/push/liveActivityRenewal.d.ts.map +1 -0
  219. package/dist/services/push/liveActivitySender.d.ts +88 -0
  220. package/dist/services/push/liveActivitySender.d.ts.map +1 -0
  221. package/dist/services/push/waitingInputNotifier.d.ts +41 -0
  222. package/dist/services/push/waitingInputNotifier.d.ts.map +1 -0
  223. package/dist/services/questions/answersToKeystrokes.d.ts +8 -0
  224. package/dist/services/questions/answersToKeystrokes.d.ts.map +1 -0
  225. package/dist/services/questions/codexGateAnswers.d.ts +14 -0
  226. package/dist/services/questions/codexGateAnswers.d.ts.map +1 -0
  227. package/dist/services/questions/codexScreen.d.ts +74 -0
  228. package/dist/services/questions/codexScreen.d.ts.map +1 -0
  229. package/dist/services/questions/detectAskUserQuestion.d.ts +6 -0
  230. package/dist/services/questions/detectAskUserQuestion.d.ts.map +1 -0
  231. package/dist/services/questions/detectPermissionGate.d.ts +62 -0
  232. package/dist/services/questions/detectPermissionGate.d.ts.map +1 -0
  233. package/dist/services/questions/detectQuestionFromScreen.d.ts +30 -0
  234. package/dist/services/questions/detectQuestionFromScreen.d.ts.map +1 -0
  235. package/dist/services/questions/detectShellPrompt.d.ts +18 -0
  236. package/dist/services/questions/detectShellPrompt.d.ts.map +1 -0
  237. package/dist/services/questions/parseAgentPhase.d.ts +12 -0
  238. package/dist/services/questions/parseAgentPhase.d.ts.map +1 -0
  239. package/dist/services/questions/parseStatusLine.d.ts +19 -0
  240. package/dist/services/questions/parseStatusLine.d.ts.map +1 -0
  241. package/dist/services/questions/questionBroadcast.d.ts +18 -0
  242. package/dist/services/questions/questionBroadcast.d.ts.map +1 -0
  243. package/dist/services/questions/resolveAnswer.d.ts +16 -0
  244. package/dist/services/questions/resolveAnswer.d.ts.map +1 -0
  245. package/dist/services/search/searchQuery.d.ts +78 -0
  246. package/dist/services/search/searchQuery.d.ts.map +1 -0
  247. package/dist/services/security/capabilities.d.ts +50 -0
  248. package/dist/services/security/capabilities.d.ts.map +1 -0
  249. package/dist/services/sessions/autoResumeOnBoot.d.ts +28 -0
  250. package/dist/services/sessions/autoResumeOnBoot.d.ts.map +1 -0
  251. package/dist/services/sessions/codexRolloutOwner.d.ts +55 -0
  252. package/dist/services/sessions/codexRolloutOwner.d.ts.map +1 -0
  253. package/dist/services/sessions/conversationBusy.d.ts +32 -0
  254. package/dist/services/sessions/conversationBusy.d.ts.map +1 -0
  255. package/dist/services/sessions/idempotency.d.ts +67 -0
  256. package/dist/services/sessions/idempotency.d.ts.map +1 -0
  257. package/dist/services/sessions/reconcileSessions.d.ts +63 -0
  258. package/dist/services/sessions/reconcileSessions.d.ts.map +1 -0
  259. package/dist/services/sessions/rehydrateSessions.d.ts +68 -0
  260. package/dist/services/sessions/rehydrateSessions.d.ts.map +1 -0
  261. package/dist/services/sessions/resumeIdentity.d.ts +16 -0
  262. package/dist/services/sessions/resumeIdentity.d.ts.map +1 -0
  263. package/dist/session-registry-boot.d.ts +142 -0
  264. package/dist/session-registry-boot.d.ts.map +1 -0
  265. package/dist/session-store.d.ts +32 -0
  266. package/dist/session-store.d.ts.map +1 -0
  267. package/dist/session-watchers.d.ts +60 -0
  268. package/dist/session-watchers.d.ts.map +1 -0
  269. package/dist/types.d.ts +616 -0
  270. package/dist/types.d.ts.map +1 -0
  271. package/dist/uploads.d.ts +16 -0
  272. package/dist/uploads.d.ts.map +1 -0
  273. package/dist/utils/bootToken.d.ts +3 -0
  274. package/dist/utils/bootToken.d.ts.map +1 -0
  275. package/dist/utils/canonicalizeFilePath.d.ts +75 -0
  276. package/dist/utils/canonicalizeFilePath.d.ts.map +1 -0
  277. package/dist/utils/canonicalizeProjectPath.d.ts +13 -0
  278. package/dist/utils/canonicalizeProjectPath.d.ts.map +1 -0
  279. package/dist/utils/codexConversationLine.d.ts +38 -0
  280. package/dist/utils/codexConversationLine.d.ts.map +1 -0
  281. package/dist/utils/conversationEtag.d.ts +19 -0
  282. package/dist/utils/conversationEtag.d.ts.map +1 -0
  283. package/dist/utils/dates.d.ts +12 -0
  284. package/dist/utils/dates.d.ts.map +1 -0
  285. package/dist/utils/debounce.d.ts +15 -0
  286. package/dist/utils/debounce.d.ts.map +1 -0
  287. package/dist/utils/deriveSessionName.d.ts +10 -0
  288. package/dist/utils/deriveSessionName.d.ts.map +1 -0
  289. package/dist/utils/fileIdentity.d.ts +36 -0
  290. package/dist/utils/fileIdentity.d.ts.map +1 -0
  291. package/dist/utils/isScannedSnapshotStale.d.ts +16 -0
  292. package/dist/utils/isScannedSnapshotStale.d.ts.map +1 -0
  293. package/dist/utils/scanProgressThrottle.d.ts +12 -0
  294. package/dist/utils/scanProgressThrottle.d.ts.map +1 -0
  295. package/dist/version.d.ts +3 -0
  296. package/dist/version.d.ts.map +1 -0
  297. package/dist/ws-hub.d.ts +15 -0
  298. package/dist/ws-hub.d.ts.map +1 -0
  299. package/package.json +3 -4
  300. package/dist/index.d.cts +0 -2571
@@ -0,0 +1,105 @@
1
+ import { type ProviderName } from "../../providers";
2
+ /**
3
+ * Provider capability declarations (C2).
4
+ * See docs/architecture/2026-07-24-provider-compatibility.md.
5
+ *
6
+ * Every field here is a branch that ALREADY exists somewhere in the codebase —
7
+ * this promotes it from an implied code path to queryable data. The point is
8
+ * that a client can ask what a provider supports instead of discovering it by
9
+ * attempting an action and getting a 501 or a silently wrong result.
10
+ */
11
+ export interface ProviderCapabilities {
12
+ /**
13
+ * How a fresh session gets its id.
14
+ * `explicit` — we generate it and pass it in (Claude: `--session-id <uuid>`).
15
+ * `late-bound` — the CLI creates its own and we discover it afterwards
16
+ * (Codex: no `--session-id` equivalent, so the rollout id is
17
+ * found by watching the sessions dir after spawn).
18
+ */
19
+ freshSessionId: "explicit" | "late-bound";
20
+ /** Whether the CLI can replay a prior transcript from an id. */
21
+ resume: "native" | "unsupported";
22
+ /**
23
+ * How a system prompt reaches the CLI.
24
+ * `flag` — a dedicated flag (Claude: `--system-prompt`).
25
+ * `positional` — passed as the opening turn (Codex has no flag).
26
+ */
27
+ systemPrompt: "flag" | "positional" | "unsupported";
28
+ /** We can detect and parse structured question menus from the TUI. */
29
+ structuredQuestions: boolean;
30
+ /** We can detect permission/trust gates and answer them programmatically. */
31
+ permissionGates: boolean;
32
+ /**
33
+ * We can send input to a live session. False means read-only observation —
34
+ * the honest state for a provider whose input path we do not understand.
35
+ */
36
+ liveControl: boolean;
37
+ }
38
+ /**
39
+ * Provider versions an adapter's parsing and detection were captured against.
40
+ *
41
+ * `captured` lists the versions we hold fixtures for. `min`/`max` bound the
42
+ * range we claim to support. A provider outside that range still runs — it just
43
+ * reports a compatibility warning rather than pretending to be verified.
44
+ */
45
+ export interface VerifiedAgainst {
46
+ min?: string;
47
+ max?: string;
48
+ captured: string[];
49
+ }
50
+ /**
51
+ * Outcome of normalizing one native-history line.
52
+ *
53
+ * The `ignored` / `unknown` split is the reason this type exists. Today every
54
+ * non-chat line returns null (src/utils/codexConversationLine.ts), so "a
55
+ * session_meta header we deliberately skip" and "a shape this adapter has never
56
+ * seen" are indistinguishable — and a provider schema change therefore renders
57
+ * an empty conversation with no error at all.
58
+ */
59
+ export type NormalizeResult =
60
+ /** Recognized chat content, normalized to the client-facing shape. */
61
+ {
62
+ kind: "message";
63
+ line: string;
64
+ }
65
+ /** Recognized, but deliberately not rendered (headers, dupes, injected context). */
66
+ | {
67
+ kind: "ignored";
68
+ reason: string;
69
+ }
70
+ /** NOT recognized. Counted and surfaced as a compatibility signal. */
71
+ | {
72
+ kind: "unknown";
73
+ raw: string;
74
+ reason: string;
75
+ };
76
+ /**
77
+ * The descriptive half of a provider integration. `SessionRunner` (types.ts) is
78
+ * the behavioural half — how to spawn and drive the CLI. This is what the
79
+ * integration claims about itself, so adding a provider means implementing a
80
+ * declared surface rather than copying a runner and hoping.
81
+ */
82
+ export interface ProviderAdapter {
83
+ name: ProviderName;
84
+ capabilities: ProviderCapabilities;
85
+ verifiedAgainst: VerifiedAgainst;
86
+ /** Installed provider version, or null when it cannot be determined. */
87
+ detectVersion(): Promise<string | null>;
88
+ /** Classify one raw native-history line. Never silently discards. */
89
+ normalizeLine(line: string): NormalizeResult;
90
+ }
91
+ export declare const CLAUDE_CODE_CAPABILITIES: ProviderCapabilities;
92
+ export declare const CODEX_CLI_CAPABILITIES: ProviderCapabilities;
93
+ /**
94
+ * Capabilities for a provider we do not recognize.
95
+ *
96
+ * This is the generic-terminal fallback: stream bytes, accept input, and claim
97
+ * no semantic understanding. It exists because the current behaviour is worse —
98
+ * `coerceProviderForRunner` (providers.ts) silently maps an unknown provider to
99
+ * claude-code, so an unrecognized CLI gets driven with Claude's argv, Claude's
100
+ * markers, and Claude's env scrubbing. Admitting we don't know beats asserting
101
+ * the wrong thing.
102
+ */
103
+ export declare const GENERIC_TERMINAL_CAPABILITIES: ProviderCapabilities;
104
+ export declare function capabilitiesFor(provider: ProviderName): ProviderCapabilities;
105
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/services/providers/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE9F;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;OAMG;IACH,cAAc,EAAE,UAAU,GAAG,YAAY,CAAC;IAC1C,gEAAgE;IAChE,MAAM,EAAE,QAAQ,GAAG,aAAa,CAAC;IACjC;;;;OAIG;IACH,YAAY,EAAE,MAAM,GAAG,YAAY,GAAG,aAAa,CAAC;IACpD,sEAAsE;IACtE,mBAAmB,EAAE,OAAO,CAAC;IAC7B,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe;AACzB,sEAAsE;AACpE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACnC,oFAAoF;GAClF;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACrC,sEAAsE;GACpE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,oBAAoB,CAAC;IACnC,eAAe,EAAE,eAAe,CAAC;IACjC,wEAAwE;IACxE,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxC,qEAAqE;IACrE,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAC;CAC9C;AAaD,eAAO,MAAM,wBAAwB,EAAE,oBAOtC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,oBAOpC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,EAAE,oBAO3C,CAAC;AAEF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,oBAAoB,CAO5E"}
@@ -0,0 +1,72 @@
1
+ import { type ProviderName } from "../../providers";
2
+ import { type ProviderCapabilities, type VerifiedAgainst } from "./capabilities";
3
+ /**
4
+ * Provider version detection and compatibility reporting (C2).
5
+ * See docs/architecture/2026-07-24-provider-compatibility.md.
6
+ *
7
+ * Our parsing and TUI detection are calibrated against specific provider
8
+ * versions — the fixtures under __tests__/fixtures/providers/<provider>/<version>
9
+ * record which. This module compares what is actually installed against that,
10
+ * so drift is reported instead of surfacing as a mysteriously stuck session.
11
+ *
12
+ * A warning is never a refusal. A provider working slightly outside our verified
13
+ * range is vastly better than us blocking it.
14
+ */
15
+ /** Versions each adapter's fixtures were captured against. */
16
+ export declare const VERIFIED_AGAINST: Record<ProviderName, VerifiedAgainst>;
17
+ export type ProviderWarningCode =
18
+ /** The CLI is not installed, or not on PATH. */
19
+ "provider_not_found"
20
+ /** Installed, but we could not read a version from it. */
21
+ | "version_undetectable"
22
+ /** Installed and readable, but outside the range our fixtures cover. */
23
+ | "version_unverified";
24
+ export interface ProviderWarning {
25
+ code: ProviderWarningCode;
26
+ message: string;
27
+ }
28
+ export interface ProviderHealth {
29
+ name: ProviderName;
30
+ available: boolean;
31
+ version: string | null;
32
+ verifiedAgainst: VerifiedAgainst;
33
+ capabilities: ProviderCapabilities;
34
+ warnings: ProviderWarning[];
35
+ }
36
+ /**
37
+ * Run `<exe> --version` and return the first version-looking token.
38
+ *
39
+ * Deliberately tolerant: providers format this line differently and change it
40
+ * between releases, so we scrape a semver-shaped substring rather than assume a
41
+ * layout. Any failure yields null, which the caller treats as "unverified"
42
+ * rather than "incompatible" — an unreadable version is not evidence of a
43
+ * problem with the provider.
44
+ */
45
+ export declare function parseVersionOutput(output: string): string | null;
46
+ /**
47
+ * Compare a detected version against the range an adapter claims to cover.
48
+ *
49
+ * Only `min` is enforced as a floor. There is deliberately no upper bound check
50
+ * beyond `max` when set: providers release constantly, and refusing to run
51
+ * against a version merely newer than our newest fixture would break users on
52
+ * every provider update for no evidence of an actual incompatibility.
53
+ */
54
+ export declare function compareToVerified(version: string | null, verified: VerifiedAgainst): ProviderWarning | null;
55
+ /**
56
+ * Compare two semver-ish strings. Prerelease suffixes sort BELOW the same
57
+ * release (0.140.0-alpha.19 < 0.140.0), matching semver, so a prerelease we
58
+ * captured does not read as newer than the release it precedes.
59
+ */
60
+ export declare function compareSemver(a: string, b: string): number;
61
+ /**
62
+ * Resolve health for one provider. `locateExe` is injected so tests can drive
63
+ * detection without depending on what happens to be installed on the machine;
64
+ * it defaults to the same `locateProviderExe` the session-start pre-flight
65
+ * uses. Sharing that one entry point is load-bearing rather than tidy: it
66
+ * clears the memoized resolution on a miss, so a health check and a start
67
+ * attempt cannot reach opposite conclusions about the same machine — which is
68
+ * what happened when this called `locateExecutable(resolveExe())` directly and
69
+ * left a stale absolute path (the normal case under launchd) in place.
70
+ */
71
+ export declare function providerHealth(name: ProviderName, locateExe?: () => string | null, detect?: (exe: string) => Promise<string | null>): Promise<ProviderHealth>;
72
+ //# sourceMappingURL=providerHealth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerHealth.d.ts","sourceRoot":"","sources":["../../../src/services/providers/providerHealth.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4C,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,EAAmB,KAAK,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAElG;;;;;;;;;;;GAWG;AAEH,8DAA8D;AAC9D,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,YAAY,EAAE,eAAe,CAGlE,CAAC;AAEF,MAAM,MAAM,mBAAmB;AAC7B,gDAAgD;AAC9C,oBAAoB;AACtB,0DAA0D;GACxD,sBAAsB;AACxB,wEAAwE;GACtE,oBAAoB,CAAC;AAEzB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,EAAE,oBAAoB,CAAC;IACnC,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAID;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGhE;AA+CD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,QAAQ,EAAE,eAAe,GACxB,eAAe,GAAG,IAAI,CAyBxB;AAMD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB1D;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,YAAY,EAClB,SAAS,GAAE,MAAM,MAAM,GAAG,IAAoC,EAC9D,MAAM,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAc,GAC3D,OAAO,CAAC,cAAc,CAAC,CAqDzB"}
@@ -0,0 +1,105 @@
1
+ /** Sandbox default: the app's `aps-environment` is still `development`. */
2
+ export declare const APNS_HOST_SANDBOX = "api.sandbox.push.apple.com";
3
+ export declare const APNS_HOST_PRODUCTION = "api.push.apple.com";
4
+ /**
5
+ * APNs rejects a payload over 4 KB.
6
+ *
7
+ * Checked before sending rather than after a rejection, so an oversized payload
8
+ * is a diagnosable local error instead of an opaque 413 from Apple.
9
+ */
10
+ export declare const APNS_MAX_PAYLOAD_BYTES = 4096;
11
+ export interface ApnsCredentials {
12
+ /** p8 PEM contents. Never a filesystem path. */
13
+ key: string;
14
+ keyId: string;
15
+ teamId: string;
16
+ bundleId: string;
17
+ host: string;
18
+ }
19
+ export interface ApnsSendResult {
20
+ ok: boolean;
21
+ status: number;
22
+ /** APNs `reason`, e.g. `BadDeviceToken` / `ExpiredToken`. */
23
+ reason?: string;
24
+ /**
25
+ * True when APNs says this token will never work again. The caller must stop
26
+ * using it rather than retrying — retrying a dead token fails forever and
27
+ * makes the health report read "failing" instead of "this device is gone".
28
+ */
29
+ tokenDead: boolean;
30
+ }
31
+ /**
32
+ * Read APNs credentials from the environment.
33
+ *
34
+ * Returns null when `APNS_KEY` is absent, which is the normal case for a
35
+ * developer machine and for CI. Callers treat null as "Live Activity push is
36
+ * off" and skip sending — the server must not fail to boot because an optional
37
+ * push credential is missing.
38
+ *
39
+ * Every identifier comes from the environment with no default. Baking one
40
+ * deployment's Apple account into the source would make this package silently
41
+ * sign for the wrong team when someone else deploys it, and the resulting APNs
42
+ * rejection names none of that. Only the host has a default, because sandbox
43
+ * versus production is a deployment choice rather than an account identity.
44
+ *
45
+ * Returns null (rather than throwing) when the key is present but an identifier
46
+ * is missing, so a half-configured environment disables the feature instead of
47
+ * taking the server down. `describeMissingApnsCredentials` explains which one.
48
+ */
49
+ export declare function readApnsCredentialsFromEnv(env?: NodeJS.ProcessEnv): ApnsCredentials | null;
50
+ /**
51
+ * Why Live Activity push is unavailable, as a message safe to log.
52
+ *
53
+ * Says which variable is missing and nothing about its value, so a boot log can
54
+ * explain the feature being off without becoming a place secrets leak.
55
+ */
56
+ export declare function describeMissingApnsCredentials(env?: NodeJS.ProcessEnv): string | null;
57
+ export declare class ApnsClient {
58
+ private readonly creds;
59
+ private session;
60
+ private cachedJwt;
61
+ constructor(creds: ApnsCredentials);
62
+ /**
63
+ * The `apns-topic` for Live Activity pushes.
64
+ *
65
+ * The `.push-type.liveactivity` suffix is mandatory and is why the signing key
66
+ * must be Team Scoped (All Topics) — a key scoped to the bundle id alone
67
+ * cannot sign this topic.
68
+ */
69
+ get topic(): string;
70
+ /**
71
+ * Mint or reuse the provider JWT.
72
+ *
73
+ * ES256 over the p8 key. Cached until shortly before expiry: Apple rejects a
74
+ * token older than an hour, but minting one per request is wasteful and can
75
+ * trip APNs' provider-token-update throttle.
76
+ */
77
+ private getJwt;
78
+ /**
79
+ * Reuse one HTTP/2 session across sends.
80
+ *
81
+ * APNs expects a long-lived connection; a fresh TLS handshake per push is slow
82
+ * and Apple treats connection churn as abuse.
83
+ */
84
+ private getSession;
85
+ /**
86
+ * Send one push.
87
+ *
88
+ * Resolves with a result rather than rejecting on an APNs rejection: a
89
+ * rejected push is an expected outcome the caller must act on (retire the
90
+ * token), not an exception. Only a genuinely unexpected local failure throws,
91
+ * and the caller logs it.
92
+ */
93
+ send(args: {
94
+ deviceToken: string;
95
+ payload: unknown;
96
+ /** 10 for a user-visible change, 5 to let iOS batch. */
97
+ priority?: 5 | 10;
98
+ /** Seconds since epoch after which APNs stops trying. */
99
+ expirationSeconds?: number;
100
+ timeoutMs?: number;
101
+ }): Promise<ApnsSendResult>;
102
+ /** Close the shared connection. Called on server shutdown. */
103
+ close(): void;
104
+ }
105
+ //# sourceMappingURL=apnsClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apnsClient.d.ts","sourceRoot":"","sources":["../../../src/services/push/apnsClient.ts"],"names":[],"mappings":"AAuBA,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,+BAA+B,CAAC;AAC9D,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAS3C,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAmBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,eAAe,GAAG,IAAI,CAYxB;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,GAAG,IAAI,CA2Bf;AAED,qBAAa,UAAU;IAIT,OAAO,CAAC,QAAQ,CAAC,KAAK;IAHlC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,SAAS,CAAqD;IAEtE,YAA6B,KAAK,EAAE,eAAe,EAAI;IAEvD;;;;;;OAMG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;;;;;OAMG;IACH,OAAO,CAAC,MAAM;IAsBd;;;;;OAKG;IACH,OAAO,CAAC,UAAU;IAclB;;;;;;;OAOG;IACG,IAAI,CAAC,IAAI,EAAE;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,wDAAwD;QACxD,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;QAClB,yDAAyD;QACzD,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,cAAc,CAAC,CAiE1B;IAED,8DAA8D;IAC9D,KAAK,IAAI,IAAI,CAGZ;CACF"}
@@ -0,0 +1,37 @@
1
+ import type { PushRepository } from "../../db/repositories/push.repository";
2
+ export declare const EXPO_PUSH_ENDPOINT = "https://exp.host/--/api/v2/push/send";
3
+ /** Expo accepts at most 100 messages per request. */
4
+ export declare const EXPO_PUSH_BATCH_SIZE = 100;
5
+ export interface ExpoPushMessage {
6
+ title: string;
7
+ body: string;
8
+ /** Delivered to the app as `notification.request.content.data`. */
9
+ data: Record<string, string>;
10
+ }
11
+ export interface ExpoPushOutcome {
12
+ attempted: number;
13
+ succeeded: number;
14
+ /** Tokens Expo rejected as permanently dead, now revoked locally. */
15
+ retired: number;
16
+ }
17
+ export declare class ExpoPushSender {
18
+ private readonly repo;
19
+ private readonly accessToken?;
20
+ /**
21
+ * @param accessToken Expo access token, when the project has enhanced
22
+ * security enabled. Optional on purpose: a self-hoster does not own the Expo
23
+ * project and cannot obtain one, so requiring it would break the deployment
24
+ * this transport exists to serve.
25
+ */
26
+ constructor(repo: PushRepository, accessToken?: string | undefined);
27
+ /**
28
+ * Send one message to every deliverable Expo token.
29
+ *
30
+ * Sends are independent: Expo returns a ticket per token in one response, so
31
+ * a dead device is recorded against its own row and never silences the other
32
+ * devices in the batch.
33
+ */
34
+ send(message: ExpoPushMessage, now?: number): Promise<ExpoPushOutcome>;
35
+ private sendChunk;
36
+ }
37
+ //# sourceMappingURL=expoPushSender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expoPushSender.d.ts","sourceRoot":"","sources":["../../../src/services/push/expoPushSender.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,uCAAuC,CAAC;AAmB1F,eAAO,MAAM,kBAAkB,yCAAyC,CAAC;AAEzE,qDAAqD;AACrD,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;CACjB;AAiBD,qBAAa,cAAc;IAQvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAR/B;;;;;OAKG;IACH,YACmB,IAAI,EAAE,cAAc,EACpB,WAAW,CAAC,EAAE,MAAM,YAAA,EACnC;IAEJ;;;;;;OAMG;IACG,IAAI,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAAC,eAAe,CAAC,CAUvF;YAEa,SAAS;CA0ExB"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The Live Activity content-state contract, shared with tb-mobile.
3
+ *
4
+ * tb-mobile defines the mirror of this shape in `types/live-activity.ts` and
5
+ * decodes it with a Swift `Codable` ActivityAttributes struct. A decode failure
6
+ * in ActivityKit is silent — the Lock Screen surface simply stops updating,
7
+ * with no error anywhere on the server — so a field name or type drifting apart
8
+ * from mobile's struct breaks the feature invisibly. Treat this file as a
9
+ * contract, not an internal type: changing it requires a coordinated tb-mobile
10
+ * change.
11
+ */
12
+ /**
13
+ * Statuses the surface renders. Deliberately narrower than the server's
14
+ * `SessionStatus`: `idle` has no Live Activity representation, because a session
15
+ * that is no longer live gets an `end` event rather than an update carrying a
16
+ * third status mobile has no case for.
17
+ */
18
+ export type LiveActivityStatus = "running" | "waiting_input";
19
+ /** Longest `lastOutput` sent. Mobile truncates to the same bound. */
20
+ export declare const LAST_OUTPUT_MAX_LENGTH = 90;
21
+ export interface LiveActivityContentState {
22
+ sessionId: string;
23
+ serverId: string;
24
+ projectName: string;
25
+ status: LiveActivityStatus;
26
+ /**
27
+ * Epoch **milliseconds** of the session's start.
28
+ *
29
+ * iOS renders its own ticking elapsed timer from this, so the server must
30
+ * never send a precomputed elapsed value and never push per-second updates.
31
+ * Carried unchanged across a renewal — a fresh value makes the user's visible
32
+ * timer reset to zero.
33
+ */
34
+ startedAt: number;
35
+ lastOutput: string;
36
+ serverLabel?: string;
37
+ /**
38
+ * User-visible session title, derived from the first user message.
39
+ *
40
+ * Absent until the first message is submitted (a session between spawn and
41
+ * that point has no title yet); mobile falls back to `projectName` when unset.
42
+ */
43
+ sessionName?: string;
44
+ }
45
+ /**
46
+ * Collapse a server session status onto the two the surface renders.
47
+ *
48
+ * Returns null for a status with no representation, which is the signal to send
49
+ * an `end` rather than an update.
50
+ */
51
+ export declare function toLiveActivityStatus(status: string): LiveActivityStatus | null;
52
+ /**
53
+ * Trim terminal output to the field's bound.
54
+ *
55
+ * Terminal output is unbounded and the whole APNs payload must stay under 4 KB,
56
+ * so this is what keeps a chatty session from producing a rejected push.
57
+ * Newlines collapse to spaces because the surface renders a single line.
58
+ */
59
+ export declare function truncateLastOutput(raw: string): string;
60
+ //# sourceMappingURL=liveActivityContentState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveActivityContentState.d.ts","sourceRoot":"","sources":["../../../src/services/push/liveActivityContentState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,eAAe,CAAC;AAE7D,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,kBAAkB,CAAC;IAC3B;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAE9E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKtD"}
@@ -0,0 +1,49 @@
1
+ import type { ManagedSession } from "../../types";
2
+ import { type LiveActivityContentState } from "./liveActivityContentState";
3
+ import type { LiveActivitySender } from "./liveActivitySender";
4
+ /**
5
+ * Build the content state mobile decodes.
6
+ *
7
+ * `startedAt` comes from the session's own start and is passed through in epoch
8
+ * milliseconds: iOS renders its own ticking timer from it, so the server must
9
+ * never compute an elapsed value.
10
+ */
11
+ export declare function contentStateForSession(args: {
12
+ session: ManagedSession;
13
+ serverId: string;
14
+ serverLabel?: string;
15
+ /** Overrides the session's own start — used by a renewal to preserve continuity. */
16
+ startedAtOverride?: number | null;
17
+ }): LiveActivityContentState | null;
18
+ export declare class LiveActivityNotifier {
19
+ private readonly sender;
20
+ private readonly serverId;
21
+ private readonly serverLabel?;
22
+ /**
23
+ * Sessions with a currently open (pushed) activity.
24
+ *
25
+ * An activity opens on a `waiting_input → running` edge (the user sent a
26
+ * prompt) and closes on the matching `running → waiting_input` edge (the
27
+ * response, including any sub-agents, finished) — so this set is what makes
28
+ * the notifier per-turn rather than per-session. A session's very first
29
+ * `running` (right after spawn, before any user prompt) has no prior
30
+ * `waiting_input` and therefore no edge, so it never opens an activity —
31
+ * this is what keeps a fresh/idle session from pushing anything.
32
+ */
33
+ private openActivity;
34
+ constructor(sender: LiveActivitySender, serverId: string, serverLabel?: string | undefined);
35
+ /**
36
+ * React to a session status change.
37
+ *
38
+ * Fire-and-forget by design: a push must never delay or fail a session
39
+ * transition, so this returns a promise the caller may ignore and every error
40
+ * is logged rather than propagated.
41
+ */
42
+ onStatusChange(session: ManagedSession, previousStatus?: string): Promise<void>;
43
+ private startTurn;
44
+ private maybeSendName;
45
+ private endFor;
46
+ /** Drop cached state for a session, so a resume re-opens on its next turn. */
47
+ forget(sessionId: string): void;
48
+ }
49
+ //# sourceMappingURL=liveActivityNotifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveActivityNotifier.d.ts","sourceRoot":"","sources":["../../../src/services/push/liveActivityNotifier.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACL,KAAK,wBAAwB,EAG9B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAuB/D;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,GAAG,wBAAwB,GAAG,IAAI,CAgBlC;AAED,qBAAa,oBAAoB;IAe7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAhB/B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,YAAY,CAAmD;IAEvE,YACmB,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,YAAA,EACnC;IAEJ;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCpF;YAEa,SAAS;YAwBT,aAAa;YA2Bb,MAAM;IAuBpB,8EAA8E;IAC9E,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE9B;CACF"}
@@ -0,0 +1,63 @@
1
+ import type { PushRepository, PushTokenRow } from "../../db/repositories/push.repository";
2
+ import type { SessionStore } from "../../session-store";
3
+ import { type LiveActivitySender } from "./liveActivitySender";
4
+ /**
5
+ * How long before the cap to renew.
6
+ *
7
+ * Far enough out that a missed tick or a slow APNs round trip still lands inside
8
+ * the window, close enough that the replacement activity gets a nearly full
9
+ * 8-hour lifetime of its own.
10
+ */
11
+ export declare const RENEWAL_LEAD_MS: number;
12
+ export interface LiveActivityRenewalDeps {
13
+ repo: PushRepository;
14
+ sender: LiveActivitySender;
15
+ sessionStore: SessionStore;
16
+ serverId: string;
17
+ serverLabel?: string;
18
+ /** Injected in tests; production uses the real clock. */
19
+ now?: () => number;
20
+ }
21
+ /** When a row should be renewed: its cap, minus the lead time. */
22
+ export declare function renewalDueAt(row: PushTokenRow): number | null;
23
+ export declare class LiveActivityRenewalScheduler {
24
+ private readonly deps;
25
+ private timer;
26
+ private stopped;
27
+ private readonly now;
28
+ constructor(deps: LiveActivityRenewalDeps);
29
+ /**
30
+ * Arm the scheduler from persisted state.
31
+ *
32
+ * Called on boot, which is what makes a renewal survive a restart: the
33
+ * deadlines were never in memory to begin with.
34
+ */
35
+ start(): void;
36
+ stop(): void;
37
+ /**
38
+ * Renew everything due, then sleep until the next deadline.
39
+ *
40
+ * Re-reads from the DB every tick rather than caching a schedule in memory, so
41
+ * an activity registered after boot is picked up without re-arming anything.
42
+ */
43
+ tick(): Promise<void>;
44
+ private scheduleNext;
45
+ /**
46
+ * Renew one activity.
47
+ *
48
+ * Claims first: `claimRenewal()` succeeds exactly once per row, so a timer
49
+ * re-armed after a restart mid-window cannot send a second time.
50
+ */
51
+ private renew;
52
+ /**
53
+ * Ask the device to start a replacement activity.
54
+ *
55
+ * Uses the app-wide push-to-start token, because the replacement does not
56
+ * exist yet and therefore has no per-activity token. Returns false when the
57
+ * device never registered one, which is not an error: the app simply cannot be
58
+ * asked to start an activity remotely, and the next foreground WS update
59
+ * recreates it.
60
+ */
61
+ private startReplacement;
62
+ }
63
+ //# sourceMappingURL=liveActivityRenewal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveActivityRenewal.d.ts","sourceRoot":"","sources":["../../../src/services/push/liveActivityRenewal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAE1F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAwBzF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,QAAiB,CAAC;AAW9C,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAE7D;AAED,qBAAa,4BAA4B;IAK3B,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IAEnC,YAA6B,IAAI,EAAE,uBAAuB,EAEzD;IAED;;;;;OAKG;IACH,KAAK,IAAI,IAAI,CAGZ;IAED,IAAI,IAAI,IAAI,CAMX;IAED;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAoB1B;IAED,OAAO,CAAC,YAAY;IAmBpB;;;;;OAKG;YACW,KAAK;IAgFnB;;;;;;;;OAQG;YACW,gBAAgB;CAgC/B"}
@@ -0,0 +1,88 @@
1
+ import type { PushRepository, PushTokenRow } from "../../db/repositories/push.repository";
2
+ import type { ApnsClient } from "./apnsClient";
3
+ import type { LiveActivityContentState } from "./liveActivityContentState";
4
+ /** iOS ends a Live Activity ~8h after it starts. */
5
+ export declare const ACTIVITY_MAX_LIFETIME_MS: number;
6
+ export type LiveActivityEvent = "update" | "end";
7
+ export interface LiveActivitySendOutcome {
8
+ attempted: number;
9
+ succeeded: number;
10
+ /** Tokens APNs rejected as permanently unusable, now expired locally. */
11
+ retired: number;
12
+ }
13
+ /**
14
+ * The APNs `aps` envelope for an ActivityKit push.
15
+ *
16
+ * Key names are Apple's and are not ours to choose: `content-state`,
17
+ * `stale-date`, and `dismissal-date` are hyphenated, while `timestamp` and
18
+ * `event` are not.
19
+ */
20
+ interface ActivityKitPayload {
21
+ aps: {
22
+ /** Seconds since epoch. iOS discards a push whose timestamp regresses. */
23
+ timestamp: number;
24
+ event: LiveActivityEvent;
25
+ "content-state": LiveActivityContentState;
26
+ /** Seconds since epoch. When iOS should start showing the content as stale. */
27
+ "stale-date"?: number;
28
+ "dismissal-date"?: number;
29
+ };
30
+ }
31
+ export declare function buildActivityKitPayload(args: {
32
+ event: LiveActivityEvent;
33
+ contentState: LiveActivityContentState;
34
+ now: number;
35
+ staleDate?: number | null;
36
+ dismissalDate?: number | null;
37
+ }): ActivityKitPayload;
38
+ export declare class LiveActivitySender {
39
+ private readonly apns;
40
+ private readonly repo;
41
+ constructor(apns: ApnsClient, repo: PushRepository);
42
+ /**
43
+ * Push to every live activity of a session.
44
+ *
45
+ * Sends are independent: one rejected token must not stop the others, because
46
+ * a single dead device would otherwise silence every other device watching the
47
+ * same session.
48
+ */
49
+ send(args: {
50
+ sessionId: string;
51
+ event: LiveActivityEvent;
52
+ contentState: LiveActivityContentState;
53
+ now?: number;
54
+ priority?: 5 | 10;
55
+ }): Promise<LiveActivitySendOutcome>;
56
+ /**
57
+ * Push to an explicit token list.
58
+ *
59
+ * Renewal needs this: a replacement activity does not exist yet, so it is
60
+ * started via the app-wide push-to-start token rather than any per-session
61
+ * lookup. Shares one fan-out body with `send()` so failure handling cannot
62
+ * drift between the two paths.
63
+ */
64
+ sendToTokens(args: {
65
+ tokens: PushTokenRow[];
66
+ sessionId: string;
67
+ event: LiveActivityEvent;
68
+ contentState: LiveActivityContentState;
69
+ now?: number;
70
+ priority?: 5 | 10;
71
+ /** Overrides the row's own cap — renewal sets the replacement's window. */
72
+ staleDate?: number | null;
73
+ }): Promise<LiveActivitySendOutcome>;
74
+ /**
75
+ * End every live activity for a session and stop tracking them.
76
+ *
77
+ * Expiring locally is what stops the renewal sweep from later resurrecting an
78
+ * activity for a session that has already finished.
79
+ */
80
+ end(args: {
81
+ sessionId: string;
82
+ contentState: LiveActivityContentState;
83
+ now?: number;
84
+ }): Promise<LiveActivitySendOutcome>;
85
+ private sendToToken;
86
+ }
87
+ export {};
88
+ //# sourceMappingURL=liveActivitySender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveActivitySender.d.ts","sourceRoot":"","sources":["../../../src/services/push/liveActivitySender.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAE1F,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAa3E,oDAAoD;AACpD,eAAO,MAAM,wBAAwB,QAAqB,CAAC;AAE3D,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEjD,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,UAAU,kBAAkB;IAC1B,GAAG,EAAE;QACH,0EAA0E;QAC1E,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,iBAAiB,CAAC;QACzB,eAAe,EAAE,wBAAwB,CAAC;QAC1C,+EAA+E;QAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,KAAK,EAAE,iBAAiB,CAAC;IACzB,YAAY,EAAE,wBAAwB,CAAC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,GAAG,kBAAkB,CAYrB;AAED,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFvB,YACmB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,cAAc,EACnC;IAEJ;;;;;;OAMG;IACG,IAAI,CAAC,IAAI,EAAE;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,iBAAiB,CAAC;QACzB,YAAY,EAAE,wBAAwB,CAAC;QACvC,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;KACnB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAUnC;IAED;;;;;;;OAOG;IACG,YAAY,CAAC,IAAI,EAAE;QACvB,MAAM,EAAE,YAAY,EAAE,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,iBAAiB,CAAC;QACzB,YAAY,EAAE,wBAAwB,CAAC;QACvC,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;QAClB,2EAA2E;QAC3E,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA0DnC;IAED;;;;;OAKG;IACG,GAAG,CAAC,IAAI,EAAE;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,wBAAwB,CAAC;QACvC,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAUnC;YAEa,WAAW;CAwB1B"}