myrlin-workbook 0.9.9 → 0.9.11

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 (288) hide show
  1. package/.planning/PROJECT.md +124 -0
  2. package/.planning/REQUIREMENTS.md +230 -0
  3. package/.planning/STATE.md +116 -0
  4. package/.planning/config.json +17 -0
  5. package/.planning/phases/01-foundation/01-01-PLAN.md +297 -0
  6. package/.planning/phases/01-foundation/01-01-SUMMARY.md +104 -0
  7. package/.planning/phases/01-foundation/01-02-PLAN.md +364 -0
  8. package/.planning/phases/01-foundation/01-02-SUMMARY.md +150 -0
  9. package/.planning/phases/01-foundation/01-03-PLAN.md +187 -0
  10. package/.planning/phases/01-foundation/01-03-SUMMARY.md +124 -0
  11. package/.planning/phases/01-foundation/01-RESEARCH.md +778 -0
  12. package/.planning/phases/01-foundation/01-VALIDATION.md +83 -0
  13. package/.planning/phases/01-foundation/01-VERIFICATION.md +139 -0
  14. package/.planning/phases/02-connection-and-auth/02-01-PLAN.md +266 -0
  15. package/.planning/phases/02-connection-and-auth/02-01-SUMMARY.md +139 -0
  16. package/.planning/phases/02-connection-and-auth/02-02-PLAN.md +276 -0
  17. package/.planning/phases/02-connection-and-auth/02-02-SUMMARY.md +138 -0
  18. package/.planning/phases/02-connection-and-auth/02-03-PLAN.md +300 -0
  19. package/.planning/phases/02-connection-and-auth/02-03-SUMMARY.md +138 -0
  20. package/.planning/phases/02-connection-and-auth/02-RESEARCH.md +713 -0
  21. package/.planning/phases/02-connection-and-auth/02-VALIDATION.md +80 -0
  22. package/.planning/phases/02-connection-and-auth/02-VERIFICATION.md +135 -0
  23. package/.planning/phases/03-sessions-and-workspaces/03-01-PLAN.md +320 -0
  24. package/.planning/phases/03-sessions-and-workspaces/03-01-SUMMARY.md +122 -0
  25. package/.planning/phases/03-sessions-and-workspaces/03-02-PLAN.md +278 -0
  26. package/.planning/phases/03-sessions-and-workspaces/03-02-SUMMARY.md +136 -0
  27. package/.planning/phases/03-sessions-and-workspaces/03-03-PLAN.md +220 -0
  28. package/.planning/phases/03-sessions-and-workspaces/03-03-SUMMARY.md +124 -0
  29. package/.planning/phases/03-sessions-and-workspaces/03-04-PLAN.md +254 -0
  30. package/.planning/phases/03-sessions-and-workspaces/03-04-SUMMARY.md +115 -0
  31. package/.planning/phases/03-sessions-and-workspaces/03-RESEARCH.md +611 -0
  32. package/.planning/phases/03-sessions-and-workspaces/03-VALIDATION.md +53 -0
  33. package/.planning/phases/03-sessions-and-workspaces/03-VERIFICATION.md +211 -0
  34. package/.planning/phases/04-terminal/04-01-PLAN.md +288 -0
  35. package/.planning/phases/04-terminal/04-01-SUMMARY.md +138 -0
  36. package/.planning/phases/04-terminal/04-02-PLAN.md +278 -0
  37. package/.planning/phases/04-terminal/04-02-SUMMARY.md +114 -0
  38. package/.planning/phases/04-terminal/04-03-PLAN.md +238 -0
  39. package/.planning/phases/04-terminal/04-03-SUMMARY.md +105 -0
  40. package/.planning/phases/04-terminal/04-RESEARCH.md +586 -0
  41. package/.planning/phases/04-terminal/04-VALIDATION.md +45 -0
  42. package/.planning/phases/04-terminal/04-VERIFICATION.md +124 -0
  43. package/.planning/phases/05-data-screens/05-01-PLAN.md +251 -0
  44. package/.planning/phases/05-data-screens/05-01-SUMMARY.md +145 -0
  45. package/.planning/phases/05-data-screens/05-02-PLAN.md +275 -0
  46. package/.planning/phases/05-data-screens/05-02-SUMMARY.md +133 -0
  47. package/.planning/phases/05-data-screens/05-03-PLAN.md +334 -0
  48. package/.planning/phases/05-data-screens/05-03-SUMMARY.md +94 -0
  49. package/.planning/phases/05-data-screens/05-04-PLAN.md +212 -0
  50. package/.planning/phases/05-data-screens/05-04-SUMMARY.md +95 -0
  51. package/.planning/phases/06-notifications-and-settings/06-01-PLAN.md +211 -0
  52. package/.planning/phases/06-notifications-and-settings/06-01-SUMMARY.md +108 -0
  53. package/.planning/phases/06-notifications-and-settings/06-02-PLAN.md +290 -0
  54. package/.planning/phases/06-notifications-and-settings/06-02-SUMMARY.md +127 -0
  55. package/.planning/phases/06-notifications-and-settings/06-03-PLAN.md +276 -0
  56. package/.planning/phases/06-notifications-and-settings/06-03-SUMMARY.md +135 -0
  57. package/.planning/phases/07-platform-polish-and-testing/07-01-PLAN.md +225 -0
  58. package/.planning/phases/07-platform-polish-and-testing/07-01-SUMMARY.md +112 -0
  59. package/.planning/phases/07-platform-polish-and-testing/07-02-PLAN.md +205 -0
  60. package/.planning/phases/07-platform-polish-and-testing/07-02-SUMMARY.md +106 -0
  61. package/.planning/phases/07-platform-polish-and-testing/07-03-PLAN.md +424 -0
  62. package/.planning/phases/07-platform-polish-and-testing/07-03-SUMMARY.md +145 -0
  63. package/.planning/phases/08-token-persistence-and-device-registry/08-01-PLAN.md +462 -0
  64. package/.planning/phases/08-token-persistence-and-device-registry/08-01-SUMMARY.md +102 -0
  65. package/.planning/phases/08-token-persistence-and-device-registry/08-02-PLAN.md +314 -0
  66. package/.planning/phases/08-token-persistence-and-device-registry/08-02-SUMMARY.md +90 -0
  67. package/.planning/phases/08-token-persistence-and-device-registry/08-03-PLAN.md +228 -0
  68. package/.planning/phases/08-token-persistence-and-device-registry/08-03-SUMMARY.md +98 -0
  69. package/.planning/phases/09-pairing-enhancement-and-desktop-ui/09-01-PLAN.md +206 -0
  70. package/.planning/phases/09-pairing-enhancement-and-desktop-ui/09-01-SUMMARY.md +102 -0
  71. package/.planning/phases/09-pairing-enhancement-and-desktop-ui/09-02-PLAN.md +371 -0
  72. package/.planning/phases/09-pairing-enhancement-and-desktop-ui/09-02-SUMMARY.md +124 -0
  73. package/.planning/phases/10-push-enhancement/10-01-PLAN.md +204 -0
  74. package/.planning/phases/10-push-enhancement/10-01-SUMMARY.md +97 -0
  75. package/.planning/phases/10-push-enhancement/10-02-PLAN.md +183 -0
  76. package/.planning/phases/10-push-enhancement/10-02-SUMMARY.md +92 -0
  77. package/.planning/phases/10-push-enhancement/10-03-PLAN.md +159 -0
  78. package/.planning/phases/10-push-enhancement/10-03-SUMMARY.md +87 -0
  79. package/.planning/phases/11-sse-and-sync-optimization/11-01-PLAN.md +195 -0
  80. package/.planning/phases/11-sse-and-sync-optimization/11-01-SUMMARY.md +89 -0
  81. package/.planning/phases/11-sse-and-sync-optimization/11-02-PLAN.md +216 -0
  82. package/.planning/phases/11-sse-and-sync-optimization/11-02-SUMMARY.md +90 -0
  83. package/.planning/phases/11-sse-and-sync-optimization/11-03-PLAN.md +261 -0
  84. package/.planning/phases/11-sse-and-sync-optimization/11-03-SUMMARY.md +116 -0
  85. package/.planning/phases/12-api-enhancement/12-01-PLAN.md +219 -0
  86. package/.planning/phases/12-api-enhancement/12-01-SUMMARY.md +92 -0
  87. package/.planning/phases/12-api-enhancement/12-02-PLAN.md +216 -0
  88. package/.planning/phases/12-api-enhancement/12-02-SUMMARY.md +98 -0
  89. package/.planning/phases/12-api-enhancement/12-03-PLAN.md +173 -0
  90. package/.planning/phases/12-api-enhancement/12-03-SUMMARY.md +86 -0
  91. package/.planning/phases/13-error-standards-and-hardening/13-01-PLAN.md +57 -0
  92. package/.planning/phases/13-error-standards-and-hardening/13-01-SUMMARY.md +90 -0
  93. package/.planning/research/ARCHITECTURE.md +309 -0
  94. package/.planning/research/FEATURES.md +104 -0
  95. package/.planning/research/PITFALLS.md +140 -0
  96. package/.planning/research/STACK.md +283 -0
  97. package/.planning/research/SUMMARY.md +207 -0
  98. package/mobile/.storybook/main.ts +18 -0
  99. package/mobile/.storybook/preview.tsx +52 -0
  100. package/mobile/.vscode/extensions.json +1 -0
  101. package/mobile/.vscode/settings.json +7 -0
  102. package/mobile/app/(auth)/_layout.tsx +36 -0
  103. package/mobile/app/(auth)/login.tsx +225 -0
  104. package/mobile/app/(auth)/manual-connect.tsx +291 -0
  105. package/mobile/app/(auth)/onboarding.tsx +135 -0
  106. package/mobile/app/(auth)/scan-qr.tsx +407 -0
  107. package/mobile/app/(tabs)/_layout.tsx +134 -0
  108. package/mobile/app/(tabs)/costs/index.tsx +186 -0
  109. package/mobile/app/(tabs)/more/_layout.tsx +32 -0
  110. package/mobile/app/(tabs)/more/conflicts.tsx +218 -0
  111. package/mobile/app/(tabs)/more/index.tsx +325 -0
  112. package/mobile/app/(tabs)/more/recent.tsx +149 -0
  113. package/mobile/app/(tabs)/more/resources.tsx +186 -0
  114. package/mobile/app/(tabs)/more/search.tsx +396 -0
  115. package/mobile/app/(tabs)/more/servers.tsx +368 -0
  116. package/mobile/app/(tabs)/more/session-manager.tsx +270 -0
  117. package/mobile/app/(tabs)/more/settings.tsx +440 -0
  118. package/mobile/app/(tabs)/more/templates.tsx +238 -0
  119. package/mobile/app/(tabs)/more/workspaces.tsx +582 -0
  120. package/mobile/app/(tabs)/sessions/[id].tsx +868 -0
  121. package/mobile/app/(tabs)/sessions/_layout.tsx +33 -0
  122. package/mobile/app/(tabs)/sessions/index.tsx +380 -0
  123. package/mobile/app/(tabs)/sessions/terminal.tsx +73 -0
  124. package/mobile/app/(tabs)/tasks/[id].tsx +94 -0
  125. package/mobile/app/(tabs)/tasks/_layout.tsx +29 -0
  126. package/mobile/app/(tabs)/tasks/index.tsx +133 -0
  127. package/mobile/app/+html.tsx +38 -0
  128. package/mobile/app/+not-found.tsx +40 -0
  129. package/mobile/app/_layout.tsx +182 -0
  130. package/mobile/app/index.tsx +24 -0
  131. package/mobile/app/modal.tsx +35 -0
  132. package/mobile/app.json +70 -0
  133. package/mobile/assets/fonts/JetBrainsMono-Bold.ttf +0 -0
  134. package/mobile/assets/fonts/JetBrainsMono-Medium.ttf +0 -0
  135. package/mobile/assets/fonts/JetBrainsMono-Regular.ttf +0 -0
  136. package/mobile/assets/fonts/SpaceMono-Regular.ttf +0 -0
  137. package/mobile/assets/images/android-icon-background.png +0 -0
  138. package/mobile/assets/images/android-icon-foreground.png +0 -0
  139. package/mobile/assets/images/android-icon-monochrome.png +0 -0
  140. package/mobile/assets/images/favicon.png +0 -0
  141. package/mobile/assets/images/icon.png +0 -0
  142. package/mobile/assets/images/splash-icon.png +0 -0
  143. package/mobile/assets/terminal.html +488 -0
  144. package/mobile/components/BiometricGate.tsx +178 -0
  145. package/mobile/components/ConnectionDot.tsx +157 -0
  146. package/mobile/components/EditScreenInfo.tsx +77 -0
  147. package/mobile/components/ExternalLink.tsx +24 -0
  148. package/mobile/components/OfflineBanner.tsx +89 -0
  149. package/mobile/components/ServerMenu.tsx +384 -0
  150. package/mobile/components/StyledText.tsx +5 -0
  151. package/mobile/components/Themed.tsx +45 -0
  152. package/mobile/components/conflicts/ConflictRow.tsx +160 -0
  153. package/mobile/components/costs/CostSummaryCards.tsx +118 -0
  154. package/mobile/components/costs/CostTimeline.tsx +115 -0
  155. package/mobile/components/costs/ModelBreakdown.tsx +122 -0
  156. package/mobile/components/costs/TopSessions.tsx +154 -0
  157. package/mobile/components/costs/WorkspaceBreakdown.tsx +131 -0
  158. package/mobile/components/resources/SessionResources.tsx +231 -0
  159. package/mobile/components/resources/SystemStats.tsx +216 -0
  160. package/mobile/components/search/QuickSwitcher.tsx +343 -0
  161. package/mobile/components/sessions/ActivityIndicator.tsx +129 -0
  162. package/mobile/components/sessions/NewSessionModal.tsx +384 -0
  163. package/mobile/components/sessions/SessionActions.tsx +419 -0
  164. package/mobile/components/sessions/SessionCard.tsx +220 -0
  165. package/mobile/components/tasks/CreateTaskSheet.tsx +218 -0
  166. package/mobile/components/tasks/TaskBoard.tsx +226 -0
  167. package/mobile/components/tasks/TaskCard.tsx +211 -0
  168. package/mobile/components/tasks/TaskDetail.tsx +542 -0
  169. package/mobile/components/tasks/TaskList.tsx +86 -0
  170. package/mobile/components/terminal/ReaderMode.tsx +235 -0
  171. package/mobile/components/terminal/TerminalCarousel.tsx +209 -0
  172. package/mobile/components/terminal/TerminalHeader.tsx +140 -0
  173. package/mobile/components/terminal/TerminalInput.tsx +127 -0
  174. package/mobile/components/terminal/TerminalScreen.tsx +332 -0
  175. package/mobile/components/terminal/TerminalToolbar.tsx +211 -0
  176. package/mobile/components/terminal/TerminalWebView.tsx +171 -0
  177. package/mobile/components/terminal/useTerminalBridge.ts +153 -0
  178. package/mobile/components/ui/ActionSheet.stories.tsx +45 -0
  179. package/mobile/components/ui/ActionSheet.tsx +154 -0
  180. package/mobile/components/ui/Badge.stories.tsx +66 -0
  181. package/mobile/components/ui/Badge.tsx +85 -0
  182. package/mobile/components/ui/Button.stories.tsx +92 -0
  183. package/mobile/components/ui/Button.tsx +159 -0
  184. package/mobile/components/ui/Card.stories.tsx +45 -0
  185. package/mobile/components/ui/Card.tsx +61 -0
  186. package/mobile/components/ui/Chip.stories.tsx +46 -0
  187. package/mobile/components/ui/Chip.tsx +69 -0
  188. package/mobile/components/ui/EmptyState.stories.tsx +48 -0
  189. package/mobile/components/ui/EmptyState.tsx +84 -0
  190. package/mobile/components/ui/Input.stories.tsx +54 -0
  191. package/mobile/components/ui/Input.tsx +98 -0
  192. package/mobile/components/ui/MetaRow.stories.tsx +44 -0
  193. package/mobile/components/ui/MetaRow.tsx +78 -0
  194. package/mobile/components/ui/ModalSheet.stories.tsx +48 -0
  195. package/mobile/components/ui/ModalSheet.tsx +138 -0
  196. package/mobile/components/ui/SearchBar.stories.tsx +46 -0
  197. package/mobile/components/ui/SearchBar.tsx +89 -0
  198. package/mobile/components/ui/SectionHeader.stories.tsx +36 -0
  199. package/mobile/components/ui/SectionHeader.tsx +75 -0
  200. package/mobile/components/ui/SegmentedControl.stories.tsx +45 -0
  201. package/mobile/components/ui/SegmentedControl.tsx +88 -0
  202. package/mobile/components/ui/Skeleton.stories.tsx +44 -0
  203. package/mobile/components/ui/Skeleton.tsx +68 -0
  204. package/mobile/components/ui/StatusDot.stories.tsx +58 -0
  205. package/mobile/components/ui/StatusDot.tsx +105 -0
  206. package/mobile/components/ui/Toast.stories.tsx +57 -0
  207. package/mobile/components/ui/Toast.tsx +145 -0
  208. package/mobile/components/ui/Toggle.stories.tsx +46 -0
  209. package/mobile/components/ui/Toggle.tsx +91 -0
  210. package/mobile/components/ui/TokenBar.stories.tsx +48 -0
  211. package/mobile/components/ui/TokenBar.tsx +70 -0
  212. package/mobile/components/ui/index.ts +58 -0
  213. package/mobile/components/useClientOnlyValue.ts +4 -0
  214. package/mobile/components/useClientOnlyValue.web.ts +12 -0
  215. package/mobile/components/useColorScheme.ts +6 -0
  216. package/mobile/components/useColorScheme.web.ts +8 -0
  217. package/mobile/components/workspaces/NewWorkspaceModal.tsx +226 -0
  218. package/mobile/components/workspaces/WorkspaceActions.tsx +337 -0
  219. package/mobile/components/workspaces/WorkspaceItem.tsx +214 -0
  220. package/mobile/constants/Colors.ts +19 -0
  221. package/mobile/eas.json +31 -0
  222. package/mobile/hooks/useAPIClient.ts +38 -0
  223. package/mobile/hooks/useConnectionHealth.ts +149 -0
  224. package/mobile/hooks/useCosts.ts +43 -0
  225. package/mobile/hooks/useDocs.ts +209 -0
  226. package/mobile/hooks/useOffline.ts +121 -0
  227. package/mobile/hooks/usePush.ts +161 -0
  228. package/mobile/hooks/useResources.ts +67 -0
  229. package/mobile/hooks/useSSE.ts +90 -0
  230. package/mobile/hooks/useSearch.ts +139 -0
  231. package/mobile/hooks/useSessions.ts +183 -0
  232. package/mobile/hooks/useTasks.ts +201 -0
  233. package/mobile/hooks/useTheme.ts +87 -0
  234. package/mobile/hooks/useToast.ts +81 -0
  235. package/mobile/hooks/useWorkspaces.ts +139 -0
  236. package/mobile/maestro/config.yaml +3 -0
  237. package/mobile/maestro/flows/app-launch.yaml +12 -0
  238. package/mobile/maestro/flows/conflicts.yaml +23 -0
  239. package/mobile/maestro/flows/costs.yaml +22 -0
  240. package/mobile/maestro/flows/docs.yaml +18 -0
  241. package/mobile/maestro/flows/navigation.yaml +31 -0
  242. package/mobile/maestro/flows/offline-banner.yaml +33 -0
  243. package/mobile/maestro/flows/resources.yaml +28 -0
  244. package/mobile/maestro/flows/search.yaml +23 -0
  245. package/mobile/maestro/flows/session-detail.yaml +21 -0
  246. package/mobile/maestro/flows/sessions-list.yaml +22 -0
  247. package/mobile/maestro/flows/settings.yaml +28 -0
  248. package/mobile/maestro/flows/tasks.yaml +32 -0
  249. package/mobile/maestro/flows/templates.yaml +23 -0
  250. package/mobile/maestro/flows/terminal.yaml +28 -0
  251. package/mobile/maestro/flows/theme-screenshots.yaml +67 -0
  252. package/mobile/maestro/flows/theme-switch.yaml +15 -0
  253. package/mobile/maestro/flows/workspaces.yaml +23 -0
  254. package/mobile/package-lock.json +16059 -0
  255. package/mobile/package.json +76 -0
  256. package/mobile/scripts/build-terminal-html.js +243 -0
  257. package/mobile/services/api-client.ts +874 -0
  258. package/mobile/services/push-service.ts +71 -0
  259. package/mobile/services/sse-client.ts +90 -0
  260. package/mobile/stores/auth-store.ts +140 -0
  261. package/mobile/stores/secure-storage-adapter.ts +64 -0
  262. package/mobile/stores/server-store.ts +260 -0
  263. package/mobile/stores/settings-store.ts +109 -0
  264. package/mobile/stores/theme-store.ts +113 -0
  265. package/mobile/stores/ui-store.ts +65 -0
  266. package/mobile/theme/fonts.ts +46 -0
  267. package/mobile/theme/tokens.ts +748 -0
  268. package/mobile/theme/types.ts +142 -0
  269. package/mobile/tsconfig.json +21 -0
  270. package/mobile/types/api.ts +687 -0
  271. package/mobile/types/navigation.ts +64 -0
  272. package/mobile/types/terminal.ts +118 -0
  273. package/mobile/utils/haptics.ts +97 -0
  274. package/mobile/utils/offline.ts +174 -0
  275. package/package.json +2 -1
  276. package/scripts/extract-themes.js +308 -0
  277. package/src/state/store.js +240 -0
  278. package/src/web/auth.js +200 -26
  279. package/src/web/device-manager.js +376 -0
  280. package/src/web/pairing.js +284 -0
  281. package/src/web/pty-manager.js +58 -0
  282. package/src/web/public/app.js +351 -0
  283. package/src/web/public/index.html +39 -0
  284. package/src/web/public/styles.css +268 -0
  285. package/src/web/public/terminal.js +7 -0
  286. package/src/web/public/vendor/qrcode.min.js +8 -0
  287. package/src/web/push.js +607 -0
  288. package/src/web/server.js +635 -220
@@ -0,0 +1,124 @@
1
+ # Myrlin Mobile
2
+
3
+ ## What This Is
4
+
5
+ A React Native (Expo) mobile app that provides full control over Myrlin's Workbook servers from iOS and Android. Connects to self-hosted Myrlin servers via QR code pairing or manual URL entry. Every feature available on the web GUI (100+ features) is accessible on mobile with native platform interactions (share sheet, haptics, push notifications, biometric auth, camera).
6
+
7
+ ## Core Value
8
+
9
+ A Myrlin user can monitor, control, and interact with all their Claude Code sessions from their phone with the same capability as the desktop web interface, plus native mobile advantages (push notifications, QR pairing, haptics, camera, share sheet).
10
+
11
+ ## Requirements
12
+
13
+ ### Validated
14
+
15
+ - ✓ Web GUI feature set (100+ features) - existing, serves as the spec
16
+ - ✓ Express REST API (60+ endpoints) - existing backend the mobile app connects to
17
+ - ✓ SSE real-time event system - existing, mobile subscribes to same stream
18
+ - ✓ WebSocket terminal protocol - existing, mobile terminal connects via same WS
19
+ - ✓ Bearer token authentication - existing auth system
20
+ - ✓ 13 theme system (Catppuccin + community) - existing, port to React Native
21
+ - ✓ Cost tracking with JSONL parsing - existing server-side calculation
22
+
23
+ ### Active
24
+
25
+ - [ ] Full feature parity mobile app (95 mapped features)
26
+ - [ ] Hybrid terminal (WebView xterm.js renderer + native interaction chrome)
27
+ - [ ] QR code server pairing (new server endpoint + mobile camera)
28
+ - [ ] Push notifications (new server push endpoints + Expo notifications)
29
+ - [ ] Multi-server support (connect phone to multiple Myrlin servers)
30
+ - [ ] Biometric app lock (Face ID / fingerprint)
31
+ - [ ] Native share sheet integration
32
+ - [ ] Voice input for terminal (iOS dictation + speech recognition)
33
+ - [ ] Image upload from camera/gallery to terminal sessions
34
+ - [ ] Offline graceful degradation (cached state, reconnection queue)
35
+ - [ ] Maestro visual test suite for every screen
36
+
37
+ ### Out of Scope
38
+
39
+ - myrlin.io relay service - Phase 2+ paid feature, requires separate backend infrastructure
40
+ - Multi-user team sync - requires coordination server, deferred to paid tier
41
+ - Desktop app (Electron) - mobile only for now
42
+ - Apple Watch companion - unnecessary complexity for v1
43
+ - Widget / Live Activities - nice-to-have for v2, not v1
44
+ - Offline terminal (local Claude) - not possible, terminal requires server connection
45
+
46
+ ## Context
47
+
48
+ ### Existing Codebase (Brownfield)
49
+
50
+ Myrlin's Workbook v0.9.9 is a mature Node.js application:
51
+
52
+ - **Backend:** Express server with 60+ REST endpoints, WebSocket PTY management, SSE event streaming
53
+ - **Frontend:** Vanilla JS SPA (16,000+ lines), xterm.js terminals, 4100 lines CSS
54
+ - **State:** JSON persistence in `~/.myrlin/`, atomic writes with backup/recovery
55
+ - **Auth:** Bearer tokens, password-based, one-time startup tokens
56
+ - **Cost:** Worker thread JSONL parsing, per-model pricing
57
+ - **Themes:** 13 themes (4 Catppuccin official + 9 community), CSS custom properties
58
+
59
+ The mobile app is a NEW client connecting to the EXISTING server. No server rewrite needed, only new endpoints for QR pairing and push notifications.
60
+
61
+ ### Design Document
62
+
63
+ Full design with all contracts, types, component specs, and screen specifications:
64
+ `docs/plans/2026-03-28-myrlin-mobile-design.md`
65
+
66
+ ### Development Environment
67
+
68
+ - **Build machine:** Mac Mini (Tailscale: 100.111.181.106)
69
+ - **Xcode:** Required for iOS Simulator and builds
70
+ - **Apple Developer:** Active account (Shuttle project on TestFlight Build 8)
71
+ - **Testing:** Maestro on iOS Simulator, Storybook for components, Expo Go on physical iPhone
72
+
73
+ ### Target Platforms
74
+
75
+ - **iOS first** (iPhone, iOS 16+)
76
+ - **Android within 2 weeks** of iOS launch (Android 13+)
77
+ - **Cross-platform:** Single React Native codebase via Expo
78
+
79
+ ## Constraints
80
+
81
+ - **Framework:** React Native (Expo SDK 52+), must use expo-router for navigation
82
+ - **Agent model:** ALL build agents must use Opus with deep thinking, no exceptions
83
+ - **Orchestration:** Two-tier only (orchestrator -> workers), no manager middle layer
84
+ - **Terminal:** Hybrid WebView approach (xterm.js renderer + native chrome), pluggable interface
85
+ - **Modularity:** Every screen, component, and service must be independently swappable
86
+ - **Testing:** Maestro flow tests required for every screen, Storybook stories for every shared component
87
+ - **Font:** Plus Jakarta Sans (sans), JetBrains Mono (mono), matching web app
88
+ - **Theme:** All 13 themes must render identically to web CSS
89
+ - **Monorepo:** Source lives in `mobile/` directory within myrlin-workbook repo
90
+ - **No em dashes:** NEVER use em dashes or double hyphens in any output
91
+
92
+ ## Current Milestone: v1.1 Server Mobile Support
93
+
94
+ **Goal:** Make the Myrlin server production-ready for mobile clients with persistent auth, device management, enhanced push notifications, optimized sync, and a desktop QR pairing UI.
95
+
96
+ **Target features:**
97
+ - Persistent device tokens that survive server restarts
98
+ - Device registry with lifecycle management (pair, track, revoke, expire)
99
+ - Enhanced QR pairing with LAN/Tailscale/tunnel URL auto-detection
100
+ - Desktop web UI: "Pair Mobile" modal with QR code and device management
101
+ - Push notification retry, batching, per-device preferences, rich payloads
102
+ - SSE optimization with heartbeat, device filtering, workspace subscriptions
103
+ - Initial sync endpoint for fast mobile bootstrap
104
+ - Session pagination for power users with 100+ sessions
105
+ - Token refresh for long-lived mobile sessions
106
+ - Server info endpoint for capability discovery
107
+
108
+ **Self-hosting:** All features are 100% local. Only external dependency is Expo Push API (free relay to Apple/Google push servers, identical to how Nextcloud and Home Assistant handle mobile push). No myrlin.io, no cloud database, no external auth.
109
+
110
+ ## Key Decisions
111
+
112
+ | Decision | Rationale | Outcome |
113
+ |----------|-----------|---------|
114
+ | React Native (Expo) over Flutter | JS/TS ecosystem matches existing codebase, Expo handles build tooling, OTA updates, largest component ecosystem | - Pending |
115
+ | Hybrid terminal (WebView + native) | xterm.js is battle-tested for ANSI rendering; native chrome gives iOS share sheet, haptics, keyboard | - Pending |
116
+ | Monorepo over separate repo | Shared types, single git history, easier API contract sync | - Pending |
117
+ | QR pairing first, relay later | Free tier needs no external service; relay requires myrlin.io infrastructure | - Pending |
118
+ | Zustand + TanStack Query | Zustand for local UI state, TanStack Query for server data with SSE cache sync | - Pending |
119
+ | Maestro for visual QA | YAML-based, runs on iOS Simulator, takes real screenshots, agent-writable | - Pending |
120
+ | Bottom tabs (5) over drawer | iOS convention, familiar navigation, badges for running counts | - Pending |
121
+ | Two-tier orchestration | Manager middle layer degrades context fidelity; direct briefing preserves contracts | - Pending |
122
+
123
+ ---
124
+ *Last updated: 2026-03-29 after milestone v1.1 start*
@@ -0,0 +1,230 @@
1
+ # Requirements: Myrlin Server Mobile Support (v1.1)
2
+
3
+ **Defined:** 2026-03-29
4
+ **Core Value:** Self-hosted Myrlin server fully supports mobile clients with persistent auth, device management, push notifications, and optimized data sync, with zero external dependencies beyond Expo Push relay.
5
+
6
+ ## v1.1 Requirements
7
+
8
+ ### Token Persistence
9
+
10
+ - [x] **TOKN-01**: Paired device tokens persist across server restarts (stored in state file)
11
+ - [x] **TOKN-02**: Server reloads all valid device tokens into active set on startup
12
+ - [x] **TOKN-03**: Expired device tokens (> 90 days) are automatically cleaned up on startup
13
+ - [x] **TOKN-04**: Token validation uses timing-safe comparison (existing pattern)
14
+ - [x] **TOKN-05**: Token refresh endpoint allows mobile to get new token before expiration
15
+ - [x] **TOKN-06**: Refreshed tokens immediately replace old tokens in active set and state
16
+
17
+ ### Device Registry
18
+
19
+ - [x] **DEVC-01**: Server stores paired device metadata (deviceId, name, platform, appVersion, pairedAt, lastSeenAt, expiresAt)
20
+ - [x] **DEVC-02**: Device lastSeenAt updates on each authenticated API request (debounced)
21
+ - [x] **DEVC-03**: GET /api/devices returns list of all paired devices with online status
22
+ - [x] **DEVC-04**: DELETE /api/devices/:deviceId revokes device token and closes active connections
23
+ - [x] **DEVC-05**: PUT /api/devices/:deviceId updates device name and push preferences
24
+ - [x] **DEVC-06**: POST /api/devices/:deviceId/test-push sends test notification to device
25
+
26
+ ### Pairing Enhancement
27
+
28
+ - [x] **PAIR-01**: POST /api/auth/pair returns deviceId and server capabilities in response
29
+ - [x] **PAIR-02**: Pair endpoint stores device metadata (name, platform, appVersion) in pairedDevices
30
+ - [x] **PAIR-03**: GET /api/auth/pairing-code detects LAN IP from network interfaces
31
+ - [x] **PAIR-04**: GET /api/auth/pairing-code detects Tailscale IP (100.x.x.x) if present
32
+ - [x] **PAIR-05**: GET /api/auth/pairing-code uses configured tunnel URL if available
33
+ - [x] **PAIR-06**: QR payload includes all available URLs so mobile can try each
34
+ - [x] **PAIR-07**: Server info endpoint (GET /api/server-info) returns capabilities, URLs, and stats without auth
35
+
36
+ ### CORS and Network
37
+
38
+ - [x] **CORS-01**: CORS allows requests from any origin when a valid Bearer token is present
39
+ - [x] **CORS-02**: CORS preflight (OPTIONS) responds correctly for mobile clients
40
+ - [x] **CORS-03**: Content-Security-Policy updated to allow mobile WebSocket connections from any host
41
+
42
+ ### Push Notifications
43
+
44
+ - [x] **PUSH-01**: Push dispatch retries failed sends with exponential backoff (max 3 attempts)
45
+ - [x] **PUSH-02**: Push events are batched in a 2-second window (5 events in 1s = 1 summary push)
46
+ - [x] **PUSH-03**: Per-device push preferences (sessionComplete, needsInput, conflicts, taskReview) stored in device record
47
+ - [x] **PUSH-04**: Push dispatch checks device preferences before sending
48
+ - [x] **PUSH-05**: Push payloads include deep link route data for mobile navigation
49
+ - [x] **PUSH-06**: Push includes badge count (running sessions) for iOS
50
+ - [x] **PUSH-07**: Stale push tokens (DeviceNotRegistered) are automatically cleaned from device registry
51
+ - [x] **PUSH-08**: GET /api/push/preferences returns device's notification preferences
52
+ - [x] **PUSH-09**: PUT /api/push/preferences updates device's notification preferences
53
+ - [x] **PUSH-10**: Push dispatched for: session complete, needs input, file conflicts, task ready for review
54
+
55
+ ### SSE Enhancement
56
+
57
+ - [x] **SSE-01**: SSE sends heartbeat comment (`: heartbeat`) every 30 seconds
58
+ - [x] **SSE-02**: SSE client registry tracks device metadata (deviceId, subscriptions)
59
+ - [x] **SSE-03**: SSE supports deviceId query param for device-specific filtering
60
+ - [x] **SSE-04**: SSE filters workspace-scoped events by device's workspace subscriptions
61
+ - [x] **SSE-05**: Global events (settings, server status) always sent regardless of subscriptions
62
+ - [x] **SSE-06**: Dead SSE connections cleaned up within 60 seconds
63
+
64
+ ### Workspace Subscriptions
65
+
66
+ - [x] **WSUB-01**: POST /api/devices/:deviceId/subscriptions sets workspace subscription list
67
+ - [x] **WSUB-02**: GET /api/devices/:deviceId/subscriptions returns current subscriptions
68
+ - [x] **WSUB-03**: Subscriptions stored in device record in pairedDevices
69
+ - [x] **WSUB-04**: Empty subscription list means "receive all events" (default)
70
+
71
+ ### Initial Sync
72
+
73
+ - [x] **SYNC-01**: GET /api/mobile/sync returns all bootstrap data in single response
74
+ - [x] **SYNC-02**: Sync response includes workspaces, sessions (sparse), groups, templates, settings, stats, device info
75
+ - [x] **SYNC-03**: Sessions in sync response use sparse fields (id, name, status, workspaceId, topic, tags, lastActive, pid)
76
+ - [x] **SYNC-04**: Sync response includes syncVersion number for future delta sync
77
+
78
+ ### Session Pagination
79
+
80
+ - [x] **PAGE-01**: GET /api/sessions supports limit and offset query parameters
81
+ - [x] **PAGE-02**: GET /api/sessions supports status filter (running, stopped, error, idle, all)
82
+ - [x] **PAGE-03**: GET /api/sessions supports sort (lastActive, name, created) and order (asc, desc)
83
+ - [x] **PAGE-04**: GET /api/sessions supports search query param (substring match on name/topic)
84
+ - [x] **PAGE-05**: GET /api/sessions supports workspaceId filter
85
+ - [x] **PAGE-06**: Paginated response includes total count, hasMore flag
86
+ - [x] **PAGE-07**: Default limit is 50, max 100, for backward compatibility unpaginated requests still work
87
+
88
+ ### Desktop Web UI
89
+
90
+ - [x] **DWUI-01**: "Pair Mobile" button visible in header bar
91
+ - [x] **DWUI-02**: Pair Mobile modal shows QR code generated from /api/auth/pairing-code
92
+ - [x] **DWUI-03**: QR code auto-refreshes every 4 minutes (tokens expire at 5)
93
+ - [x] **DWUI-04**: Modal shows all detected connection URLs (LAN, Tailscale, tunnel)
94
+ - [x] **DWUI-05**: Modal shows paired devices list with name, platform, last seen, push status
95
+ - [x] **DWUI-06**: Each paired device has a "Revoke" button with confirmation
96
+ - [x] **DWUI-07**: Each paired device has a "Test Push" button
97
+ - [x] **DWUI-08**: QR code rendered as SVG using qrcode library
98
+
99
+ ### Scrollback and Logs
100
+
101
+ - [x] **SCRL-01**: GET /api/sessions/:id/scrollback returns paginated terminal scrollback
102
+ - [x] **SCRL-02**: Scrollback supports lines and from parameters (from=end for last N lines)
103
+ - [x] **SCRL-03**: GET /api/sessions/:id/logs supports limit and offset pagination
104
+
105
+ ### Error Standards
106
+
107
+ - [ ] **ERRR-01**: Mobile-facing endpoints return structured errors with machine-readable code
108
+ - [ ] **ERRR-02**: Rate limit responses include Retry-After header
109
+ - [ ] **ERRR-03**: All responses include X-API-Version header (value: 1)
110
+
111
+ ### Testing
112
+
113
+ - [x] **MTST-01**: Integration tests for token persistence across simulated restart
114
+ - [x] **MTST-02**: Integration tests for device CRUD (pair, list, update, revoke)
115
+ - [x] **MTST-03**: Integration tests for push retry, batching, and preference filtering
116
+ - [x] **MTST-04**: Integration tests for SSE heartbeat and workspace filtering
117
+ - [x] **MTST-05**: Integration tests for session pagination with various filters
118
+ - [x] **MTST-06**: Integration tests for initial sync endpoint response shape
119
+
120
+ ## Future Requirements (v1.2+)
121
+
122
+ ### Delta Sync
123
+ - **DSYN-01**: GET /api/mobile/delta returns only changes since a given timestamp
124
+ - **DSYN-02**: Server maintains circular buffer of last 1000 state changes
125
+
126
+ ### Offline Bundle
127
+ - **OFFL-01**: GET /api/mobile/offline-bundle returns compressed state snapshot
128
+ - **OFFL-02**: POST /api/mobile/offline-sync uploads queued mutations for merge
129
+
130
+ ### Connection Quality
131
+ - **CQAL-01**: POST /api/devices/:deviceId/connection-quality reports network conditions
132
+ - **CQAL-02**: Server adjusts SSE event frequency based on reported quality
133
+
134
+ ## Out of Scope
135
+
136
+ | Feature | Reason |
137
+ |---------|--------|
138
+ | myrlin.io relay service | Separate infrastructure, paid tier scope |
139
+ | Multi-user auth (per-user tokens) | v2 feature, requires identity system |
140
+ | End-to-end encryption | Adds complexity, LAN/Tailscale already encrypted in transit |
141
+ | Custom push notification sounds | Low value, use system defaults |
142
+ | Advanced per-device rate limiting | Basic IP rate limiting sufficient for v1.1 |
143
+ | Certificate pinning | Overkill for self-hosted LAN/Tailscale use case |
144
+
145
+ ## Traceability
146
+
147
+ | Requirement | Phase | Status |
148
+ |-------------|-------|--------|
149
+ | TOKN-01 | Phase 8 | Complete |
150
+ | TOKN-02 | Phase 8 | Complete |
151
+ | TOKN-03 | Phase 8 | Complete |
152
+ | TOKN-04 | Phase 8 | Complete |
153
+ | TOKN-05 | Phase 12 | Complete |
154
+ | TOKN-06 | Phase 12 | Complete |
155
+ | DEVC-01 | Phase 8 | Complete |
156
+ | DEVC-02 | Phase 8 | Complete |
157
+ | DEVC-03 | Phase 8 | Complete |
158
+ | DEVC-04 | Phase 8 | Complete |
159
+ | DEVC-05 | Phase 8 | Complete |
160
+ | DEVC-06 | Phase 8 | Complete |
161
+ | PAIR-01 | Phase 9 | Complete |
162
+ | PAIR-02 | Phase 9 | Complete |
163
+ | PAIR-03 | Phase 9 | Complete |
164
+ | PAIR-04 | Phase 9 | Complete |
165
+ | PAIR-05 | Phase 9 | Complete |
166
+ | PAIR-06 | Phase 9 | Complete |
167
+ | PAIR-07 | Phase 9 | Complete |
168
+ | CORS-01 | Phase 8 | Complete |
169
+ | CORS-02 | Phase 8 | Complete |
170
+ | CORS-03 | Phase 8 | Complete |
171
+ | PUSH-01 | Phase 10 | Complete |
172
+ | PUSH-02 | Phase 10 | Complete |
173
+ | PUSH-03 | Phase 10 | Complete |
174
+ | PUSH-04 | Phase 10 | Complete |
175
+ | PUSH-05 | Phase 10 | Complete |
176
+ | PUSH-06 | Phase 10 | Complete |
177
+ | PUSH-07 | Phase 10 | Complete |
178
+ | PUSH-08 | Phase 10 | Complete |
179
+ | PUSH-09 | Phase 10 | Complete |
180
+ | PUSH-10 | Phase 10 | Complete |
181
+ | SSE-01 | Phase 11 | Complete |
182
+ | SSE-02 | Phase 11 | Complete |
183
+ | SSE-03 | Phase 11 | Complete |
184
+ | SSE-04 | Phase 11 | Complete |
185
+ | SSE-05 | Phase 11 | Complete |
186
+ | SSE-06 | Phase 11 | Complete |
187
+ | WSUB-01 | Phase 11 | Complete |
188
+ | WSUB-02 | Phase 11 | Complete |
189
+ | WSUB-03 | Phase 11 | Complete |
190
+ | WSUB-04 | Phase 11 | Complete |
191
+ | SYNC-01 | Phase 11 | Complete |
192
+ | SYNC-02 | Phase 11 | Complete |
193
+ | SYNC-03 | Phase 11 | Complete |
194
+ | SYNC-04 | Phase 11 | Complete |
195
+ | PAGE-01 | Phase 12 | Complete |
196
+ | PAGE-02 | Phase 12 | Complete |
197
+ | PAGE-03 | Phase 12 | Complete |
198
+ | PAGE-04 | Phase 12 | Complete |
199
+ | PAGE-05 | Phase 12 | Complete |
200
+ | PAGE-06 | Phase 12 | Complete |
201
+ | PAGE-07 | Phase 12 | Complete |
202
+ | DWUI-01 | Phase 9 | Complete |
203
+ | DWUI-02 | Phase 9 | Complete |
204
+ | DWUI-03 | Phase 9 | Complete |
205
+ | DWUI-04 | Phase 9 | Complete |
206
+ | DWUI-05 | Phase 9 | Complete |
207
+ | DWUI-06 | Phase 9 | Complete |
208
+ | DWUI-07 | Phase 9 | Complete |
209
+ | DWUI-08 | Phase 9 | Complete |
210
+ | SCRL-01 | Phase 12 | Complete |
211
+ | SCRL-02 | Phase 12 | Complete |
212
+ | SCRL-03 | Phase 12 | Complete |
213
+ | ERRR-01 | Phase 13 | Pending |
214
+ | ERRR-02 | Phase 13 | Pending |
215
+ | ERRR-03 | Phase 13 | Pending |
216
+ | MTST-01 | Phase 8 | Complete |
217
+ | MTST-02 | Phase 8 | Complete |
218
+ | MTST-03 | Phase 10 | Complete |
219
+ | MTST-04 | Phase 11 | Complete |
220
+ | MTST-05 | Phase 12 | Complete |
221
+ | MTST-06 | Phase 11 | Complete |
222
+
223
+ **Coverage:**
224
+ - v1.1 requirements: 73 total (13 categories)
225
+ - Mapped to phases: 73/73
226
+ - Unmapped: 0
227
+
228
+ ---
229
+ *Requirements defined: 2026-03-29*
230
+ *Last updated: 2026-03-29 after roadmap creation (traceability populated)*
@@ -0,0 +1,116 @@
1
+ ---
2
+ gsd_state_version: 1.0
3
+ milestone: v1.0
4
+ milestone_name: Mobile App
5
+ status: completed
6
+ stopped_at: Completed 13-01-PLAN.md - v1.1 milestone complete
7
+ last_updated: "2026-03-29T08:59:32.532Z"
8
+ last_activity: 2026-03-29 - Completed Plan 13-01 (structured errors, Retry-After, X-API-Version)
9
+ progress:
10
+ total_phases: 13
11
+ completed_phases: 13
12
+ total_plans: 38
13
+ completed_plans: 38
14
+ percent: 100
15
+ ---
16
+
17
+ # Project State
18
+
19
+ ## Project Reference
20
+
21
+ See: .planning/PROJECT.md (updated 2026-03-29)
22
+
23
+ **Core value:** Self-hosted Myrlin server fully supports mobile clients with persistent auth, device management, push notifications, and optimized data sync.
24
+ **Current focus:** All phases complete. v1.1 Server Mobile Support done.
25
+
26
+ ## Current Position
27
+
28
+ Phase: 13 of 13 (Error Standards and Hardening)
29
+ Plan: 1 of 1 in current phase (COMPLETE)
30
+ Status: Milestone Complete
31
+ Last activity: 2026-03-29 - Completed Plan 13-01 (structured errors, Retry-After, X-API-Version)
32
+
33
+ Progress: [██████████] 100% (38/38 plans)
34
+
35
+ ## Performance Metrics
36
+
37
+ **Velocity (from v1.0):**
38
+ - Total plans completed: 23
39
+ - Average duration: 4.7m
40
+ - Total execution time: ~1.8 hours
41
+
42
+ **v1.1 metrics:**
43
+
44
+ | Phase | Plan | Duration | Tasks | Files |
45
+ |-------|------|----------|-------|-------|
46
+ | 08 | 01 | 3min | 2 | 4 |
47
+ | Phase 08 P02 | 2min | 2 tasks | 2 files |
48
+ | Phase 08 P03 | 4min | 2 tasks | 2 files |
49
+ | 11 | 01 | 3min | 1 | 1 |
50
+ | Phase 09 P01 | 2min | 2 tasks | 2 files |
51
+ | Phase 10 P01 | 2min | 2 tasks | 1 files |
52
+ | 12 | 01 | 3min | 2 | 2 |
53
+ | Phase 10 P02 | 3min | 2 tasks | 1 files |
54
+ | Phase 12 P02 | 3min | 2 tasks | 4 files |
55
+ | Phase 11 P02 | 2min | 2 tasks | 2 files |
56
+ | Phase 09 P02 | 4min | 3 tasks | 5 files |
57
+ | 11 | 03 | 5min | 2 | 2 |
58
+ | Phase 10 P03 | 3min | 1 tasks | 1 files |
59
+ | Phase 12 P03 | 2min | 1 tasks | 1 files |
60
+ | 13 | 01 | 3min | 1 | 2 |
61
+
62
+ ## Accumulated Context
63
+
64
+ ### Decisions
65
+
66
+ - v1.1 Roadmap: 6 phases (8-13), standard granularity, derived from design doc phases A-F
67
+ - v1.1 Roadmap: Phase 8 is critical path; Phases 9, 10, 11, 12 can run in parallel after Phase 8
68
+ - v1.1 Roadmap: Testing requirements distributed across phases (each phase tests its own work)
69
+ - v1.1 Roadmap: Token refresh (TOKN-05/06) placed in Phase 12 (API Enhancement) not Phase 8 (avoids scope creep on critical path)
70
+ - v1.1 Roadmap: ERRR requirements isolated in Phase 13 (applies uniformly to all endpoints after they exist)
71
+
72
+ - 08-01: Device tokens stored plaintext (matches pushDevices pattern; hashing deferred to Phase 12)
73
+ - 08-01: CORS preflight allows Authorization from any origin (OPTIONS cannot carry Bearer)
74
+ - 08-01: lastSeenAt debounced at 60s per device
75
+ - [Phase 08]: SSE clients migrated from Set to Map for device online detection
76
+ - [Phase 08]: Test push sends to single device via Expo API, not broadcast
77
+ - [Phase 08]: Module-level reload pattern for testing restart survival (faster than full server restart)
78
+
79
+ - 11-01: SSE heartbeat uses comment syntax (`: heartbeat`) not data events, avoids triggering onmessage
80
+ - 11-01: All SSE timers call .unref() so Node process exits cleanly
81
+ - 11-01: GLOBAL_EVENT_TYPES kept module-scoped (not exported), Plan 11-02 uses it in same file
82
+ - [Phase 09]: Tailscale detection uses 100.x.x.x prefix match; primary URL order: custom > tunnel > lan > local
83
+ - [Phase 10]: 10-01: Per-device retry (not batch POST) so one stale token does not block others
84
+ - [Phase 10]: 10-01: Module-level Map + setTimeout for 2-second push batching window
85
+ - 12-01: Dual-mode endpoint detection (mode param = legacy, pagination params = new response shape)
86
+ - 12-01: Default no-params returns legacy { sessions } for backward compat with existing GUI
87
+ - [Phase 10]: shouldNotify defaults to true for unknown event types and missing preferences (fail-open)
88
+ - [Phase 12]: Scrollback joins buffer chunks then splits by newline for accurate line counting
89
+ - [Phase 12]: Token refresh only for device tokens (403 for browser tokens) as security boundary
90
+ - [Phase 11]: Empty or null subscriptions = receive all events (backward compat with desktop)
91
+ - [Phase 11]: workspace:created added to GLOBAL_EVENT_TYPES so new workspaces reach all clients
92
+ - [Phase 11]: SSE client subscriptions updated in-place on POST, no reconnection needed
93
+ - [Phase 09]: Client-side QR generation via esbuild-bundled qrcode browser build to vendor/
94
+ - [Phase 09]: QR SVG uses theme --text color with transparent bg for all theme compat
95
+ - [Phase 11]: Sparse session fields: id, name, workspaceId, status, topic, tags, lastActive, pid, resumeSessionId
96
+ - [Phase 11]: syncVersion=1 for future delta sync; totalCost=0 in sync to avoid expensive JSONL parsing
97
+ - [Phase 11]: SSE integration tests spawn real server on port 3463 (matching pairing test pattern)
98
+ - [Phase 10]: setTimeout mocked to fire immediately for retry tests; batching tests flush manually with 50ms settle
99
+ - [Phase 12]: Direct store method testing for pagination (no HTTP server) for speed and isolation
100
+ - [Phase 13]: Error codes use uppercase snake_case (RATE_LIMITED, UNAUTHORIZED, INVALID_PASSWORD)
101
+ - [Phase 13]: isRateLimited() returns { limited, retryAfter } object for Retry-After header calculation
102
+ - [Phase 13]: structuredError helper exported from server.js for reuse by other route modules
103
+
104
+ ### Pending Todos
105
+
106
+ None yet.
107
+
108
+ ### Blockers/Concerns
109
+
110
+ - Phase 2 and Phase 7 from v1.0 show as in-progress in prior state (may need completion before v1.1 starts)
111
+
112
+ ## Session Continuity
113
+
114
+ Last session: 2026-03-29T08:58:30Z
115
+ Stopped at: Completed 13-01-PLAN.md - v1.1 milestone complete
116
+ Resume file: None
@@ -0,0 +1,17 @@
1
+ {
2
+ "mode": "yolo",
3
+ "granularity": "standard",
4
+ "parallelization": true,
5
+ "commit_docs": true,
6
+ "model_profile": "quality",
7
+ "workflow": {
8
+ "research": true,
9
+ "plan_check": true,
10
+ "verifier": true,
11
+ "nyquist_validation": true,
12
+ "auto_advance": true,
13
+ "_auto_verify": true,
14
+ "_qa_agent": true,
15
+ "_opus_override": "ALL agents must use model: opus. Non-negotiable per project rules."
16
+ }
17
+ }