@cats-inc/cats-platform 0.1.1 → 0.1.7

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 (203) hide show
  1. package/.env.example +2 -2
  2. package/README.md +6 -0
  3. package/build/desktop/bootstrapPage.d.ts.map +1 -1
  4. package/build/desktop/bootstrapPage.js +81 -4
  5. package/build/desktop/bootstrapPage.js.map +1 -1
  6. package/build/desktop/config.d.ts +11 -1
  7. package/build/desktop/config.d.ts.map +1 -1
  8. package/build/desktop/config.js +5 -2
  9. package/build/desktop/config.js.map +1 -1
  10. package/build/desktop/contracts.d.ts +68 -11
  11. package/build/desktop/contracts.d.ts.map +1 -1
  12. package/build/desktop/contracts.js +52 -1
  13. package/build/desktop/contracts.js.map +1 -1
  14. package/build/desktop/hostState.d.ts +4 -3
  15. package/build/desktop/hostState.d.ts.map +1 -1
  16. package/build/desktop/hostState.js +22 -30
  17. package/build/desktop/hostState.js.map +1 -1
  18. package/build/desktop/hostVersion.d.ts +1 -0
  19. package/build/desktop/hostVersion.d.ts.map +1 -1
  20. package/build/desktop/hostVersion.js +29 -5
  21. package/build/desktop/hostVersion.js.map +1 -1
  22. package/build/desktop/ipcSecurity.d.ts +6 -0
  23. package/build/desktop/ipcSecurity.d.ts.map +1 -0
  24. package/build/desktop/ipcSecurity.js +10 -0
  25. package/build/desktop/ipcSecurity.js.map +1 -0
  26. package/build/desktop/main.js +272 -59
  27. package/build/desktop/main.js.map +1 -1
  28. package/build/desktop/packaging.d.ts.map +1 -1
  29. package/build/desktop/packaging.js +10 -4
  30. package/build/desktop/packaging.js.map +1 -1
  31. package/build/desktop/preload.cjs +39 -0
  32. package/build/desktop/preload.cjs.map +1 -1
  33. package/build/desktop/processSupervisor.d.ts +2 -0
  34. package/build/desktop/processSupervisor.d.ts.map +1 -1
  35. package/build/desktop/processSupervisor.js +28 -13
  36. package/build/desktop/processSupervisor.js.map +1 -1
  37. package/build/desktop/readiness.d.ts +2 -2
  38. package/build/desktop/readiness.d.ts.map +1 -1
  39. package/build/desktop/readiness.js +2 -2
  40. package/build/desktop/readiness.js.map +1 -1
  41. package/build/desktop/releaseDescriptor.d.ts +85 -0
  42. package/build/desktop/releaseDescriptor.d.ts.map +1 -0
  43. package/build/desktop/releaseDescriptor.js +246 -0
  44. package/build/desktop/releaseDescriptor.js.map +1 -0
  45. package/build/desktop/screenshotCapture.d.ts.map +1 -1
  46. package/build/desktop/screenshotCapture.js +3 -7
  47. package/build/desktop/screenshotCapture.js.map +1 -1
  48. package/build/desktop/security.d.ts +8 -0
  49. package/build/desktop/security.d.ts.map +1 -1
  50. package/build/desktop/security.js +54 -1
  51. package/build/desktop/security.js.map +1 -1
  52. package/build/desktop/tray.d.ts +1 -0
  53. package/build/desktop/tray.d.ts.map +1 -1
  54. package/build/desktop/tray.js +26 -0
  55. package/build/desktop/tray.js.map +1 -1
  56. package/build/desktop/trayMenu.d.ts +22 -1
  57. package/build/desktop/trayMenu.d.ts.map +1 -1
  58. package/build/desktop/trayMenu.js +61 -0
  59. package/build/desktop/trayMenu.js.map +1 -1
  60. package/build/desktop/updateInstallHandoff.d.ts +30 -0
  61. package/build/desktop/updateInstallHandoff.d.ts.map +1 -0
  62. package/build/desktop/updateInstallHandoff.js +39 -0
  63. package/build/desktop/updateInstallHandoff.js.map +1 -0
  64. package/build/desktop/updateIpc.d.ts +42 -0
  65. package/build/desktop/updateIpc.d.ts.map +1 -0
  66. package/build/desktop/updateIpc.js +71 -0
  67. package/build/desktop/updateIpc.js.map +1 -0
  68. package/build/desktop/updateManager.d.ts +76 -0
  69. package/build/desktop/updateManager.d.ts.map +1 -0
  70. package/build/desktop/updateManager.js +342 -0
  71. package/build/desktop/updateManager.js.map +1 -0
  72. package/build/desktop/updateNotifications.d.ts +64 -0
  73. package/build/desktop/updateNotifications.d.ts.map +1 -0
  74. package/build/desktop/updateNotifications.js +143 -0
  75. package/build/desktop/updateNotifications.js.map +1 -0
  76. package/build/desktop/updaterAdapter.d.ts +72 -0
  77. package/build/desktop/updaterAdapter.d.ts.map +1 -0
  78. package/build/desktop/updaterAdapter.js +198 -0
  79. package/build/desktop/updaterAdapter.js.map +1 -0
  80. package/build/desktop/voiceCapture.d.ts.map +1 -1
  81. package/build/desktop/voiceCapture.js +3 -7
  82. package/build/desktop/voiceCapture.js.map +1 -1
  83. package/build/renderer/assets/ActiveSessionPermissionChip-BRMLwkvf.js +1 -0
  84. package/build/renderer/assets/{App-BbuTWT6Y.js → App-BM2nzo6s.js} +1 -1
  85. package/build/renderer/assets/{App-n-RtGh42.js → App-CVQAwCMi.js} +1 -1
  86. package/build/renderer/assets/{App-B13AzNko.js → App-Dl5FLaR_.js} +1 -1
  87. package/build/renderer/assets/{WorkspaceAppRoutes-BktWrQK-.js → WorkspaceAppRoutes-C3DUzdbj.js} +1 -1
  88. package/build/renderer/assets/app-hP5h2jAt.js +43 -0
  89. package/build/renderer/assets/{client-DREGSZqQ.js → client-BdGHAUoK.js} +1 -1
  90. package/build/renderer/assets/{conversationSidebarRecentEntries-BNPz3X1V.js → conversationSidebarRecentEntries-B-mNvfiy.js} +1 -1
  91. package/build/renderer/assets/{screenshotOverlay-EF07cXvw.js → screenshotOverlay-DfBcolX-.js} +1 -1
  92. package/build/renderer/assets/{useDraftSessionChips-3z_Je4ju.js → useDraftSessionChips-DuXIoptW.js} +1 -1
  93. package/build/renderer/desktop/overlay/index.html +2 -2
  94. package/build/renderer/index.html +2 -2
  95. package/build/server/app/renderer/settings/settingsDesktopErrorLabels.d.ts +5 -0
  96. package/build/server/app/renderer/settings/settingsDesktopErrorLabels.d.ts.map +1 -0
  97. package/build/server/app/renderer/settings/settingsDesktopErrorLabels.js +16 -0
  98. package/build/server/app/renderer/settings/settingsDesktopErrorLabels.js.map +1 -0
  99. package/build/server/app/renderer/settings/settingsDesktopPreferences.d.ts +11 -0
  100. package/build/server/app/renderer/settings/settingsDesktopPreferences.d.ts.map +1 -0
  101. package/build/server/app/renderer/settings/settingsDesktopPreferences.js +30 -0
  102. package/build/server/app/renderer/settings/settingsDesktopPreferences.js.map +1 -0
  103. package/build/server/app/renderer/settings/settingsDesktopUpdateLabels.d.ts +31 -0
  104. package/build/server/app/renderer/settings/settingsDesktopUpdateLabels.d.ts.map +1 -0
  105. package/build/server/app/renderer/settings/settingsDesktopUpdateLabels.js +101 -0
  106. package/build/server/app/renderer/settings/settingsDesktopUpdateLabels.js.map +1 -0
  107. package/build/server/app/server/authGatePolicy.js +14 -2
  108. package/build/server/app/server/authGatePolicy.js.map +1 -1
  109. package/build/server/app/server/authRoutes.d.ts +2 -1
  110. package/build/server/app/server/authRoutes.d.ts.map +1 -1
  111. package/build/server/app/server/authRoutes.js +260 -4
  112. package/build/server/app/server/authRoutes.js.map +1 -1
  113. package/build/server/app/server/contracts.d.ts +3 -1
  114. package/build/server/app/server/contracts.d.ts.map +1 -1
  115. package/build/server/app/server/dependencies.d.ts.map +1 -1
  116. package/build/server/app/server/dependencies.js +4 -1
  117. package/build/server/app/server/dependencies.js.map +1 -1
  118. package/build/server/app/server/index.js +1 -1
  119. package/build/server/app/server/index.js.map +1 -1
  120. package/build/server/app/server/platformSetupRoutes.d.ts.map +1 -1
  121. package/build/server/app/server/platformSetupRoutes.js +42 -5
  122. package/build/server/app/server/platformSetupRoutes.js.map +1 -1
  123. package/build/server/app/server/requestRouter.d.ts.map +1 -1
  124. package/build/server/app/server/requestRouter.js +3 -0
  125. package/build/server/app/server/requestRouter.js.map +1 -1
  126. package/build/server/design/components/runtimeChips.d.ts +1 -1
  127. package/build/server/design/components/runtimeChips.d.ts.map +1 -1
  128. package/build/server/design/components/runtimeChips.js +4 -1
  129. package/build/server/design/components/runtimeChips.js.map +1 -1
  130. package/build/server/index.js +12 -1
  131. package/build/server/index.js.map +1 -1
  132. package/build/server/platform/auth/browserHandoff.d.ts +50 -0
  133. package/build/server/platform/auth/browserHandoff.d.ts.map +1 -0
  134. package/build/server/platform/auth/browserHandoff.js +94 -0
  135. package/build/server/platform/auth/browserHandoff.js.map +1 -0
  136. package/build/server/platform/auth/index.d.ts +1 -0
  137. package/build/server/platform/auth/index.d.ts.map +1 -1
  138. package/build/server/platform/auth/index.js +1 -0
  139. package/build/server/platform/auth/index.js.map +1 -1
  140. package/build/server/platform/auth/principal.js +2 -2
  141. package/build/server/platform/auth/principal.js.map +1 -1
  142. package/build/server/platform/auth/session.d.ts +3 -0
  143. package/build/server/platform/auth/session.d.ts.map +1 -1
  144. package/build/server/platform/auth/session.js +41 -0
  145. package/build/server/platform/auth/session.js.map +1 -1
  146. package/build/server/platform/auth/sessionSecretProvisioning.d.ts +23 -0
  147. package/build/server/platform/auth/sessionSecretProvisioning.d.ts.map +1 -0
  148. package/build/server/platform/auth/sessionSecretProvisioning.js +291 -0
  149. package/build/server/platform/auth/sessionSecretProvisioning.js.map +1 -0
  150. package/build/server/platform/auth/state.js +4 -0
  151. package/build/server/platform/auth/state.js.map +1 -1
  152. package/build/server/platform/auth/types.d.ts +1 -0
  153. package/build/server/platform/auth/types.d.ts.map +1 -1
  154. package/build/server/products/code/livePreview/realProcessAdapter.d.ts.map +1 -1
  155. package/build/server/products/code/livePreview/realProcessAdapter.js +7 -1
  156. package/build/server/products/code/livePreview/realProcessAdapter.js.map +1 -1
  157. package/build/server/products/code/state/appExport.d.ts.map +1 -1
  158. package/build/server/products/code/state/appExport.js +2 -0
  159. package/build/server/products/code/state/appExport.js.map +1 -1
  160. package/build/server/shared/browserHandoff.d.ts +11 -0
  161. package/build/server/shared/browserHandoff.d.ts.map +1 -0
  162. package/build/server/shared/browserHandoff.js +2 -0
  163. package/build/server/shared/browserHandoff.js.map +1 -0
  164. package/build/server/shared/desktopRecoveryBridge.d.ts +47 -0
  165. package/build/server/shared/desktopRecoveryBridge.d.ts.map +1 -1
  166. package/build/server/shared/desktopRecoveryBridge.js +20 -0
  167. package/build/server/shared/desktopRecoveryBridge.js.map +1 -1
  168. package/build/server/shared/i18n/catalogs/en.d.ts.map +1 -1
  169. package/build/server/shared/i18n/catalogs/en.js +38 -0
  170. package/build/server/shared/i18n/catalogs/en.js.map +1 -1
  171. package/build/server/shared/i18n/catalogs/zh-TW.d.ts.map +1 -1
  172. package/build/server/shared/i18n/catalogs/zh-TW.js +36 -0
  173. package/build/server/shared/i18n/catalogs/zh-TW.js.map +1 -1
  174. package/build/server/shared/i18n/index.d.ts +36 -0
  175. package/build/server/shared/i18n/index.d.ts.map +1 -1
  176. package/build/server/shared/i18n/messageKeys.d.ts +36 -0
  177. package/build/server/shared/i18n/messageKeys.d.ts.map +1 -1
  178. package/build/server/shared/i18n/messageKeys.js +36 -0
  179. package/build/server/shared/i18n/messageKeys.js.map +1 -1
  180. package/build/server/shared/loadProjectEnvFile.d.ts.map +1 -1
  181. package/build/server/shared/loadProjectEnvFile.js +18 -19
  182. package/build/server/shared/loadProjectEnvFile.js.map +1 -1
  183. package/build/server/shared/platformChildProcessEnv.d.ts +2 -0
  184. package/build/server/shared/platformChildProcessEnv.d.ts.map +1 -0
  185. package/build/server/shared/platformChildProcessEnv.js +22 -0
  186. package/build/server/shared/platformChildProcessEnv.js.map +1 -0
  187. package/package.json +19 -27
  188. package/scripts/build-desktop-installer.mjs +438 -37
  189. package/scripts/build-test-ui.mjs +13 -2
  190. package/scripts/generate-desktop-release-descriptor.mjs +258 -0
  191. package/scripts/validate-release-assets.mjs +422 -0
  192. package/scripts/validate-release-version.mjs +217 -0
  193. package/scripts/windows/Test-WindowsInstallerSmoke.ps1 +55 -1
  194. package/build/desktop/update.d.ts +0 -24
  195. package/build/desktop/update.d.ts.map +0 -1
  196. package/build/desktop/update.js +0 -173
  197. package/build/desktop/update.js.map +0 -1
  198. package/build/renderer/assets/ActiveSessionPermissionChip-BYr8cDpb.js +0 -1
  199. package/build/renderer/assets/app-DnVQMpW_.js +0 -43
  200. package/build/server/app/renderer/settings/settingsDesktopStartupErrorLabels.d.ts +0 -5
  201. package/build/server/app/renderer/settings/settingsDesktopStartupErrorLabels.d.ts.map +0 -1
  202. package/build/server/app/renderer/settings/settingsDesktopStartupErrorLabels.js +0 -11
  203. package/build/server/app/renderer/settings/settingsDesktopStartupErrorLabels.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"trayMenu.js","sourceRoot":"","sources":["../../desktop/host/trayMenu.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trayMenu.js","sourceRoot":"","sources":["../../desktop/host/trayMenu.ts"],"names":[],"mappings":"AAuEA,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAsB;IAC3D,WAAW;IACX,YAAY;IACZ,cAAc;IACd,OAAO;IACP,gBAAgB;CACjB,CAAC,CAAC;AAEH,MAAM,6BAA6B,GAA2B;IAC5D,yBAAyB,EAAE,eAAe;IAC1C,yDAAyD,EACvD,sBAAsB;IACxB,wDAAwD,EACtD,qBAAqB;IACvB,yDAAyD,EACvD,wBAAwB;IAC1B,oEAAoE,EAClE,qCAAqC;IACvC,kDAAkD,EAChD,uBAAuB;IACzB,kDAAkD,EAChD,kBAAkB;IACpB,4EAA4E,EAC1E,0BAA0B;IAC5B,oFAAoF,EAClF,0CAA0C;IAC5C,4DAA4D,EAC1D,yBAAyB;IAC3B,4DAA4D,EAC1D,oBAAoB;IACtB,8EAA8E,EAC5E,gCAAgC;IAClC,mFAAmF,EACjF,iCAAiC;CACpC,CAAC;AAEF,SAAS,oBAAoB,CAAC,OAAqC;IACjE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,KAAK,WAAW,IAAI,OAAO,CAAC,YAAY,KAAK,YAAY,EAAE,CAAC;QAClF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,UAAU,KAAK,KAAK,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,MAAiC;IAEjC,MAAM,UAAU,GAAG,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IACnE,OAAO,UAAU,KAAK,OAAO;WACxB,UAAU,KAAK,SAAS;WACxB,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC;WAC/B,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;QACpC,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,SAAS,uBAAuB,CAC9B,MAA+C,EAC/C,MAAyB;IAEzB,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,QAAQ,MAAM,CAAC,EAAE,EAAE,CAAC;QAClB,KAAK,WAAW;YACd,OAAO,SAAS,CAAC;QACnB,KAAK,YAAY;YACf,OAAO,MAAM,CAAC;QAChB,KAAK,cAAc;YACjB,OAAO,QAAQ,CAAC;QAClB,KAAK,OAAO,CAAC;QACb,KAAK,gBAAgB;YACnB,OAAO,IAAI,CAAC;QACd;YACE,OAAO,MAAM,CAAC,KAAK,CAAC;IACxB,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAe,EAAE,MAAyB;IACrE,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,6BAA6B,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC;AAC3D,CAAC;AAED,SAAS,kBAAkB,CAAC,WAAmB,EAAE,MAAyB;IACxE,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC5B,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;YAChC,CAAC,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvC,CAAC,CAAC,MAAM,OAAO,EAAE,CAAC;IACtB,CAAC;IACD,OAAO,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;QAChC,CAAC,CAAC,QAAQ,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACzC,CAAC,CAAC,QAAQ,OAAO,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,kBAAkB,GAAsD;IAC5E,EAAE,EAAE;QACF,KAAK,EAAE,oBAAoB;QAC3B,QAAQ,EAAE,uBAAuB;QACjC,SAAS,EAAE,mBAAmB;QAC9B,WAAW,EAAE,qBAAqB;QAClC,UAAU,EAAE,oBAAoB;QAChC,UAAU,EAAE,oBAAoB;KACjC;IACD,OAAO,EAAE;QACP,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,SAAS;QACnB,SAAS,EAAE,QAAQ;QACnB,WAAW,EAAE,SAAS;QACtB,UAAU,EAAE,UAAU;QACtB,UAAU,EAAE,SAAS;KACtB;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CACxC,QAAkD,EAClD,WAA2B;IAE3B,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,0BAA0B,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC1C,uEAAuE;IACvE,wDAAwD;IACxD,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,YAAY,KAAK,kBAAkB;QACpE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;QAC9C,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,UAAU,GAAG,CAAC,IAA2B,EAAyB,EAAE,CAAC,CAAC;QAC1E,GAAG,IAAI;QACP,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,GAAG,MAAM,EAAE;KAChC,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,qBAAqB,CAC5B,QAA+B,EAC/B,MAA8B;IAE9B,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxB,KAAK,UAAU;YACb,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACrE,KAAK,kBAAkB;YACrB,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;QAC7E,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC;YAC5D,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,WAAW,IAAI,OAAO,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACzF,CAAC;QACD,KAAK,YAAY;YACf,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;QAC9E,KAAK,YAAY;YACf,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACvE;YACE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IACnE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,OAAyC;IAEzC,MAAM,wBAAwB,GAAG,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,uBAAuB,IAAI,IAAI,CAAC;IACpG,MAAM,MAAM,GAAG,0BAA0B,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,wBAAwB;QACvC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;aACvB,MAAM,CAAC,oBAAoB,CAAC;aAC5B,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACjB,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,WAAY,CAAC,IAAI,EAAE;YACrD,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,WAAY,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC;YAC9D,IAAI,EAAE,OAAO,CAAC,WAAY,CAAC,IAAI,EAAE;SAClC,CAAC,CAAC;QACL,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE,mBAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC;QACrD,eAAe,EAAE,wBAAwB;QACzC,OAAO,EAAE,OAAO,CAAC,OAAO;aACrB,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,uBAAuB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;aAC1D,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAChB,GAAG,MAAM;YACT,KAAK,EAAE,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC;SAC/C,CAAC,CAAC;QACL,QAAQ;QACR,UAAU,EAAE,0BAA0B,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC;KACxE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iCAAiC,CAC/C,WAA2B;IAE3B,MAAM,MAAM,GAAG,0BAA0B,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;IACnE,OAAO;QACL,OAAO,EAAE,WAAW;QACpB,eAAe,EAAE,IAAI;QACrB,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,EAAE;QACZ,WAAW;QACX,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,iBAAiB;KACtE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { DesktopUpdaterAdapter } from './updateManager.js';
2
+ /**
3
+ * Managed-service drain around the installer handoff.
4
+ *
5
+ * `quitAndInstall` ends the process, so without this the Cats runtime and
6
+ * platform sidecars are killed mid-flight rather than drained. On Windows that
7
+ * is not merely untidy: the upgrade runs the previous uninstaller before
8
+ * installing, and a sidecar still holding files in the install directory can
9
+ * make that uninstall or the install that follows fail, which is how an update
10
+ * leaves a broken installation behind.
11
+ *
12
+ * This is a decorator rather than a manager feature so the update state machine
13
+ * stays a state machine, and so the ordering is testable without Electron.
14
+ */
15
+ export interface DesktopInstallHandoffHooks {
16
+ /**
17
+ * Brings managed services down. Resolves once they are stopped, including the
18
+ * forced path when a graceful stop times out.
19
+ */
20
+ drainManagedServices: () => Promise<void>;
21
+ /**
22
+ * Brings managed services back after a handoff that failed while the process
23
+ * was still alive. Without it the app would still be running but with dead
24
+ * sidecars, which is a worse state than the one the user started in.
25
+ */
26
+ restartManagedServices: () => Promise<void>;
27
+ logger?: (message: string) => void;
28
+ }
29
+ export declare function withDesktopInstallHandoff(adapter: DesktopUpdaterAdapter, hooks: DesktopInstallHandoffHooks): DesktopUpdaterAdapter;
30
+ //# sourceMappingURL=updateInstallHandoff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateInstallHandoff.d.ts","sourceRoot":"","sources":["../../desktop/host/updateInstallHandoff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,oBAAoB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,0BAA0B,GAChC,qBAAqB,CA0CvB"}
@@ -0,0 +1,39 @@
1
+ export function withDesktopInstallHandoff(adapter, hooks) {
2
+ const log = hooks.logger ?? (() => { });
3
+ async function restoreAfterFailedHandoff(stage) {
4
+ try {
5
+ await hooks.restartManagedServices();
6
+ }
7
+ catch (restartError) {
8
+ // Nothing further can be done from here. The manager still reports a
9
+ // recoverable state, and the log says why the app may be degraded.
10
+ log(`[desktop-update] managed services did not restart after a failed ${stage}: `
11
+ + `${restartError instanceof Error ? restartError.message : String(restartError)}`);
12
+ }
13
+ }
14
+ return {
15
+ checkForUpdates: adapter.checkForUpdates.bind(adapter),
16
+ downloadUpdate: adapter.downloadUpdate.bind(adapter),
17
+ async quitAndInstall() {
18
+ try {
19
+ await hooks.drainManagedServices();
20
+ }
21
+ catch (drainError) {
22
+ // Handing off now would point the installer at files a surviving
23
+ // sidecar may still hold, so the install is abandoned instead.
24
+ log('[desktop-update] managed services failed to drain; abandoning the installer handoff: '
25
+ + `${drainError instanceof Error ? drainError.message : String(drainError)}`);
26
+ await restoreAfterFailedHandoff('drain');
27
+ throw drainError;
28
+ }
29
+ try {
30
+ await adapter.quitAndInstall();
31
+ }
32
+ catch (handoffError) {
33
+ await restoreAfterFailedHandoff('handoff');
34
+ throw handoffError;
35
+ }
36
+ },
37
+ };
38
+ }
39
+ //# sourceMappingURL=updateInstallHandoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateInstallHandoff.js","sourceRoot":"","sources":["../../desktop/host/updateInstallHandoff.ts"],"names":[],"mappings":"AA+BA,MAAM,UAAU,yBAAyB,CACvC,OAA8B,EAC9B,KAAiC;IAEjC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEvC,KAAK,UAAU,yBAAyB,CAAC,KAAa;QACpD,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,sBAAsB,EAAE,CAAC;QACvC,CAAC;QAAC,OAAO,YAAY,EAAE,CAAC;YACtB,qEAAqE;YACrE,mEAAmE;YACnE,GAAG,CACD,oEAAoE,KAAK,IAAI;kBACzE,GAAG,YAAY,YAAY,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CACrF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,eAAe,EAAE,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC;QACtD,cAAc,EAAE,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;QAEpD,KAAK,CAAC,cAAc;YAClB,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,oBAAoB,EAAE,CAAC;YACrC,CAAC;YAAC,OAAO,UAAU,EAAE,CAAC;gBACpB,iEAAiE;gBACjE,+DAA+D;gBAC/D,GAAG,CACD,uFAAuF;sBACnF,GAAG,UAAU,YAAY,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAC/E,CAAC;gBACF,MAAM,yBAAyB,CAAC,OAAO,CAAC,CAAC;gBACzC,MAAM,UAAU,CAAC;YACnB,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC;YACjC,CAAC;YAAC,OAAO,YAAY,EAAE,CAAC;gBACtB,MAAM,yBAAyB,CAAC,SAAS,CAAC,CAAC;gBAC3C,MAAM,YAAY,CAAC;YACrB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { DesktopUpdateSnapshot } from './contracts.js';
2
+ import type { DesktopUpdateManager } from './updateManager.js';
3
+ /**
4
+ * Bounded IPC surface for the host-owned update manager.
5
+ *
6
+ * SPEC-111 section 3: every command takes no arguments, so a renderer cannot
7
+ * supply a feed URL, filesystem destination, shell command, executable path, or
8
+ * installer flag. Every handler also verifies the sender is the current Cats
9
+ * main window before touching the manager.
10
+ */
11
+ export declare const DESKTOP_UPDATE_IPC_CHANNELS: {
12
+ readonly snapshot: "cats-host:update-get-snapshot";
13
+ readonly check: "cats-host:update-check";
14
+ readonly download: "cats-host:update-download";
15
+ readonly install: "cats-host:update-install";
16
+ readonly event: "cats-host:update-event";
17
+ };
18
+ export interface DesktopUpdateIpcEvent {
19
+ sender: unknown;
20
+ }
21
+ export interface DesktopUpdateWebContentsLike {
22
+ isDestroyed?: () => boolean;
23
+ send: (channel: string, payload: unknown) => void;
24
+ }
25
+ export declare function isDesktopUpdateIpcSenderTrusted(event: DesktopUpdateIpcEvent, mainWindowWebContents: unknown): boolean;
26
+ export interface CreateDesktopUpdateIpcHandlersInput {
27
+ manager: DesktopUpdateManager;
28
+ resolveMainWindowWebContents: () => unknown;
29
+ logger?: (message: string) => void;
30
+ }
31
+ export type DesktopUpdateIpcHandlers = Record<string, (event: DesktopUpdateIpcEvent) => Promise<DesktopUpdateSnapshot | void>>;
32
+ export declare function createDesktopUpdateIpcHandlers(input: CreateDesktopUpdateIpcHandlersInput): DesktopUpdateIpcHandlers;
33
+ export interface CreateDesktopUpdateSnapshotBroadcastInput {
34
+ manager: DesktopUpdateManager;
35
+ resolveMainWindowWebContents: () => DesktopUpdateWebContentsLike | null;
36
+ }
37
+ /**
38
+ * Streams manager snapshots to the main window. Returns the unsubscribe
39
+ * function so the caller can detach deterministically during shutdown.
40
+ */
41
+ export declare function createDesktopUpdateSnapshotBroadcast(input: CreateDesktopUpdateSnapshotBroadcastInput): () => void;
42
+ //# sourceMappingURL=updateIpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateIpc.d.ts","sourceRoot":"","sources":["../../desktop/host/updateIpc.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE/D;;;;;;;GAOG;AAEH,eAAO,MAAM,2BAA2B;;;;;;CAM9B,CAAC;AAEX,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;IAC5B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,qBAAqB,EAC5B,qBAAqB,EAAE,OAAO,GAC7B,OAAO,CAKT;AAED,MAAM,WAAW,mCAAmC;IAClD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,4BAA4B,EAAE,MAAM,OAAO,CAAC;IAC5C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAC3C,MAAM,EACN,CAAC,KAAK,EAAE,qBAAqB,KAAK,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CACxE,CAAC;AAEF,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,mCAAmC,GACzC,wBAAwB,CAgC1B;AAED,MAAM,WAAW,yCAAyC;IACxD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,4BAA4B,EAAE,MAAM,4BAA4B,GAAG,IAAI,CAAC;CACzE;AAED;;;GAGG;AACH,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,yCAAyC,GAC/C,MAAM,IAAI,CAaZ"}
@@ -0,0 +1,71 @@
1
+ import { DESKTOP_UPDATE_CHECK_CHANNEL, DESKTOP_UPDATE_DOWNLOAD_CHANNEL, DESKTOP_UPDATE_EVENT_CHANNEL, DESKTOP_UPDATE_INSTALL_CHANNEL, DESKTOP_UPDATE_SNAPSHOT_CHANNEL, } from './contracts.js';
2
+ /**
3
+ * Bounded IPC surface for the host-owned update manager.
4
+ *
5
+ * SPEC-111 section 3: every command takes no arguments, so a renderer cannot
6
+ * supply a feed URL, filesystem destination, shell command, executable path, or
7
+ * installer flag. Every handler also verifies the sender is the current Cats
8
+ * main window before touching the manager.
9
+ */
10
+ export const DESKTOP_UPDATE_IPC_CHANNELS = {
11
+ snapshot: DESKTOP_UPDATE_SNAPSHOT_CHANNEL,
12
+ check: DESKTOP_UPDATE_CHECK_CHANNEL,
13
+ download: DESKTOP_UPDATE_DOWNLOAD_CHANNEL,
14
+ install: DESKTOP_UPDATE_INSTALL_CHANNEL,
15
+ event: DESKTOP_UPDATE_EVENT_CHANNEL,
16
+ };
17
+ export function isDesktopUpdateIpcSenderTrusted(event, mainWindowWebContents) {
18
+ if (mainWindowWebContents === null || mainWindowWebContents === undefined) {
19
+ return false;
20
+ }
21
+ return event.sender === mainWindowWebContents;
22
+ }
23
+ export function createDesktopUpdateIpcHandlers(input) {
24
+ const { manager, resolveMainWindowWebContents } = input;
25
+ const logger = input.logger ?? (() => { });
26
+ function assertTrusted(event, channel) {
27
+ if (isDesktopUpdateIpcSenderTrusted(event, resolveMainWindowWebContents())) {
28
+ return;
29
+ }
30
+ logger(`[desktop-update] rejected ${channel} from an untrusted sender.`);
31
+ // Deliberately generic: the renderer learns the command was refused and
32
+ // nothing about the host window topology.
33
+ throw new Error('Update command rejected.');
34
+ }
35
+ return {
36
+ [DESKTOP_UPDATE_IPC_CHANNELS.snapshot]: async (event) => {
37
+ assertTrusted(event, DESKTOP_UPDATE_IPC_CHANNELS.snapshot);
38
+ return manager.getSnapshot();
39
+ },
40
+ [DESKTOP_UPDATE_IPC_CHANNELS.check]: async (event) => {
41
+ assertTrusted(event, DESKTOP_UPDATE_IPC_CHANNELS.check);
42
+ return manager.checkForUpdates();
43
+ },
44
+ [DESKTOP_UPDATE_IPC_CHANNELS.download]: async (event) => {
45
+ assertTrusted(event, DESKTOP_UPDATE_IPC_CHANNELS.download);
46
+ return manager.downloadUpdate();
47
+ },
48
+ [DESKTOP_UPDATE_IPC_CHANNELS.install]: async (event) => {
49
+ assertTrusted(event, DESKTOP_UPDATE_IPC_CHANNELS.install);
50
+ await manager.restartAndInstall();
51
+ },
52
+ };
53
+ }
54
+ /**
55
+ * Streams manager snapshots to the main window. Returns the unsubscribe
56
+ * function so the caller can detach deterministically during shutdown.
57
+ */
58
+ export function createDesktopUpdateSnapshotBroadcast(input) {
59
+ const { manager, resolveMainWindowWebContents } = input;
60
+ return manager.subscribe((snapshot) => {
61
+ const webContents = resolveMainWindowWebContents();
62
+ if (webContents === null || webContents === undefined) {
63
+ return;
64
+ }
65
+ if (webContents.isDestroyed?.() === true) {
66
+ return;
67
+ }
68
+ webContents.send(DESKTOP_UPDATE_IPC_CHANNELS.event, snapshot);
69
+ });
70
+ }
71
+ //# sourceMappingURL=updateIpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateIpc.js","sourceRoot":"","sources":["../../desktop/host/updateIpc.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,EAC/B,4BAA4B,EAC5B,8BAA8B,EAC9B,+BAA+B,GAChC,MAAM,gBAAgB,CAAC;AAIxB;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,QAAQ,EAAE,+BAA+B;IACzC,KAAK,EAAE,4BAA4B;IACnC,QAAQ,EAAE,+BAA+B;IACzC,OAAO,EAAE,8BAA8B;IACvC,KAAK,EAAE,4BAA4B;CAC3B,CAAC;AAWX,MAAM,UAAU,+BAA+B,CAC7C,KAA4B,EAC5B,qBAA8B;IAE9B,IAAI,qBAAqB,KAAK,IAAI,IAAI,qBAAqB,KAAK,SAAS,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,KAAK,qBAAqB,CAAC;AAChD,CAAC;AAaD,MAAM,UAAU,8BAA8B,CAC5C,KAA0C;IAE1C,MAAM,EAAE,OAAO,EAAE,4BAA4B,EAAE,GAAG,KAAK,CAAC;IACxD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAE1C,SAAS,aAAa,CAAC,KAA4B,EAAE,OAAe;QAClE,IAAI,+BAA+B,CAAC,KAAK,EAAE,4BAA4B,EAAE,CAAC,EAAE,CAAC;YAC3E,OAAO;QACT,CAAC;QACD,MAAM,CAAC,6BAA6B,OAAO,4BAA4B,CAAC,CAAC;QACzE,wEAAwE;QACxE,0CAA0C;QAC1C,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO;QACL,CAAC,2BAA2B,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACtD,aAAa,CAAC,KAAK,EAAE,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YAC3D,OAAO,OAAO,CAAC,WAAW,EAAE,CAAC;QAC/B,CAAC;QACD,CAAC,2BAA2B,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACnD,aAAa,CAAC,KAAK,EAAE,2BAA2B,CAAC,KAAK,CAAC,CAAC;YACxD,OAAO,OAAO,CAAC,eAAe,EAAE,CAAC;QACnC,CAAC;QACD,CAAC,2BAA2B,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACtD,aAAa,CAAC,KAAK,EAAE,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YAC3D,OAAO,OAAO,CAAC,cAAc,EAAE,CAAC;QAClC,CAAC;QACD,CAAC,2BAA2B,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACrD,aAAa,CAAC,KAAK,EAAE,2BAA2B,CAAC,OAAO,CAAC,CAAC;YAC1D,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC;AAOD;;;GAGG;AACH,MAAM,UAAU,oCAAoC,CAClD,KAAgD;IAEhD,MAAM,EAAE,OAAO,EAAE,4BAA4B,EAAE,GAAG,KAAK,CAAC;IAExD,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE;QACpC,MAAM,WAAW,GAAG,4BAA4B,EAAE,CAAC;QACnD,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YACtD,OAAO;QACT,CAAC;QACD,IAAI,WAAW,CAAC,WAAW,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC;YACzC,OAAO;QACT,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,2BAA2B,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,76 @@
1
+ import type { DesktopUpdateCapability, DesktopUpdateError, DesktopUpdateNextAction, DesktopUpdateProgress, DesktopUpdateSnapshot, DesktopUpdateStatus } from './contracts.js';
2
+ import type { DesktopDistributionIdentity, DesktopReleasePlatform } from './releaseDescriptor.js';
3
+ /**
4
+ * Host-owned update state machine.
5
+ *
6
+ * The renderer and tray are presentation surfaces over this one manager. They
7
+ * request bounded actions and observe snapshots; they never choose a feed, a
8
+ * URL, a file, or installer arguments.
9
+ *
10
+ * The provider is reached through an injected adapter so tests exercise the
11
+ * lifecycle without live GitHub requests.
12
+ */
13
+ /**
14
+ * Platforms whose signed old-version-to-new-version upgrade path has passed.
15
+ *
16
+ * PLAN-101 gate G3 admits one platform at a time, and SPEC-111 section 9 keeps
17
+ * Windows and macOS self-update disabled until signing is validated. The list
18
+ * is empty on purpose: no platform has passed yet, so no build advertises
19
+ * self-update even when it carries a valid release descriptor.
20
+ */
21
+ export declare const DESKTOP_RELEASE_READY_PLATFORMS: readonly DesktopReleasePlatform[];
22
+ export interface DesktopUpdaterCheckResult {
23
+ updateAvailable: boolean;
24
+ version: string | null;
25
+ releaseSummary: string | null;
26
+ }
27
+ export interface DesktopUpdaterAdapter {
28
+ checkForUpdates(): Promise<DesktopUpdaterCheckResult>;
29
+ downloadUpdate(onProgress: (progress: DesktopUpdateProgress) => void): Promise<void>;
30
+ quitAndInstall(): Promise<void>;
31
+ }
32
+ export interface CreateDesktopUpdateCapabilityInput {
33
+ identity: DesktopDistributionIdentity;
34
+ nodePlatform: NodeJS.Platform | string;
35
+ releaseReadyPlatforms?: readonly DesktopReleasePlatform[];
36
+ }
37
+ export declare function createDesktopUpdateCapability(input: CreateDesktopUpdateCapabilityInput): DesktopUpdateCapability;
38
+ /**
39
+ * The snapshot a build without update capability publishes.
40
+ *
41
+ * Used as the fallback wherever a snapshot is required before the manager
42
+ * exists, so those code paths cannot accidentally imply an update is possible.
43
+ */
44
+ export declare function createUnavailableDesktopUpdateSnapshot(currentVersion: string): DesktopUpdateSnapshot;
45
+ export declare function resolveDesktopUpdateNextAction(status: DesktopUpdateStatus, capability: DesktopUpdateCapability): DesktopUpdateNextAction;
46
+ /**
47
+ * Maps a provider error to a stable code plus copy that is safe to render.
48
+ *
49
+ * The returned summary is an English fallback only. Renderer surfaces localize
50
+ * from the code through the shared i18n catalogs, so the raw provider message
51
+ * never reaches the UI.
52
+ */
53
+ export declare function mapDesktopUpdateError(error: unknown): DesktopUpdateError;
54
+ export declare function redactDesktopUpdateDiagnostic(message: string): string;
55
+ export interface CreateDesktopUpdateManagerInput {
56
+ capability: DesktopUpdateCapability;
57
+ adapter: DesktopUpdaterAdapter | null;
58
+ now?: () => Date;
59
+ logger?: (message: string) => void;
60
+ /**
61
+ * Restored from the host state file. It is the only update fact worth
62
+ * carrying across a restart: a provider-dependent status such as
63
+ * update_available cannot be acted on in a new process without checking
64
+ * again, so restoring it would offer a download the manager cannot perform.
65
+ */
66
+ initialLastCheckedAt?: string | null;
67
+ }
68
+ export interface DesktopUpdateManager {
69
+ getSnapshot(): DesktopUpdateSnapshot;
70
+ subscribe(listener: (snapshot: DesktopUpdateSnapshot) => void): () => void;
71
+ checkForUpdates(): Promise<DesktopUpdateSnapshot>;
72
+ downloadUpdate(): Promise<DesktopUpdateSnapshot>;
73
+ restartAndInstall(): Promise<DesktopUpdateSnapshot>;
74
+ }
75
+ export declare function createDesktopUpdateManager(input: CreateDesktopUpdateManagerInput): DesktopUpdateManager;
76
+ //# sourceMappingURL=updateManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateManager.d.ts","sourceRoot":"","sources":["../../desktop/host/updateManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,kBAAkB,EAElB,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,2BAA2B,EAC3B,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAGhC;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,EAAE,SAAS,sBAAsB,EAAO,CAAC;AAErF,MAAM,WAAW,yBAAyB;IACxC,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACtD,cAAc,CACZ,UAAU,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI,GACpD,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,kCAAkC;IACjD,QAAQ,EAAE,2BAA2B,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC;IACvC,qBAAqB,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAC3D;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,kCAAkC,GACxC,uBAAuB,CA0DzB;AAED;;;;;GAKG;AACH,wBAAgB,sCAAsC,CACpD,cAAc,EAAE,MAAM,GACrB,qBAAqB,CAqBvB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,mBAAmB,EAC3B,UAAU,EAAE,uBAAuB,GAClC,uBAAuB,CAiBzB;AA0BD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAcxE;AAQD,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKrE;AAMD,MAAM,WAAW,+BAA+B;IAC9C,UAAU,EAAE,uBAAuB,CAAC;IACpC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,IAAI,qBAAqB,CAAC;IACrC,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC3E,eAAe,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAClD,cAAc,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACjD,iBAAiB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACrD;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,+BAA+B,GACrC,oBAAoB,CAkMtB"}
@@ -0,0 +1,342 @@
1
+ import { resolveDesktopReleasePlatform } from './releaseDescriptor.js';
2
+ /**
3
+ * Host-owned update state machine.
4
+ *
5
+ * The renderer and tray are presentation surfaces over this one manager. They
6
+ * request bounded actions and observe snapshots; they never choose a feed, a
7
+ * URL, a file, or installer arguments.
8
+ *
9
+ * The provider is reached through an injected adapter so tests exercise the
10
+ * lifecycle without live GitHub requests.
11
+ */
12
+ /**
13
+ * Platforms whose signed old-version-to-new-version upgrade path has passed.
14
+ *
15
+ * PLAN-101 gate G3 admits one platform at a time, and SPEC-111 section 9 keeps
16
+ * Windows and macOS self-update disabled until signing is validated. The list
17
+ * is empty on purpose: no platform has passed yet, so no build advertises
18
+ * self-update even when it carries a valid release descriptor.
19
+ */
20
+ export const DESKTOP_RELEASE_READY_PLATFORMS = [];
21
+ export function createDesktopUpdateCapability(input) {
22
+ const { identity, nodePlatform } = input;
23
+ const releaseReadyPlatforms = input.releaseReadyPlatforms ?? DESKTOP_RELEASE_READY_PLATFORMS;
24
+ const base = {
25
+ distribution: identity.distribution,
26
+ channel: identity.channel,
27
+ currentVersion: identity.currentVersion,
28
+ };
29
+ const packagedFromWorkflow = identity.distribution === 'official_packaged'
30
+ || identity.distribution === 'preview_packaged';
31
+ if (!packagedFromWorkflow || identity.provider !== 'github_release') {
32
+ return {
33
+ ...base,
34
+ provider: 'none',
35
+ canCheck: false,
36
+ canDownload: false,
37
+ canInstall: false,
38
+ unavailableReason: identity.unavailableReason,
39
+ };
40
+ }
41
+ const platform = resolveDesktopReleasePlatform(nodePlatform);
42
+ if (platform === null) {
43
+ return {
44
+ ...base,
45
+ provider: 'github_release',
46
+ canCheck: false,
47
+ canDownload: false,
48
+ canInstall: false,
49
+ unavailableReason: 'platform_not_release_ready',
50
+ };
51
+ }
52
+ // The release-ready gate exists so a stable build cannot advertise
53
+ // self-update before its signed upgrade test passes. A preview build is how
54
+ // that test is run, so the gate does not apply to it.
55
+ if (identity.distribution === 'official_packaged' && !releaseReadyPlatforms.includes(platform)) {
56
+ return {
57
+ ...base,
58
+ provider: 'github_release',
59
+ canCheck: false,
60
+ canDownload: false,
61
+ canInstall: false,
62
+ unavailableReason: 'platform_not_release_ready',
63
+ };
64
+ }
65
+ return {
66
+ ...base,
67
+ provider: 'github_release',
68
+ canCheck: true,
69
+ canDownload: true,
70
+ canInstall: true,
71
+ unavailableReason: null,
72
+ };
73
+ }
74
+ /**
75
+ * The snapshot a build without update capability publishes.
76
+ *
77
+ * Used as the fallback wherever a snapshot is required before the manager
78
+ * exists, so those code paths cannot accidentally imply an update is possible.
79
+ */
80
+ export function createUnavailableDesktopUpdateSnapshot(currentVersion) {
81
+ return {
82
+ capability: {
83
+ distribution: 'unofficial_packaged',
84
+ provider: 'none',
85
+ channel: 'stable',
86
+ currentVersion,
87
+ canCheck: false,
88
+ canDownload: false,
89
+ canInstall: false,
90
+ unavailableReason: 'descriptor_missing',
91
+ },
92
+ status: 'unavailable',
93
+ currentVersion,
94
+ availableVersion: null,
95
+ releaseSummary: null,
96
+ lastCheckedAt: null,
97
+ progress: null,
98
+ error: null,
99
+ nextAction: 'none',
100
+ };
101
+ }
102
+ export function resolveDesktopUpdateNextAction(status, capability) {
103
+ if (!capability.canCheck) {
104
+ return 'none';
105
+ }
106
+ switch (status) {
107
+ case 'idle':
108
+ case 'up_to_date':
109
+ case 'failed':
110
+ return 'check';
111
+ case 'update_available':
112
+ return capability.canDownload ? 'download' : 'none';
113
+ case 'downloaded':
114
+ return capability.canInstall ? 'restart_install' : 'none';
115
+ default:
116
+ return 'none';
117
+ }
118
+ }
119
+ const ERROR_SUMMARIES = {
120
+ offline: 'Cats could not reach the update service.',
121
+ timeout: 'The update service did not respond in time.',
122
+ provider_rejected: 'The update service rejected the request.',
123
+ metadata_invalid: 'The update information could not be read.',
124
+ checksum_mismatch: 'The downloaded update failed its integrity check.',
125
+ signature_rejected: 'The downloaded update failed its signature check.',
126
+ unsupported_package: 'This installation cannot update itself.',
127
+ download_cancelled: 'The update download was cancelled.',
128
+ install_handoff_failed: 'Cats could not hand off to the installer.',
129
+ unknown: 'The update could not be completed.',
130
+ };
131
+ const ERROR_CODE_PATTERNS = [
132
+ ['offline', /enotfound|eai_again|econnrefused|econnreset|enetunreach|offline|dns/iu],
133
+ ['timeout', /etimedout|timed? ?out|esockettimedout/iu],
134
+ ['checksum_mismatch', /sha512|sha256|checksum|integrity/iu],
135
+ ['signature_rejected', /signature|publishername|not signed|authenticode/iu],
136
+ ['download_cancelled', /cancel/iu],
137
+ ['unsupported_package', /unsupported|not supported|no published versions|dev-app-update/iu],
138
+ ['metadata_invalid', /latest\.yml|latest-mac\.yml|metadata|unable to parse|invalid yml/iu],
139
+ ['provider_rejected', /http (4|5)\d\d|status code (4|5)\d\d|forbidden|not found|rate limit/iu],
140
+ ];
141
+ /**
142
+ * Maps a provider error to a stable code plus copy that is safe to render.
143
+ *
144
+ * The returned summary is an English fallback only. Renderer surfaces localize
145
+ * from the code through the shared i18n catalogs, so the raw provider message
146
+ * never reaches the UI.
147
+ */
148
+ export function mapDesktopUpdateError(error) {
149
+ const haystack = [
150
+ typeof error === 'string' ? error : '',
151
+ error instanceof Error ? error.message : '',
152
+ isRecord(error) && typeof error.code === 'string' ? error.code : '',
153
+ ].join(' ');
154
+ for (const [code, pattern] of ERROR_CODE_PATTERNS) {
155
+ if (pattern.test(haystack)) {
156
+ return { code, summary: ERROR_SUMMARIES[code] };
157
+ }
158
+ }
159
+ return { code: 'unknown', summary: ERROR_SUMMARIES.unknown };
160
+ }
161
+ const SECRET_PATTERNS = [
162
+ /gh[pousr]_[A-Za-z0-9_]{16,}/gu,
163
+ /github_pat_[A-Za-z0-9_]{20,}/gu,
164
+ /(authorization|token|password|secret)"?\s*[:=]\s*"?[^\s",}]+/giu,
165
+ ];
166
+ export function redactDesktopUpdateDiagnostic(message) {
167
+ return SECRET_PATTERNS.reduce((redacted, pattern) => redacted.replace(pattern, '[redacted]'), message);
168
+ }
169
+ function isRecord(value) {
170
+ return typeof value === 'object' && value !== null;
171
+ }
172
+ export function createDesktopUpdateManager(input) {
173
+ const { capability, adapter } = input;
174
+ const now = input.now ?? (() => new Date());
175
+ const logger = input.logger ?? (() => { });
176
+ const usable = capability.canCheck && adapter !== null;
177
+ let status = usable ? 'idle' : 'unavailable';
178
+ let availableVersion = null;
179
+ let releaseSummary = null;
180
+ let lastCheckedAt = input.initialLastCheckedAt ?? null;
181
+ let progress = null;
182
+ let error = null;
183
+ // SPEC-111 section 2 allows one check or download at a time. Repeated
184
+ // requests join the in-flight operation instead of starting a second
185
+ // provider request.
186
+ let pendingCheck = null;
187
+ let pendingDownload = null;
188
+ const listeners = new Set();
189
+ function snapshot() {
190
+ return {
191
+ capability,
192
+ status,
193
+ currentVersion: capability.currentVersion,
194
+ availableVersion,
195
+ releaseSummary,
196
+ lastCheckedAt,
197
+ progress,
198
+ error,
199
+ nextAction: resolveDesktopUpdateNextAction(status, capability),
200
+ };
201
+ }
202
+ function publish() {
203
+ const current = snapshot();
204
+ for (const listener of listeners) {
205
+ listener(current);
206
+ }
207
+ return current;
208
+ }
209
+ function log(message) {
210
+ logger(redactDesktopUpdateDiagnostic(message));
211
+ }
212
+ function fail(cause, stage) {
213
+ error = mapDesktopUpdateError(cause);
214
+ status = 'failed';
215
+ progress = null;
216
+ log(`[desktop-update] ${stage} failed (${error.code}): `
217
+ + `${cause instanceof Error ? cause.message : String(cause)}`);
218
+ return publish();
219
+ }
220
+ async function runCheck(activeAdapter) {
221
+ status = 'checking';
222
+ error = null;
223
+ publish();
224
+ try {
225
+ const result = await activeAdapter.checkForUpdates();
226
+ lastCheckedAt = now().toISOString();
227
+ if (!result.updateAvailable) {
228
+ status = 'up_to_date';
229
+ availableVersion = null;
230
+ releaseSummary = null;
231
+ return publish();
232
+ }
233
+ if (result.version === null || result.version.trim() === '') {
234
+ throw new Error('Provider reported an available update without a version.');
235
+ }
236
+ status = 'update_available';
237
+ availableVersion = result.version;
238
+ releaseSummary = result.releaseSummary;
239
+ return publish();
240
+ }
241
+ catch (cause) {
242
+ lastCheckedAt = now().toISOString();
243
+ return fail(cause, 'check');
244
+ }
245
+ }
246
+ async function runDownload(activeAdapter) {
247
+ status = 'downloading';
248
+ error = null;
249
+ progress = { percent: 0, transferredBytes: 0, totalBytes: 0, bytesPerSecond: 0 };
250
+ publish();
251
+ try {
252
+ await activeAdapter.downloadUpdate((next) => {
253
+ // A late progress event after a failure must not resurrect the
254
+ // downloading state.
255
+ if (status !== 'downloading') {
256
+ return;
257
+ }
258
+ progress = next;
259
+ publish();
260
+ });
261
+ status = 'downloaded';
262
+ progress = null;
263
+ return publish();
264
+ }
265
+ catch (cause) {
266
+ return fail(cause, 'download');
267
+ }
268
+ }
269
+ return {
270
+ getSnapshot: snapshot,
271
+ subscribe(listener) {
272
+ listeners.add(listener);
273
+ return () => {
274
+ listeners.delete(listener);
275
+ };
276
+ },
277
+ async checkForUpdates() {
278
+ if (!usable || adapter === null) {
279
+ return snapshot();
280
+ }
281
+ if (pendingDownload !== null) {
282
+ return pendingDownload;
283
+ }
284
+ if (pendingCheck !== null) {
285
+ return pendingCheck;
286
+ }
287
+ pendingCheck = runCheck(adapter).finally(() => {
288
+ pendingCheck = null;
289
+ });
290
+ return pendingCheck;
291
+ },
292
+ async downloadUpdate() {
293
+ if (!usable || adapter === null || !capability.canDownload) {
294
+ return snapshot();
295
+ }
296
+ if (pendingDownload !== null) {
297
+ return pendingDownload;
298
+ }
299
+ if (pendingCheck !== null) {
300
+ return pendingCheck;
301
+ }
302
+ // Automatic download stays disabled: only an explicit request from a
303
+ // surface reaches here, and only from update_available.
304
+ if (status !== 'update_available') {
305
+ return snapshot();
306
+ }
307
+ pendingDownload = runDownload(adapter).finally(() => {
308
+ pendingDownload = null;
309
+ });
310
+ return pendingDownload;
311
+ },
312
+ async restartAndInstall() {
313
+ if (!usable || adapter === null || !capability.canInstall) {
314
+ return snapshot();
315
+ }
316
+ if (status !== 'downloaded') {
317
+ return snapshot();
318
+ }
319
+ status = 'installing';
320
+ error = null;
321
+ publish();
322
+ try {
323
+ await adapter.quitAndInstall();
324
+ return snapshot();
325
+ }
326
+ catch (cause) {
327
+ log('[desktop-update] install handoff failed: '
328
+ + `${cause instanceof Error ? cause.message : String(cause)}`);
329
+ // The handoff failed before the process exited, so the downloaded
330
+ // update is still installable and the user can retry it.
331
+ status = 'downloaded';
332
+ progress = null;
333
+ error = {
334
+ code: 'install_handoff_failed',
335
+ summary: ERROR_SUMMARIES.install_handoff_failed,
336
+ };
337
+ return publish();
338
+ }
339
+ },
340
+ };
341
+ }
342
+ //# sourceMappingURL=updateManager.js.map