waybetter 0.1.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (537) hide show
  1. package/README.md +139 -6
  2. package/bin/waybetter.mjs +43 -0
  3. package/build/runtime.mjs +105 -0
  4. package/cli/buildenv.mjs +130 -0
  5. package/cli/dev.mjs +97 -0
  6. package/cli/i18n.mjs +382 -0
  7. package/cli/manifests.mjs +383 -0
  8. package/cli/release.mjs +437 -0
  9. package/cli/releasecheck.mjs +15 -0
  10. package/cli/remote.mjs +260 -0
  11. package/cli/store.mjs +378 -0
  12. package/cli/strings.mjs +123 -0
  13. package/dist/runtime/column.d.ts +93 -0
  14. package/dist/runtime/column.js +451 -0
  15. package/dist/runtime/column.js.map +1 -0
  16. package/dist/runtime/commandReport.d.ts +19 -0
  17. package/dist/runtime/commandReport.js +47 -0
  18. package/dist/runtime/commandReport.js.map +1 -0
  19. package/dist/runtime/commands.d.ts +72 -0
  20. package/dist/runtime/commands.js +214 -0
  21. package/dist/runtime/commands.js.map +1 -0
  22. package/dist/runtime/devErrors.d.ts +16 -0
  23. package/dist/runtime/devErrors.js +30 -0
  24. package/dist/runtime/devErrors.js.map +1 -0
  25. package/dist/runtime/domHub.d.ts +21 -0
  26. package/dist/runtime/domHub.js +139 -4
  27. package/dist/runtime/domHub.js.map +1 -1
  28. package/dist/runtime/featureModules.d.ts +157 -0
  29. package/dist/runtime/featureModules.js +484 -0
  30. package/dist/runtime/featureModules.js.map +1 -0
  31. package/dist/runtime/featureTable.d.ts +144 -0
  32. package/dist/runtime/featureTable.js +223 -0
  33. package/dist/runtime/featureTable.js.map +1 -0
  34. package/dist/runtime/fonts.d.ts +22 -0
  35. package/dist/runtime/fonts.js +72 -0
  36. package/dist/runtime/fonts.js.map +1 -0
  37. package/dist/runtime/i18n.d.ts +138 -0
  38. package/dist/runtime/i18n.js +614 -0
  39. package/dist/runtime/i18n.js.map +1 -0
  40. package/dist/runtime/i18nCheck.d.ts +30 -0
  41. package/dist/runtime/i18nCheck.js +224 -0
  42. package/dist/runtime/i18nCheck.js.map +1 -0
  43. package/dist/runtime/pageLang.d.ts +8 -0
  44. package/dist/runtime/pageLang.js +64 -0
  45. package/dist/runtime/pageLang.js.map +1 -0
  46. package/dist/runtime/pageStrings.d.ts +35 -0
  47. package/dist/runtime/pageStrings.js +76 -0
  48. package/dist/runtime/pageStrings.js.map +1 -0
  49. package/dist/runtime/panelButton.d.ts +33 -0
  50. package/dist/runtime/panelButton.js +83 -0
  51. package/dist/runtime/panelButton.js.map +1 -0
  52. package/dist/runtime/permissions.d.ts +47 -0
  53. package/dist/runtime/permissions.js +141 -0
  54. package/dist/runtime/permissions.js.map +1 -0
  55. package/dist/runtime/pluginApi.d.ts +51 -2
  56. package/dist/runtime/pluginApi.js +137 -22
  57. package/dist/runtime/pluginApi.js.map +1 -1
  58. package/dist/runtime/pluginI18n.d.ts +29 -0
  59. package/dist/runtime/pluginI18n.js +119 -0
  60. package/dist/runtime/pluginI18n.js.map +1 -0
  61. package/dist/runtime/settingsForm.d.ts +66 -0
  62. package/dist/runtime/settingsForm.js +114 -0
  63. package/dist/runtime/settingsForm.js.map +1 -0
  64. package/dist/runtime/site.d.ts +5 -0
  65. package/dist/runtime/site.js +1 -1
  66. package/dist/runtime/site.js.map +1 -1
  67. package/dist/runtime/siteRuntime.d.ts +144 -0
  68. package/dist/runtime/siteRuntime.js +175 -0
  69. package/dist/runtime/siteRuntime.js.map +1 -0
  70. package/dist/runtime/stringPackHook.d.ts +84 -0
  71. package/dist/runtime/stringPackHook.js +220 -0
  72. package/dist/runtime/stringPackHook.js.map +1 -0
  73. package/dist/runtime/stringPackTranslate.d.ts +61 -0
  74. package/dist/runtime/stringPackTranslate.js +267 -0
  75. package/dist/runtime/stringPackTranslate.js.map +1 -0
  76. package/dist/runtime/stringPacks.d.ts +248 -0
  77. package/dist/runtime/stringPacks.js +610 -0
  78. package/dist/runtime/stringPacks.js.map +1 -0
  79. package/dist/runtime/styles.d.ts +15 -0
  80. package/dist/runtime/styles.js +81 -0
  81. package/dist/runtime/styles.js.map +1 -0
  82. package/dist/runtime/textNet.d.ts +15 -0
  83. package/dist/runtime/textNet.js +131 -0
  84. package/dist/runtime/textNet.js.map +1 -0
  85. package/dist/runtime/themeApi.d.ts +121 -0
  86. package/dist/runtime/themeApi.js +220 -0
  87. package/dist/runtime/themeApi.js.map +1 -0
  88. package/dist/runtime/themeBar.d.ts +28 -0
  89. package/dist/runtime/themeBar.js +82 -0
  90. package/dist/runtime/themeBar.js.map +1 -0
  91. package/dist/runtime/themeChoice.d.ts +52 -0
  92. package/dist/runtime/themeChoice.js +69 -0
  93. package/dist/runtime/themeChoice.js.map +1 -0
  94. package/dist/runtime/themeComponents.d.ts +435 -0
  95. package/dist/runtime/themeComponents.js +476 -0
  96. package/dist/runtime/themeComponents.js.map +1 -0
  97. package/dist/runtime/themeDecor.d.ts +73 -0
  98. package/dist/runtime/themeDecor.js +133 -0
  99. package/dist/runtime/themeDecor.js.map +1 -0
  100. package/dist/runtime/themeDerive.d.ts +69 -0
  101. package/dist/runtime/themeDerive.js +117 -0
  102. package/dist/runtime/themeDerive.js.map +1 -0
  103. package/dist/runtime/themeDoctor.d.ts +52 -0
  104. package/dist/runtime/themeDoctor.js +112 -0
  105. package/dist/runtime/themeDoctor.js.map +1 -0
  106. package/dist/runtime/themeGuards.d.ts +60 -0
  107. package/dist/runtime/themeGuards.js +235 -0
  108. package/dist/runtime/themeGuards.js.map +1 -0
  109. package/dist/runtime/themeIcons.d.ts +130 -0
  110. package/dist/runtime/themeIcons.js +271 -0
  111. package/dist/runtime/themeIcons.js.map +1 -0
  112. package/dist/runtime/themeInk.d.ts +37 -0
  113. package/dist/runtime/themeInk.js +111 -0
  114. package/dist/runtime/themeInk.js.map +1 -0
  115. package/dist/runtime/themeInvariants.d.ts +39 -0
  116. package/dist/runtime/themeInvariants.js +273 -0
  117. package/dist/runtime/themeInvariants.js.map +1 -0
  118. package/dist/runtime/themeRuntime.d.ts +114 -0
  119. package/dist/runtime/themeRuntime.js +570 -0
  120. package/dist/runtime/themeRuntime.js.map +1 -0
  121. package/dist/runtime/themeSchema.d.ts +10 -0
  122. package/dist/runtime/themeSchema.js +150 -0
  123. package/dist/runtime/themeSchema.js.map +1 -0
  124. package/dist/runtime/themeSpec.d.ts +263 -0
  125. package/dist/runtime/themeSpec.js +435 -0
  126. package/dist/runtime/themeSpec.js.map +1 -0
  127. package/dist/runtime/themeTokens.d.ts +12 -0
  128. package/dist/runtime/themeTokens.js +14 -6
  129. package/dist/runtime/themeTokens.js.map +1 -1
  130. package/dist/runtime/themeVariants.d.ts +30 -0
  131. package/dist/runtime/themeVariants.js +53 -0
  132. package/dist/runtime/themeVariants.js.map +1 -0
  133. package/dist/runtime/ui.d.ts +192 -0
  134. package/dist/runtime/ui.js +926 -0
  135. package/dist/runtime/ui.js.map +1 -0
  136. package/dist/shell/InstallDialog.d.ts +40 -0
  137. package/dist/shell/InstallDialog.js +176 -0
  138. package/dist/shell/InstallDialog.js.map +1 -0
  139. package/dist/shell/StoreView.d.ts +78 -0
  140. package/dist/shell/StoreView.js +108 -0
  141. package/dist/shell/StoreView.js.map +1 -0
  142. package/dist/shell/addressModel.js.map +1 -1
  143. package/dist/shell/chrome.js.map +1 -1
  144. package/dist/shell/deckModel.d.ts +117 -0
  145. package/dist/shell/deckModel.js +267 -0
  146. package/dist/shell/deckModel.js.map +1 -0
  147. package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
  148. package/dist/shell/frame/AccountSwitcher.js +243 -0
  149. package/dist/shell/frame/AccountSwitcher.js.map +1 -0
  150. package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
  151. package/dist/shell/frame/AddColumnDialog.js +81 -0
  152. package/dist/shell/frame/AddColumnDialog.js.map +1 -0
  153. package/dist/shell/frame/AppMenu.d.ts +44 -0
  154. package/dist/shell/frame/AppMenu.js +721 -0
  155. package/dist/shell/frame/AppMenu.js.map +1 -0
  156. package/dist/shell/frame/CommandPalette.d.ts +7 -0
  157. package/dist/shell/frame/CommandPalette.js +118 -0
  158. package/dist/shell/frame/CommandPalette.js.map +1 -0
  159. package/dist/shell/frame/DeckView.d.ts +13 -0
  160. package/dist/shell/frame/DeckView.js +287 -0
  161. package/dist/shell/frame/DeckView.js.map +1 -0
  162. package/dist/shell/frame/FindBar.d.ts +10 -0
  163. package/dist/shell/frame/FindBar.js +108 -0
  164. package/dist/shell/frame/FindBar.js.map +1 -0
  165. package/dist/shell/frame/MediaPanel.d.ts +8 -0
  166. package/dist/shell/frame/MediaPanel.js +76 -0
  167. package/dist/shell/frame/MediaPanel.js.map +1 -0
  168. package/dist/shell/frame/NewTabPage.d.ts +9 -0
  169. package/dist/shell/frame/NewTabPage.js +71 -0
  170. package/dist/shell/frame/NewTabPage.js.map +1 -0
  171. package/dist/shell/frame/PaneTheme.d.ts +16 -0
  172. package/dist/shell/frame/PaneTheme.js +67 -0
  173. package/dist/shell/frame/PaneTheme.js.map +1 -0
  174. package/dist/shell/frame/ReportDialog.d.ts +3 -0
  175. package/dist/shell/frame/ReportDialog.js +95 -0
  176. package/dist/shell/frame/ReportDialog.js.map +1 -0
  177. package/dist/shell/frame/Shell.d.ts +9 -0
  178. package/dist/shell/frame/Shell.js +1139 -0
  179. package/dist/shell/frame/Shell.js.map +1 -0
  180. package/dist/shell/frame/Titlebar.d.ts +17 -0
  181. package/dist/shell/frame/Titlebar.js +79 -0
  182. package/dist/shell/frame/Titlebar.js.map +1 -0
  183. package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
  184. package/dist/shell/frame/TitlebarExtras.js +202 -0
  185. package/dist/shell/frame/TitlebarExtras.js.map +1 -0
  186. package/dist/shell/frame/WebPanel.d.ts +4 -0
  187. package/dist/shell/frame/WebPanel.js +185 -0
  188. package/dist/shell/frame/WebPanel.js.map +1 -0
  189. package/dist/shell/frame/accountModel.d.ts +49 -0
  190. package/dist/shell/frame/accountModel.js +67 -0
  191. package/dist/shell/frame/accountModel.js.map +1 -0
  192. package/dist/shell/frame/accountSwitcher.css +91 -0
  193. package/dist/shell/frame/appI18n.d.ts +44 -0
  194. package/dist/shell/frame/appI18n.js +64 -0
  195. package/dist/shell/frame/appI18n.js.map +1 -0
  196. package/dist/shell/frame/appMenu.css +127 -0
  197. package/dist/shell/frame/backupModel.d.ts +38 -0
  198. package/dist/shell/frame/backupModel.js +192 -0
  199. package/dist/shell/frame/backupModel.js.map +1 -0
  200. package/dist/shell/frame/boot.d.ts +8 -0
  201. package/dist/shell/frame/boot.js +37 -0
  202. package/dist/shell/frame/boot.js.map +1 -0
  203. package/dist/shell/frame/brand.d.ts +1 -0
  204. package/dist/shell/frame/brand.js +4 -0
  205. package/dist/shell/frame/brand.js.map +1 -0
  206. package/dist/shell/frame/bridge.d.ts +35 -0
  207. package/dist/shell/frame/bridge.js +70 -0
  208. package/dist/shell/frame/bridge.js.map +1 -0
  209. package/dist/shell/frame/chromeTheme.d.ts +47 -0
  210. package/dist/shell/frame/chromeTheme.js +118 -0
  211. package/dist/shell/frame/chromeTheme.js.map +1 -0
  212. package/dist/shell/frame/deck.css +209 -0
  213. package/dist/shell/frame/deckStore.d.ts +89 -0
  214. package/dist/shell/frame/deckStore.js +239 -0
  215. package/dist/shell/frame/deckStore.js.map +1 -0
  216. package/dist/shell/frame/devHost.d.ts +35 -0
  217. package/dist/shell/frame/devHost.js +80 -0
  218. package/dist/shell/frame/devHost.js.map +1 -0
  219. package/dist/shell/frame/devModel.d.ts +7 -0
  220. package/dist/shell/frame/devModel.js +17 -0
  221. package/dist/shell/frame/devModel.js.map +1 -0
  222. package/dist/shell/frame/diag.d.ts +7 -0
  223. package/dist/shell/frame/diag.js +39 -0
  224. package/dist/shell/frame/diag.js.map +1 -0
  225. package/dist/shell/frame/edges.css +159 -0
  226. package/dist/shell/frame/findBar.css +14 -0
  227. package/dist/shell/frame/frameMessages.d.ts +248 -0
  228. package/dist/shell/frame/frameMessages.js +252 -0
  229. package/dist/shell/frame/frameMessages.js.map +1 -0
  230. package/dist/shell/frame/hooks.d.ts +39 -0
  231. package/dist/shell/frame/hooks.js +97 -0
  232. package/dist/shell/frame/hooks.js.map +1 -0
  233. package/dist/shell/frame/i18n.d.ts +27 -0
  234. package/dist/shell/frame/i18n.js +66 -0
  235. package/dist/shell/frame/i18n.js.map +1 -0
  236. package/dist/shell/frame/iconPack.d.ts +11 -0
  237. package/dist/shell/frame/iconPack.js +45 -0
  238. package/dist/shell/frame/iconPack.js.map +1 -0
  239. package/dist/shell/frame/icons.d.ts +71 -0
  240. package/dist/shell/frame/icons.js +75 -0
  241. package/dist/shell/frame/icons.js.map +1 -0
  242. package/dist/shell/frame/index.d.ts +34 -0
  243. package/dist/shell/frame/index.js +43 -0
  244. package/dist/shell/frame/index.js.map +1 -0
  245. package/dist/shell/frame/language.d.ts +58 -0
  246. package/dist/shell/frame/language.js +165 -0
  247. package/dist/shell/frame/language.js.map +1 -0
  248. package/dist/shell/frame/mediaModel.d.ts +47 -0
  249. package/dist/shell/frame/mediaModel.js +67 -0
  250. package/dist/shell/frame/mediaModel.js.map +1 -0
  251. package/dist/shell/frame/menuMessages.en.json +96 -0
  252. package/dist/shell/frame/menuModel.d.ts +319 -0
  253. package/dist/shell/frame/menuModel.js +301 -0
  254. package/dist/shell/frame/menuModel.js.map +1 -0
  255. package/dist/shell/frame/nativeMenu.d.ts +5 -0
  256. package/dist/shell/frame/nativeMenu.js +178 -0
  257. package/dist/shell/frame/nativeMenu.js.map +1 -0
  258. package/dist/shell/frame/nativeMenuModel.d.ts +102 -0
  259. package/dist/shell/frame/nativeMenuModel.js +186 -0
  260. package/dist/shell/frame/nativeMenuModel.js.map +1 -0
  261. package/dist/shell/frame/paletteModel.d.ts +139 -0
  262. package/dist/shell/frame/paletteModel.js +114 -0
  263. package/dist/shell/frame/paletteModel.js.map +1 -0
  264. package/dist/shell/frame/paneTheme.css +9 -0
  265. package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
  266. package/dist/shell/frame/pluginCommandStore.js +70 -0
  267. package/dist/shell/frame/pluginCommandStore.js.map +1 -0
  268. package/dist/shell/frame/reportModel.d.ts +52 -0
  269. package/dist/shell/frame/reportModel.js +105 -0
  270. package/dist/shell/frame/reportModel.js.map +1 -0
  271. package/dist/shell/frame/safeStore.d.ts +7 -0
  272. package/dist/shell/frame/safeStore.js +40 -0
  273. package/dist/shell/frame/safeStore.js.map +1 -0
  274. package/dist/shell/frame/searchInput.d.ts +2 -0
  275. package/dist/shell/frame/searchInput.js +11 -0
  276. package/dist/shell/frame/searchInput.js.map +1 -0
  277. package/dist/shell/frame/shell.css +634 -0
  278. package/dist/shell/frame/site.d.ts +206 -0
  279. package/dist/shell/frame/site.js +22 -0
  280. package/dist/shell/frame/site.js.map +1 -0
  281. package/dist/shell/frame/state.d.ts +101 -0
  282. package/dist/shell/frame/state.js +286 -0
  283. package/dist/shell/frame/state.js.map +1 -0
  284. package/dist/shell/frame/syncGate.d.ts +10 -0
  285. package/dist/shell/frame/syncGate.js +36 -0
  286. package/dist/shell/frame/syncGate.js.map +1 -0
  287. package/dist/shell/frame/syncHost.d.ts +35 -0
  288. package/dist/shell/frame/syncHost.js +85 -0
  289. package/dist/shell/frame/syncHost.js.map +1 -0
  290. package/dist/shell/frame/tabStill.d.ts +2 -0
  291. package/dist/shell/frame/tabStill.js +62 -0
  292. package/dist/shell/frame/tabStill.js.map +1 -0
  293. package/dist/shell/frame/themeScopes.d.ts +29 -0
  294. package/dist/shell/frame/themeScopes.js +61 -0
  295. package/dist/shell/frame/themeScopes.js.map +1 -0
  296. package/dist/shell/frame/themeStore.d.ts +99 -0
  297. package/dist/shell/frame/themeStore.js +267 -0
  298. package/dist/shell/frame/themeStore.js.map +1 -0
  299. package/dist/shell/frame/windowBinding.d.ts +2 -0
  300. package/dist/shell/frame/windowBinding.js +7 -0
  301. package/dist/shell/frame/windowBinding.js.map +1 -0
  302. package/dist/shell/frame/workspaceModel.d.ts +82 -0
  303. package/dist/shell/frame/workspaceModel.js +250 -0
  304. package/dist/shell/frame/workspaceModel.js.map +1 -0
  305. package/dist/shell/frame/workspaces.css +84 -0
  306. package/dist/shell/frame/workspaces.d.ts +22 -0
  307. package/dist/shell/frame/workspaces.js +125 -0
  308. package/dist/shell/frame/workspaces.js.map +1 -0
  309. package/dist/shell/frame/zoomStore.d.ts +10 -0
  310. package/dist/shell/frame/zoomStore.js +65 -0
  311. package/dist/shell/frame/zoomStore.js.map +1 -0
  312. package/dist/shell/installController.d.ts +137 -0
  313. package/dist/shell/installController.js +172 -0
  314. package/dist/shell/installController.js.map +1 -0
  315. package/dist/shell/installerMessages.d.ts +30 -0
  316. package/dist/shell/installerMessages.js +36 -0
  317. package/dist/shell/installerMessages.js.map +1 -0
  318. package/dist/shell/linkDrop.js.map +1 -1
  319. package/dist/shell/messages.d.ts +16 -0
  320. package/dist/shell/messages.js +27 -0
  321. package/dist/shell/messages.js.map +1 -0
  322. package/dist/shell/palette.js.map +1 -1
  323. package/dist/shell/paneModel.d.ts +22 -0
  324. package/dist/shell/paneModel.js +24 -1
  325. package/dist/shell/paneModel.js.map +1 -1
  326. package/dist/shell/panel/Appearance.d.ts +8 -0
  327. package/dist/shell/panel/Appearance.js +265 -0
  328. package/dist/shell/panel/Appearance.js.map +1 -0
  329. package/dist/shell/panel/BackupPanel.d.ts +5 -0
  330. package/dist/shell/panel/BackupPanel.js +198 -0
  331. package/dist/shell/panel/BackupPanel.js.map +1 -0
  332. package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
  333. package/dist/shell/panel/DeveloperPanel.js +51 -0
  334. package/dist/shell/panel/DeveloperPanel.js.map +1 -0
  335. package/dist/shell/panel/FeatureToggles.d.ts +13 -0
  336. package/dist/shell/panel/FeatureToggles.js +42 -0
  337. package/dist/shell/panel/FeatureToggles.js.map +1 -0
  338. package/dist/shell/panel/Home.d.ts +3 -0
  339. package/dist/shell/panel/Home.js +23 -0
  340. package/dist/shell/panel/Home.js.map +1 -0
  341. package/dist/shell/panel/IconPackInstall.d.ts +15 -0
  342. package/dist/shell/panel/IconPackInstall.js +41 -0
  343. package/dist/shell/panel/IconPackInstall.js.map +1 -0
  344. package/dist/shell/panel/LanguageSettings.d.ts +1 -0
  345. package/dist/shell/panel/LanguageSettings.js +54 -0
  346. package/dist/shell/panel/LanguageSettings.js.map +1 -0
  347. package/dist/shell/panel/MakePanel.d.ts +3 -0
  348. package/dist/shell/panel/MakePanel.js +237 -0
  349. package/dist/shell/panel/MakePanel.js.map +1 -0
  350. package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
  351. package/dist/shell/panel/MarkdownDoc.js +35 -0
  352. package/dist/shell/panel/MarkdownDoc.js.map +1 -0
  353. package/dist/shell/panel/Modes.d.ts +40 -0
  354. package/dist/shell/panel/Modes.js +270 -0
  355. package/dist/shell/panel/Modes.js.map +1 -0
  356. package/dist/shell/panel/NavIcon.d.ts +4 -0
  357. package/dist/shell/panel/NavIcon.js +6 -0
  358. package/dist/shell/panel/NavIcon.js.map +1 -0
  359. package/dist/shell/panel/Panel.d.ts +7 -0
  360. package/dist/shell/panel/Panel.js +139 -0
  361. package/dist/shell/panel/Panel.js.map +1 -0
  362. package/dist/shell/panel/PluginFeatures.d.ts +24 -0
  363. package/dist/shell/panel/PluginFeatures.js +165 -0
  364. package/dist/shell/panel/PluginFeatures.js.map +1 -0
  365. package/dist/shell/panel/Plugins.d.ts +33 -0
  366. package/dist/shell/panel/Plugins.js +112 -0
  367. package/dist/shell/panel/Plugins.js.map +1 -0
  368. package/dist/shell/panel/PowerSettings.d.ts +4 -0
  369. package/dist/shell/panel/PowerSettings.js +52 -0
  370. package/dist/shell/panel/PowerSettings.js.map +1 -0
  371. package/dist/shell/panel/Settings.d.ts +23 -0
  372. package/dist/shell/panel/Settings.js +117 -0
  373. package/dist/shell/panel/Settings.js.map +1 -0
  374. package/dist/shell/panel/ShareSetup.d.ts +8 -0
  375. package/dist/shell/panel/ShareSetup.js +130 -0
  376. package/dist/shell/panel/ShareSetup.js.map +1 -0
  377. package/dist/shell/panel/StoreSection.d.ts +7 -0
  378. package/dist/shell/panel/StoreSection.js +78 -0
  379. package/dist/shell/panel/StoreSection.js.map +1 -0
  380. package/dist/shell/panel/StringPacks.d.ts +20 -0
  381. package/dist/shell/panel/StringPacks.js +131 -0
  382. package/dist/shell/panel/StringPacks.js.map +1 -0
  383. package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
  384. package/dist/shell/panel/ThemeBuilder.js +205 -0
  385. package/dist/shell/panel/ThemeBuilder.js.map +1 -0
  386. package/dist/shell/panel/backup.css +34 -0
  387. package/dist/shell/panel/builder.css +240 -0
  388. package/dist/shell/panel/builderModel.d.ts +55 -0
  389. package/dist/shell/panel/builderModel.js +95 -0
  390. package/dist/shell/panel/builderModel.js.map +1 -0
  391. package/dist/shell/panel/compare.d.ts +10 -0
  392. package/dist/shell/panel/compare.js +51 -0
  393. package/dist/shell/panel/compare.js.map +1 -0
  394. package/dist/shell/panel/controls.d.ts +135 -0
  395. package/dist/shell/panel/controls.js +213 -0
  396. package/dist/shell/panel/controls.js.map +1 -0
  397. package/dist/shell/panel/featureModel.d.ts +69 -0
  398. package/dist/shell/panel/featureModel.js +79 -0
  399. package/dist/shell/panel/featureModel.js.map +1 -0
  400. package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
  401. package/dist/shell/panel/fonts/FontBrowser.js +189 -0
  402. package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
  403. package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
  404. package/dist/shell/panel/fonts/FontRoles.js +77 -0
  405. package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
  406. package/dist/shell/panel/fonts/catalog.d.ts +37 -0
  407. package/dist/shell/panel/fonts/catalog.js +68 -0
  408. package/dist/shell/panel/fonts/catalog.js.map +1 -0
  409. package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
  410. package/dist/shell/panel/index.d.ts +20 -0
  411. package/dist/shell/panel/index.js +34 -0
  412. package/dist/shell/panel/index.js.map +1 -0
  413. package/dist/shell/panel/languageModel.d.ts +5 -0
  414. package/dist/shell/panel/languageModel.js +7 -0
  415. package/dist/shell/panel/languageModel.js.map +1 -0
  416. package/dist/shell/panel/make.css +73 -0
  417. package/dist/shell/panel/makeModel.d.ts +32 -0
  418. package/dist/shell/panel/makeModel.js +84 -0
  419. package/dist/shell/panel/makeModel.js.map +1 -0
  420. package/dist/shell/panel/markdown.d.ts +46 -0
  421. package/dist/shell/panel/markdown.js +100 -0
  422. package/dist/shell/panel/markdown.js.map +1 -0
  423. package/dist/shell/panel/nav.d.ts +12 -0
  424. package/dist/shell/panel/nav.js +50 -0
  425. package/dist/shell/panel/nav.js.map +1 -0
  426. package/dist/shell/panel/panel.css +401 -0
  427. package/dist/shell/panel/panelMessages.d.ts +803 -0
  428. package/dist/shell/panel/panelMessages.js +779 -0
  429. package/dist/shell/panel/panelMessages.js.map +1 -0
  430. package/dist/shell/panel/plugins.css +59 -0
  431. package/dist/shell/panel/setupModel.d.ts +87 -0
  432. package/dist/shell/panel/setupModel.js +152 -0
  433. package/dist/shell/panel/setupModel.js.map +1 -0
  434. package/dist/shell/panel/site.d.ts +259 -0
  435. package/dist/shell/panel/site.js +25 -0
  436. package/dist/shell/panel/site.js.map +1 -0
  437. package/dist/shell/panel/strings.css +7 -0
  438. package/dist/shell/panel/themes.d.ts +10 -0
  439. package/dist/shell/panel/themes.js +8 -0
  440. package/dist/shell/panel/themes.js.map +1 -0
  441. package/dist/shell/profileModel.d.ts +3 -2
  442. package/dist/shell/profileModel.js +7 -5
  443. package/dist/shell/profileModel.js.map +1 -1
  444. package/dist/shell/store.css +250 -0
  445. package/dist/shell/storeMessages.d.ts +193 -0
  446. package/dist/shell/storeMessages.js +196 -0
  447. package/dist/shell/storeMessages.js.map +1 -0
  448. package/dist/shell/storeModel.d.ts +205 -0
  449. package/dist/shell/storeModel.js +146 -0
  450. package/dist/shell/storeModel.js.map +1 -0
  451. package/dist/shell/stringPacksModel.d.ts +44 -0
  452. package/dist/shell/stringPacksModel.js +99 -0
  453. package/dist/shell/stringPacksModel.js.map +1 -0
  454. package/dist/shell/updateModel.d.ts +2 -1
  455. package/dist/shell/updateModel.js +5 -4
  456. package/dist/shell/updateModel.js.map +1 -1
  457. package/dist/shell/windowControls.d.ts +4 -0
  458. package/dist/shell/windowControls.js +5 -0
  459. package/dist/shell/windowControls.js.map +1 -1
  460. package/i18n-config.schema.json +29 -0
  461. package/i18n-meta.schema.json +26 -0
  462. package/i18n.schema.json +42 -0
  463. package/icons.schema.json +655 -0
  464. package/languages.schema.json +23 -0
  465. package/locales/ar-x-fm.json +11 -0
  466. package/locales/ar.json +1388 -0
  467. package/locales/bg.json +1387 -0
  468. package/locales/bn.json +1387 -0
  469. package/locales/ca.json +1387 -0
  470. package/locales/cs.json +1387 -0
  471. package/locales/da.json +1387 -0
  472. package/locales/de.json +1387 -0
  473. package/locales/el.json +1387 -0
  474. package/locales/en-GB.json +27 -0
  475. package/locales/en.json +1386 -0
  476. package/locales/en.meta.json +51 -0
  477. package/locales/es.json +1387 -0
  478. package/locales/eu.json +1387 -0
  479. package/locales/fa.json +1388 -0
  480. package/locales/fi.json +1387 -0
  481. package/locales/fil.json +1387 -0
  482. package/locales/fr.json +1387 -0
  483. package/locales/ga.json +1387 -0
  484. package/locales/gl.json +1387 -0
  485. package/locales/gu.json +1387 -0
  486. package/locales/ha.json +1387 -0
  487. package/locales/he.json +1388 -0
  488. package/locales/hi.json +1387 -0
  489. package/locales/hr.json +1387 -0
  490. package/locales/hu.json +1387 -0
  491. package/locales/id.json +1387 -0
  492. package/locales/ig.json +1387 -0
  493. package/locales/it.json +1387 -0
  494. package/locales/ja.json +1387 -0
  495. package/locales/kn.json +1387 -0
  496. package/locales/ko.json +1387 -0
  497. package/locales/mr.json +1387 -0
  498. package/locales/ms.json +1387 -0
  499. package/locales/nb.json +1387 -0
  500. package/locales/nl.json +1387 -0
  501. package/locales/pl.json +1387 -0
  502. package/locales/pt.json +1387 -0
  503. package/locales/ro.json +1387 -0
  504. package/locales/ru.json +1387 -0
  505. package/locales/sk.json +1387 -0
  506. package/locales/sr.json +1387 -0
  507. package/locales/sv.json +1387 -0
  508. package/locales/ta.json +1387 -0
  509. package/locales/th.json +1387 -0
  510. package/locales/tr.json +1387 -0
  511. package/locales/uk.json +1387 -0
  512. package/locales/ur.json +1388 -0
  513. package/locales/vi.json +1387 -0
  514. package/locales/yo.json +1387 -0
  515. package/locales/zh-Hans.json +1387 -0
  516. package/locales/zh-Hant.json +1387 -0
  517. package/package.json +138 -5
  518. package/store-catalog.schema.json +78 -0
  519. package/theme.schema.json +4668 -0
  520. package/windows/installer.nsi +946 -0
  521. package/windows/languages/Basque.nsh +28 -0
  522. package/windows/languages/Catalan.nsh +28 -0
  523. package/windows/languages/Croatian.nsh +28 -0
  524. package/windows/languages/Czech.nsh +28 -0
  525. package/windows/languages/Danish.nsh +28 -0
  526. package/windows/languages/Finnish.nsh +28 -0
  527. package/windows/languages/Galician.nsh +28 -0
  528. package/windows/languages/Greek.nsh +28 -0
  529. package/windows/languages/Hungarian.nsh +28 -0
  530. package/windows/languages/Indonesian.nsh +28 -0
  531. package/windows/languages/Irish.nsh +28 -0
  532. package/windows/languages/Malay.nsh +28 -0
  533. package/windows/languages/Polish.nsh +28 -0
  534. package/windows/languages/Romanian.nsh +28 -0
  535. package/windows/languages/Serbian.nsh +28 -0
  536. package/windows/languages/Slovak.nsh +28 -0
  537. package/windows/languages/Thai.nsh +28 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zoomStore.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/zoomStore.ts"],"names":[],"mappings":"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","sourcesContent":["// Page zoom of the tab webviews, as the shell knows it. Native code owns it (`tab_zoom`, shell-only:\n// the engine's own page zoom, clamped and remembered per tab; waybetter-host `zoom.rs`); the shell\n// asks for a factor and keeps what native code answered, for the app menu's zoom row and the\n// titlebar chip. Nothing here touches a page's CSS.\n\nimport { invoke } from './bridge.ts';\nimport { deckById, decks } from './deckStore.ts';\nimport { zoomStep } from './menuModel.ts';\nimport { hasFeature } from './site.ts';\nimport { isWeb, shell, type TabParams } from './state.ts';\n\nconst factors = new Map<string, number>();\n\n/** The factor tab `id` shows, as last answered by native code (100% until asked). */\nexport const zoomOf = (id: string | null) => (id ? factors.get(id) ?? 1 : 1);\n\nfunction note(id: string, factor: number) {\n if (!Number.isFinite(factor) || zoomOf(id) === factor) return;\n if (factor === 1) factors.delete(id); else factors.set(id, factor);\n window.dispatchEvent(new CustomEvent('bt-zoom', { detail: id }));\n}\n\n/** The active pane's page: the tab in front, or the focused column of the deck in front. None for the app's own tabs. */\nexport function zoomTarget(): string | null {\n const panel = shell.api?.activePanel;\n if (!panel) return null;\n if (isWeb(panel)) return panel.id;\n const params = panel.params as TabParams | undefined;\n if (params?.kind !== 'deck') return null;\n const deck = deckById(params.deckId);\n const focused = decks.focus.get(params.deckId);\n return deck?.columns.find(column => column.id === focused)?.tabId ?? null;\n}\n\n/** Reads a tab's remembered zoom (a restored tab may come back zoomed). */\nexport async function readZoom(id: string | null): Promise<void> {\n if (!id || !hasFeature('zoom')) return;\n try { note(id, await invoke<number>('tab_zoom', { id })); } catch { /* No such webview yet: 100%. */ }\n}\n\n/** Sets a tab's zoom; native code answers the factor in effect. */\nexport async function setZoom(id: string, factor: number): Promise<number> {\n const applied = await invoke<number>('tab_zoom', { id, factor });\n note(id, applied);\n return applied;\n}\n\n/** One step in (`1`), out (`-1`) or back to 100% (`0`) for tab `id` (default: the active pane's page). */\nexport async function stepZoom(direction: 1 | -1 | 0, id: string | null = zoomTarget()): Promise<void> {\n if (!id || !hasFeature('zoom')) return;\n const next = zoomStep(zoomOf(id), direction);\n if (next === zoomOf(id)) return;\n try { await setZoom(id, next); } catch (error) { console.error('[shell] tab_zoom', error); }\n}\n"]}
@@ -0,0 +1,137 @@
1
+ import { type IconPack } from '../runtime/themeIcons.ts';
2
+ import { type InstallKind, type InstallPreview, type OpenedFile, type StoreItem } from './storeModel.ts';
3
+ import type { StoreText } from './storeMessages.ts';
4
+ /** How the controller reaches native code (the app passes Tauri's `invoke` and `listen`). */
5
+ export type StoreBackend = {
6
+ invoke<T>(command: string, args?: Record<string, unknown>): Promise<T>;
7
+ /** Subscribes to a shell event; resolves to the unsubscribe function. */
8
+ listen<T>(event: string, handler: (payload: T) => void): Promise<() => void>;
9
+ };
10
+ /** What the install screen shows of a theme (the app's theme format stays the app's). */
11
+ export type ThemeFacts = {
12
+ name: string;
13
+ author?: string;
14
+ description?: string;
15
+ /** Theme CSS, shown as its own code block (it has custom-CSS trust). */
16
+ css?: string;
17
+ /** The theme's own colors for the tile at the top. */
18
+ tile?: {
19
+ background: string;
20
+ color: string;
21
+ border: string;
22
+ };
23
+ };
24
+ export type ThemeAdapter<Theme> = {
25
+ /** Parses (and sanitizes) a theme file the way the app's theme import does. */
26
+ parse(text: string): {
27
+ theme: Theme;
28
+ warnings: string[];
29
+ } | {
30
+ error: string;
31
+ };
32
+ /** Loads the app's theme state and resolves to the owner's own theme ids. */
33
+ userThemes(): Promise<string[]>;
34
+ /** Theme ids that ship with the app. */
35
+ builtinThemes: readonly string[];
36
+ /** The id a theme asks for (a free one is chosen from it). */
37
+ idOf(theme: Theme): string;
38
+ facts(theme: Theme): ThemeFacts;
39
+ /**
40
+ * Saves the theme the owner confirmed under `id` (replacing the owner's copy `replaces`), and
41
+ * makes it the current theme when `enable`. Resolves to whether it is current now and the font
42
+ * names it uses that are not available yet.
43
+ */
44
+ save(theme: Theme, id: string, options: {
45
+ replaces: string | null;
46
+ enable: boolean;
47
+ }): Promise<{
48
+ enabled: boolean;
49
+ fonts: string[];
50
+ }>;
51
+ };
52
+ export type InstallRequest<Theme> = {
53
+ status: 'loading';
54
+ title: string;
55
+ detail: string;
56
+ } | {
57
+ status: 'ready';
58
+ preview: InstallPreview;
59
+ theme: Theme | null;
60
+ warnings: string[];
61
+ replaces: string | null;
62
+ pack?: IconPack | null;
63
+ } | {
64
+ status: 'installing';
65
+ preview: InstallPreview;
66
+ theme: Theme | null;
67
+ pack?: IconPack | null;
68
+ } | {
69
+ status: 'done';
70
+ kind: InstallKind;
71
+ name: string;
72
+ themeId?: string;
73
+ fonts: string[];
74
+ enabled: boolean;
75
+ } | {
76
+ status: 'error';
77
+ title: string;
78
+ message: string;
79
+ };
80
+ export type InstallControllerOptions<Theme> = {
81
+ backend: StoreBackend;
82
+ /** The app's translator (framework catalogs merged in); called at request time. */
83
+ t: StoreText;
84
+ /** The site's name in messages ("X"). */
85
+ site: string;
86
+ theme: ThemeAdapter<Theme>;
87
+ /** A plugin was installed (the app refreshes its plugin list). */
88
+ onPluginsChanged?(): void;
89
+ /** A theme was installed (the app refreshes its store/theme views). */
90
+ onThemesChanged?(): void;
91
+ /**
92
+ * Adds the icon pack the owner confirmed (already sanitized) to the app's icon packs, replacing
93
+ * one with the same id, and makes it the current pack when `enable`. Absent: icon packs cannot
94
+ * be installed (the screen says so).
95
+ */
96
+ icons?: {
97
+ save(pack: IconPack, options: {
98
+ enable: boolean;
99
+ }): Promise<void>;
100
+ };
101
+ /** A string pack was installed (the app hands the site tabs the packs that are on). */
102
+ onStringsChanged?(): void | Promise<void>;
103
+ /**
104
+ * A `waybetter://setup` link was opened (its text, shape-checked natively): the app shows its
105
+ * "Share my setup" preview (panel/ShareSetup.tsx). Absent: such links are ignored.
106
+ */
107
+ onSetupLink?(text: string): void;
108
+ };
109
+ export type InstallController<Theme> = {
110
+ current(): InstallRequest<Theme> | null;
111
+ subscribe(listener: () => void): () => void;
112
+ /** A validated `waybetter://install` link: download it natively and show the screen. */
113
+ requestLink(link: {
114
+ kind: InstallKind;
115
+ url: string;
116
+ }): Promise<void>;
117
+ /** A file dropped on the window. */
118
+ requestFile(file: {
119
+ name: string;
120
+ size: number;
121
+ text(): Promise<string>;
122
+ }): Promise<void>;
123
+ /** A file the OS handed to the app ("Open with", double-click), asked for by its id: staged natively like a dropped file. */
124
+ requestOpened(file: OpenedFile): Promise<void>;
125
+ /** A store item: downloaded natively and checked against the signed catalog. */
126
+ requestStoreItem(item: StoreItem): Promise<void>;
127
+ linkRejected(error: string): void;
128
+ /** Closes the screen and drops what was staged. */
129
+ cancel(): Promise<void>;
130
+ close(): void;
131
+ /** The owner pressed Install. `enable`: turn the plugin on / use the theme now. */
132
+ confirm(enable: boolean): Promise<void>;
133
+ /** Listens for install links (once). Returns a disposer. */
134
+ start(): () => void;
135
+ facts(theme: Theme): ThemeFacts;
136
+ };
137
+ export declare function createInstallController<Theme>(options: InstallControllerOptions<Theme>): InstallController<Theme>;
@@ -0,0 +1,172 @@
1
+ // The install screen's state machine, shared by every wayBetter app. Requests come from
2
+ // `waybetter://install` links (the native `install-link` event, plus links that arrived before the
3
+ // shell listened), files dropped on the window, files the OS handed over ("Open with") and the Store view. Each request is staged natively
4
+ // (downloaded/validated, hashed) and shown on the install screen; nothing is written until the owner
5
+ // presses Install there. The app supplies how it talks to native code (Tauri `invoke`/`listen`) and
6
+ // how its themes are parsed and saved; plugins need nothing app-specific.
7
+ import { parseIconPackJson } from "../runtime/themeIcons.js";
8
+ import { freeThemeId, installedThemeId, kindForFile, MAX_FILE_BYTES, errorText } from "./storeModel.js";
9
+ export function createInstallController(options) {
10
+ const { backend, t, theme: themes } = options;
11
+ let current = null;
12
+ let records = {};
13
+ let started = false;
14
+ const listeners = new Set();
15
+ const set = (next) => { current = next; for (const listener of [...listeners])
16
+ listener(); };
17
+ async function refreshRecords() {
18
+ try {
19
+ records = (await backend.invoke('install_records')).items ?? {};
20
+ }
21
+ catch { /* Keep the last copy. */ }
22
+ }
23
+ /** Parses a staged theme the way the app's import does, and finds the theme it would update. */
24
+ async function prepared(preview) {
25
+ if (preview.kind === 'plugin' || preview.kind === 'strings')
26
+ return { status: 'ready', preview, theme: null, warnings: [], replaces: null };
27
+ if (preview.kind === 'icons') {
28
+ if (!options.icons)
29
+ return { status: 'error', title: t('wb.install.err.icons'), message: t('wb.install.err.iconsNone', { site: options.site }) };
30
+ const parsed = parseIconPackJson(preview.text);
31
+ if ('error' in parsed)
32
+ return { status: 'error', title: t('wb.install.err.icons'), message: parsed.error };
33
+ return { status: 'ready', preview, theme: null, warnings: parsed.warnings, replaces: null, pack: parsed.pack };
34
+ }
35
+ const parsed = themes.parse(preview.text);
36
+ if ('error' in parsed)
37
+ return { status: 'error', title: t('wb.install.err.theme'), message: parsed.error };
38
+ const userThemes = await themes.userThemes();
39
+ const replaces = preview.store ? installedThemeId(preview.store, records, userThemes) : null;
40
+ return { status: 'ready', preview, theme: parsed.theme, warnings: parsed.warnings, replaces };
41
+ }
42
+ async function stage(title, detail, run) {
43
+ set({ status: 'loading', title, detail });
44
+ try {
45
+ await Promise.all([themes.userThemes(), refreshRecords()]);
46
+ const preview = await run();
47
+ set(await prepared(preview));
48
+ }
49
+ catch (error) {
50
+ set({ status: 'error', title, message: errorText(error) });
51
+ }
52
+ }
53
+ const controller = {
54
+ current: () => current,
55
+ subscribe(listener) {
56
+ listeners.add(listener);
57
+ return () => { listeners.delete(listener); };
58
+ },
59
+ requestLink(link) {
60
+ let host = link.url;
61
+ try {
62
+ host = new URL(link.url).host;
63
+ }
64
+ catch { /* Shown as is. */ }
65
+ return stage(t('wb.install.stage.link', { kind: link.kind, host }), t('wb.install.stage.linkDetail'), () => backend.invoke('install_stage_link', { kind: link.kind, url: link.url }));
66
+ },
67
+ async requestFile(file) {
68
+ const kind = kindForFile(file.name);
69
+ if (!kind) {
70
+ set({ status: 'error', title: t('wb.install.err.kind', { file: file.name }), message: t('wb.install.err.kindHint', { site: options.site }) });
71
+ return;
72
+ }
73
+ if (file.size > MAX_FILE_BYTES[kind]) {
74
+ set({ status: 'error', title: t('wb.install.err.large', { file: file.name }), message: kind === 'strings' ? t('wb.install.err.stringsLarge') : kind === 'icons' ? t('wb.install.err.iconsLarge') : t('wb.install.err.largeHint', { kind }) });
75
+ return;
76
+ }
77
+ await stage(t('wb.install.stage.named', { name: file.name }), t('wb.install.stage.fileDetail'), async () => backend.invoke('install_stage_file', { name: file.name, text: await file.text() }));
78
+ },
79
+ requestOpened(file) {
80
+ return stage(t('wb.install.stage.named', { name: file.name }), t('wb.install.stage.fileDetail'), () => backend.invoke('install_stage_opened', { id: file.id }));
81
+ },
82
+ requestStoreItem(item) {
83
+ return stage(t('wb.install.stage.named', { name: item.name }), t('wb.install.stage.storeDetail'), () => backend.invoke('store_stage', { item: { kind: item.kind, id: item.id } }));
84
+ },
85
+ linkRejected(error) {
86
+ // `FILE:` errors are about a file the OS handed over, `LINK:` ones about a link.
87
+ set({ status: 'error', title: error.startsWith('FILE: ') ? t('wb.install.err.opened') : t('wb.install.err.link'), message: error.replace(/^(LINK|FILE): /, '') });
88
+ },
89
+ async cancel() {
90
+ const request = current;
91
+ set(null);
92
+ if (request && request.status === 'ready')
93
+ await backend.invoke('install_cancel', { token: request.preview.token }).catch(() => { });
94
+ },
95
+ close: () => set(null),
96
+ async confirm(enable) {
97
+ const request = current;
98
+ if (!request || request.status !== 'ready')
99
+ return;
100
+ const { preview } = request;
101
+ set({ status: 'installing', preview, theme: request.theme, pack: request.pack });
102
+ try {
103
+ if (preview.kind === 'icons') {
104
+ const outcome = await backend.invoke('install_commit', { token: preview.token, enable, themeId: null });
105
+ // The exact bytes native code staged and hashed; parsed and sanitized again here.
106
+ const parsed = parseIconPackJson(outcome.iconsText ?? '');
107
+ if ('error' in parsed)
108
+ throw new Error(parsed.error);
109
+ await options.icons.save(parsed.pack, { enable });
110
+ options.onThemesChanged?.();
111
+ set({ status: 'done', kind: 'icons', name: parsed.pack.name, fonts: [], enabled: enable });
112
+ return;
113
+ }
114
+ if (preview.kind === 'plugin') {
115
+ await backend.invoke('install_commit', { token: preview.token, enable, themeId: null });
116
+ options.onPluginsChanged?.();
117
+ set({ status: 'done', kind: 'plugin', name: preview.plugin?.name ?? preview.file ?? 'Plugin', fonts: [], enabled: enable || Boolean(preview.existing?.enabled) });
118
+ return;
119
+ }
120
+ if (preview.kind === 'strings') {
121
+ await backend.invoke('install_commit', { token: preview.token, enable, themeId: null });
122
+ await options.onStringsChanged?.();
123
+ set({ status: 'done', kind: 'strings', name: preview.strings?.name ?? 'String pack', fonts: [], enabled: enable || Boolean(preview.existing?.enabled) });
124
+ return;
125
+ }
126
+ const own = await themes.userThemes();
127
+ const wanted = themes.idOf(request.theme);
128
+ const taken = [...themes.builtinThemes, ...own.filter(id => id !== request.replaces)];
129
+ const id = request.replaces ?? freeThemeId(wanted, taken);
130
+ const outcome = await backend.invoke('install_commit', { token: preview.token, enable, themeId: id });
131
+ // The exact bytes native code staged and hashed; parsed and sanitized again here.
132
+ const parsed = themes.parse(outcome.themeText ?? '');
133
+ if ('error' in parsed)
134
+ throw new Error(parsed.error);
135
+ const saved = await themes.save(parsed.theme, id, { replaces: request.replaces, enable });
136
+ options.onThemesChanged?.();
137
+ set({ status: 'done', kind: 'theme', name: themes.facts(parsed.theme).name, themeId: id, fonts: saved.fonts, enabled: saved.enabled });
138
+ }
139
+ catch (error) {
140
+ set({ status: 'error', title: preview.kind === 'strings' ? t('wb.install.err.stringsNotInstalled') : preview.kind === 'icons' ? t('wb.install.err.iconsNotInstalled') : t('wb.install.err.notInstalled', { kind: preview.kind }), message: errorText(error) });
141
+ }
142
+ },
143
+ start() {
144
+ if (started)
145
+ return () => { };
146
+ started = true;
147
+ const handle = (event) => {
148
+ if (event.setup)
149
+ options.onSetupLink?.(event.setup);
150
+ else if (event.link)
151
+ void controller.requestLink(event.link);
152
+ else if (event.opened)
153
+ void controller.requestOpened(event.opened);
154
+ else if (event.error)
155
+ controller.linkRejected(event.error);
156
+ };
157
+ // Native code queues every link and also emits it; a handled event clears the queue so a
158
+ // reload of the shell does not show it again.
159
+ const unlisten = backend.listen('install-link', event => { handle(event); void backend.invoke('install_pending').catch(() => { }); });
160
+ // Links that arrived before the shell listened (the app was started by one): the newest.
161
+ void unlisten.then(() => backend.invoke('install_pending').then(events => {
162
+ const last = events[events.length - 1];
163
+ if (last && current === null)
164
+ handle(last);
165
+ })).catch(() => { });
166
+ return () => { started = false; void unlisten.then(off => off()).catch(() => { }); };
167
+ },
168
+ facts: theme => themes.facts(theme),
169
+ };
170
+ return controller;
171
+ }
172
+ //# sourceMappingURL=installController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installController.js","sourceRoot":"","sources":["../../../../../shell/src/installController.ts"],"names":[],"mappings":"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","sourcesContent":["// The install screen's state machine, shared by every wayBetter app. Requests come from\n// `waybetter://install` links (the native `install-link` event, plus links that arrived before the\n// shell listened), files dropped on the window, files the OS handed over (\"Open with\") and the Store view. Each request is staged natively\n// (downloaded/validated, hashed) and shown on the install screen; nothing is written until the owner\n// presses Install there. The app supplies how it talks to native code (Tauri `invoke`/`listen`) and\n// how its themes are parsed and saved; plugins need nothing app-specific.\n\nimport { parseIconPackJson, type IconPack } from '../../runtime/src/themeIcons.ts';\nimport { freeThemeId, installedThemeId, kindForFile, MAX_FILE_BYTES, errorText, type InstallKind, type InstallPreview, type InstallRecord, type LinkEvent, type OpenedFile, type StoreItem } from './storeModel.ts';\nimport type { StoreText } from './storeMessages.ts';\n\n/** How the controller reaches native code (the app passes Tauri's `invoke` and `listen`). */\nexport type StoreBackend = {\n invoke<T>(command: string, args?: Record<string, unknown>): Promise<T>;\n /** Subscribes to a shell event; resolves to the unsubscribe function. */\n listen<T>(event: string, handler: (payload: T) => void): Promise<() => void>;\n};\n\n/** What the install screen shows of a theme (the app's theme format stays the app's). */\nexport type ThemeFacts = {\n name: string;\n author?: string;\n description?: string;\n /** Theme CSS, shown as its own code block (it has custom-CSS trust). */\n css?: string;\n /** The theme's own colors for the tile at the top. */\n tile?: { background: string; color: string; border: string };\n};\n\nexport type ThemeAdapter<Theme> = {\n /** Parses (and sanitizes) a theme file the way the app's theme import does. */\n parse(text: string): { theme: Theme; warnings: string[] } | { error: string };\n /** Loads the app's theme state and resolves to the owner's own theme ids. */\n userThemes(): Promise<string[]>;\n /** Theme ids that ship with the app. */\n builtinThemes: readonly string[];\n /** The id a theme asks for (a free one is chosen from it). */\n idOf(theme: Theme): string;\n facts(theme: Theme): ThemeFacts;\n /**\n * Saves the theme the owner confirmed under `id` (replacing the owner's copy `replaces`), and\n * makes it the current theme when `enable`. Resolves to whether it is current now and the font\n * names it uses that are not available yet.\n */\n save(theme: Theme, id: string, options: { replaces: string | null; enable: boolean }): Promise<{ enabled: boolean; fonts: string[] }>;\n};\n\nexport type InstallRequest<Theme> =\n | { status: 'loading'; title: string; detail: string }\n | { status: 'ready'; preview: InstallPreview; theme: Theme | null; warnings: string[]; replaces: string | null; pack?: IconPack | null }\n | { status: 'installing'; preview: InstallPreview; theme: Theme | null; pack?: IconPack | null }\n | { status: 'done'; kind: InstallKind; name: string; themeId?: string; fonts: string[]; enabled: boolean }\n | { status: 'error'; title: string; message: string };\n\nexport type InstallControllerOptions<Theme> = {\n backend: StoreBackend;\n /** The app's translator (framework catalogs merged in); called at request time. */\n t: StoreText;\n /** The site's name in messages (\"X\"). */\n site: string;\n theme: ThemeAdapter<Theme>;\n /** A plugin was installed (the app refreshes its plugin list). */\n onPluginsChanged?(): void;\n /** A theme was installed (the app refreshes its store/theme views). */\n onThemesChanged?(): void;\n /**\n * Adds the icon pack the owner confirmed (already sanitized) to the app's icon packs, replacing\n * one with the same id, and makes it the current pack when `enable`. Absent: icon packs cannot\n * be installed (the screen says so).\n */\n icons?: { save(pack: IconPack, options: { enable: boolean }): Promise<void> };\n /** A string pack was installed (the app hands the site tabs the packs that are on). */\n onStringsChanged?(): void | Promise<void>;\n /**\n * A `waybetter://setup` link was opened (its text, shape-checked natively): the app shows its\n * \"Share my setup\" preview (panel/ShareSetup.tsx). Absent: such links are ignored.\n */\n onSetupLink?(text: string): void;\n};\n\nexport type InstallController<Theme> = {\n current(): InstallRequest<Theme> | null;\n subscribe(listener: () => void): () => void;\n /** A validated `waybetter://install` link: download it natively and show the screen. */\n requestLink(link: { kind: InstallKind; url: string }): Promise<void>;\n /** A file dropped on the window. */\n requestFile(file: { name: string; size: number; text(): Promise<string> }): Promise<void>;\n /** A file the OS handed to the app (\"Open with\", double-click), asked for by its id: staged natively like a dropped file. */\n requestOpened(file: OpenedFile): Promise<void>;\n /** A store item: downloaded natively and checked against the signed catalog. */\n requestStoreItem(item: StoreItem): Promise<void>;\n linkRejected(error: string): void;\n /** Closes the screen and drops what was staged. */\n cancel(): Promise<void>;\n close(): void;\n /** The owner pressed Install. `enable`: turn the plugin on / use the theme now. */\n confirm(enable: boolean): Promise<void>;\n /** Listens for install links (once). Returns a disposer. */\n start(): () => void;\n facts(theme: Theme): ThemeFacts;\n};\n\nexport function createInstallController<Theme>(options: InstallControllerOptions<Theme>): InstallController<Theme> {\n const { backend, t, theme: themes } = options;\n let current: InstallRequest<Theme> | null = null;\n let records: Record<string, InstallRecord> = {};\n let started = false;\n const listeners = new Set<() => void>();\n const set = (next: InstallRequest<Theme> | null) => { current = next; for (const listener of [...listeners]) listener(); };\n\n async function refreshRecords() {\n try { records = (await backend.invoke<{ items: Record<string, InstallRecord> }>('install_records')).items ?? {}; } catch { /* Keep the last copy. */ }\n }\n\n /** Parses a staged theme the way the app's import does, and finds the theme it would update. */\n async function prepared(preview: InstallPreview): Promise<InstallRequest<Theme>> {\n if (preview.kind === 'plugin' || preview.kind === 'strings') return { status: 'ready', preview, theme: null, warnings: [], replaces: null };\n if (preview.kind === 'icons') {\n if (!options.icons) return { status: 'error', title: t('wb.install.err.icons'), message: t('wb.install.err.iconsNone', { site: options.site }) };\n const parsed = parseIconPackJson(preview.text);\n if ('error' in parsed) return { status: 'error', title: t('wb.install.err.icons'), message: parsed.error };\n return { status: 'ready', preview, theme: null, warnings: parsed.warnings, replaces: null, pack: parsed.pack };\n }\n const parsed = themes.parse(preview.text);\n if ('error' in parsed) return { status: 'error', title: t('wb.install.err.theme'), message: parsed.error };\n const userThemes = await themes.userThemes();\n const replaces = preview.store ? installedThemeId(preview.store, records, userThemes) : null;\n return { status: 'ready', preview, theme: parsed.theme, warnings: parsed.warnings, replaces };\n }\n\n async function stage(title: string, detail: string, run: () => Promise<InstallPreview>) {\n set({ status: 'loading', title, detail });\n try {\n await Promise.all([themes.userThemes(), refreshRecords()]);\n const preview = await run();\n set(await prepared(preview));\n } catch (error) {\n set({ status: 'error', title, message: errorText(error) });\n }\n }\n\n const controller: InstallController<Theme> = {\n current: () => current,\n subscribe(listener) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n requestLink(link) {\n let host = link.url;\n try { host = new URL(link.url).host; } catch { /* Shown as is. */ }\n return stage(t('wb.install.stage.link', { kind: link.kind, host }), t('wb.install.stage.linkDetail'), () => backend.invoke<InstallPreview>('install_stage_link', { kind: link.kind, url: link.url }));\n },\n async requestFile(file) {\n const kind = kindForFile(file.name);\n if (!kind) {\n set({ status: 'error', title: t('wb.install.err.kind', { file: file.name }), message: t('wb.install.err.kindHint', { site: options.site }) });\n return;\n }\n if (file.size > MAX_FILE_BYTES[kind]) {\n set({ status: 'error', title: t('wb.install.err.large', { file: file.name }), message: kind === 'strings' ? t('wb.install.err.stringsLarge') : kind === 'icons' ? t('wb.install.err.iconsLarge') : t('wb.install.err.largeHint', { kind }) });\n return;\n }\n await stage(t('wb.install.stage.named', { name: file.name }), t('wb.install.stage.fileDetail'), async () => backend.invoke<InstallPreview>('install_stage_file', { name: file.name, text: await file.text() }));\n },\n requestOpened(file) {\n return stage(t('wb.install.stage.named', { name: file.name }), t('wb.install.stage.fileDetail'), () => backend.invoke<InstallPreview>('install_stage_opened', { id: file.id }));\n },\n requestStoreItem(item) {\n return stage(t('wb.install.stage.named', { name: item.name }), t('wb.install.stage.storeDetail'), () => backend.invoke<InstallPreview>('store_stage', { item: { kind: item.kind, id: item.id } }));\n },\n linkRejected(error) {\n // `FILE:` errors are about a file the OS handed over, `LINK:` ones about a link.\n set({ status: 'error', title: error.startsWith('FILE: ') ? t('wb.install.err.opened') : t('wb.install.err.link'), message: error.replace(/^(LINK|FILE): /, '') });\n },\n async cancel() {\n const request = current;\n set(null);\n if (request && request.status === 'ready') await backend.invoke('install_cancel', { token: request.preview.token }).catch(() => {});\n },\n close: () => set(null),\n async confirm(enable) {\n const request = current;\n if (!request || request.status !== 'ready') return;\n const { preview } = request;\n set({ status: 'installing', preview, theme: request.theme, pack: request.pack });\n try {\n if (preview.kind === 'icons') {\n const outcome = await backend.invoke<{ iconsText: string | null }>('install_commit', { token: preview.token, enable, themeId: null });\n // The exact bytes native code staged and hashed; parsed and sanitized again here.\n const parsed = parseIconPackJson(outcome.iconsText ?? '');\n if ('error' in parsed) throw new Error(parsed.error);\n await options.icons!.save(parsed.pack, { enable });\n options.onThemesChanged?.();\n set({ status: 'done', kind: 'icons', name: parsed.pack.name, fonts: [], enabled: enable });\n return;\n }\n if (preview.kind === 'plugin') {\n await backend.invoke('install_commit', { token: preview.token, enable, themeId: null });\n options.onPluginsChanged?.();\n set({ status: 'done', kind: 'plugin', name: preview.plugin?.name ?? preview.file ?? 'Plugin', fonts: [], enabled: enable || Boolean(preview.existing?.enabled) });\n return;\n }\n if (preview.kind === 'strings') {\n await backend.invoke('install_commit', { token: preview.token, enable, themeId: null });\n await options.onStringsChanged?.();\n set({ status: 'done', kind: 'strings', name: preview.strings?.name ?? 'String pack', fonts: [], enabled: enable || Boolean(preview.existing?.enabled) });\n return;\n }\n const own = await themes.userThemes();\n const wanted = themes.idOf(request.theme!);\n const taken = [...themes.builtinThemes, ...own.filter(id => id !== request.replaces)];\n const id = request.replaces ?? freeThemeId(wanted, taken);\n const outcome = await backend.invoke<{ themeText: string | null }>('install_commit', { token: preview.token, enable, themeId: id });\n // The exact bytes native code staged and hashed; parsed and sanitized again here.\n const parsed = themes.parse(outcome.themeText ?? '');\n if ('error' in parsed) throw new Error(parsed.error);\n const saved = await themes.save(parsed.theme, id, { replaces: request.replaces, enable });\n options.onThemesChanged?.();\n set({ status: 'done', kind: 'theme', name: themes.facts(parsed.theme).name, themeId: id, fonts: saved.fonts, enabled: saved.enabled });\n } catch (error) {\n set({ status: 'error', title: preview.kind === 'strings' ? t('wb.install.err.stringsNotInstalled') : preview.kind === 'icons' ? t('wb.install.err.iconsNotInstalled') : t('wb.install.err.notInstalled', { kind: preview.kind }), message: errorText(error) });\n }\n },\n start() {\n if (started) return () => {};\n started = true;\n const handle = (event: LinkEvent) => {\n if (event.setup) options.onSetupLink?.(event.setup);\n else if (event.link) void controller.requestLink(event.link);\n else if (event.opened) void controller.requestOpened(event.opened);\n else if (event.error) controller.linkRejected(event.error);\n };\n // Native code queues every link and also emits it; a handled event clears the queue so a\n // reload of the shell does not show it again.\n const unlisten = backend.listen<LinkEvent>('install-link', event => { handle(event); void backend.invoke('install_pending').catch(() => {}); });\n // Links that arrived before the shell listened (the app was started by one): the newest.\n void unlisten.then(() => backend.invoke<LinkEvent[]>('install_pending').then(events => {\n const last = events[events.length - 1];\n if (last && current === null) handle(last);\n })).catch(() => {});\n return () => { started = false; void unlisten.then(off => off()).catch(() => {}); };\n },\n facts: theme => themes.facts(theme),\n };\n return controller;\n}\n"]}
@@ -0,0 +1,30 @@
1
+ export declare const INSTALLER_MESSAGES: {
2
+ readonly 'wb.installer.addOrReinstall': "Add/Reinstall components";
3
+ readonly 'wb.installer.alreadyInstalled': "Already Installed";
4
+ readonly 'wb.installer.alreadyInstalledLong': "{product} {version} is already installed. Select the operation you want to perform and click Next to continue.";
5
+ readonly 'wb.installer.appRunning': "{product} is running! Please close it first then try again.";
6
+ readonly 'wb.installer.appRunningOkKill': "{product} is running!\nClick OK to kill it";
7
+ readonly 'wb.installer.chooseMaintenanceOption': "Choose the maintenance option to perform.";
8
+ readonly 'wb.installer.choowHowToInstall': "Choose how you want to install {product}.";
9
+ readonly 'wb.installer.createDesktop': "Create desktop shortcut";
10
+ readonly 'wb.installer.dontUninstall': "Do not uninstall";
11
+ readonly 'wb.installer.dontUninstallDowngrade': "Do not uninstall (Downgrading without uninstall is disabled for this installer)";
12
+ readonly 'wb.installer.failedToKillApp': "Failed to kill {product}. Please close it first then try again";
13
+ readonly 'wb.installer.installingWebview2': "Installing WebView2...";
14
+ readonly 'wb.installer.newerVersionInstalled': "A newer version of {product} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it's better to uninstall the current version first. Select the operation you want to perform and click Next to continue.";
15
+ readonly 'wb.installer.older': "older";
16
+ readonly 'wb.installer.olderOrUnknownVersionInstalled': "An {installed} version of {product} is installed on your system. It's recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue.";
17
+ readonly 'wb.installer.silentDowngrades': "Downgrades are disabled for this installer, can't proceed with the silent installer, please use the graphical interface installer instead.\n";
18
+ readonly 'wb.installer.unableToUninstall': "Unable to uninstall!";
19
+ readonly 'wb.installer.uninstallApp': "Uninstall {product}";
20
+ readonly 'wb.installer.uninstallBeforeInstalling': "Uninstall before installing";
21
+ readonly 'wb.installer.unknown': "unknown";
22
+ readonly 'wb.installer.webview2AbortError': "Failed to install WebView2! The app can't run without it. Try restarting the installer.";
23
+ readonly 'wb.installer.webview2DownloadError': "Error: Downloading WebView2 Failed - {error}";
24
+ readonly 'wb.installer.webview2DownloadSuccess': "WebView2 bootstrapper downloaded successfully";
25
+ readonly 'wb.installer.webview2Downloading': "Downloading WebView2 bootstrapper...";
26
+ readonly 'wb.installer.webview2InstallError': "Error: Installing WebView2 failed with exit code {code}";
27
+ readonly 'wb.installer.webview2InstallSuccess': "WebView2 installed successfully";
28
+ readonly 'wb.installer.deleteAppData': "Delete the application data";
29
+ };
30
+ export type InstallerKey = keyof typeof INSTALLER_MESSAGES;
@@ -0,0 +1,36 @@
1
+ // The Windows installer's words in English (`wb.installer.*`), the source of the framework
2
+ // catalogs (`waybetter/locales/<bcp47>.json`). They are Tauri's NSIS installer messages for the
3
+ // languages Tauri does not ship itself; `packages/waybetter/scripts/installer-languages.mjs` writes
4
+ // them as `windows/languages/<Language>.nsh`, which an app lists under `customLanguageFiles`.
5
+ // Placeholders: `{product}` the app's name, `{version}` its version, `{installed}` the installed
6
+ // version, `{error}` and `{code}` what the WebView2 setup reported.
7
+ export const INSTALLER_MESSAGES = {
8
+ 'wb.installer.addOrReinstall': 'Add/Reinstall components',
9
+ 'wb.installer.alreadyInstalled': 'Already Installed',
10
+ 'wb.installer.alreadyInstalledLong': '{product} {version} is already installed. Select the operation you want to perform and click Next to continue.',
11
+ 'wb.installer.appRunning': '{product} is running! Please close it first then try again.',
12
+ 'wb.installer.appRunningOkKill': '{product} is running!\nClick OK to kill it',
13
+ 'wb.installer.chooseMaintenanceOption': 'Choose the maintenance option to perform.',
14
+ 'wb.installer.choowHowToInstall': 'Choose how you want to install {product}.',
15
+ 'wb.installer.createDesktop': 'Create desktop shortcut',
16
+ 'wb.installer.dontUninstall': 'Do not uninstall',
17
+ 'wb.installer.dontUninstallDowngrade': 'Do not uninstall (Downgrading without uninstall is disabled for this installer)',
18
+ 'wb.installer.failedToKillApp': 'Failed to kill {product}. Please close it first then try again',
19
+ 'wb.installer.installingWebview2': 'Installing WebView2...',
20
+ 'wb.installer.newerVersionInstalled': 'A newer version of {product} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it\'s better to uninstall the current version first. Select the operation you want to perform and click Next to continue.',
21
+ 'wb.installer.older': 'older',
22
+ 'wb.installer.olderOrUnknownVersionInstalled': 'An {installed} version of {product} is installed on your system. It\'s recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue.',
23
+ 'wb.installer.silentDowngrades': 'Downgrades are disabled for this installer, can\'t proceed with the silent installer, please use the graphical interface installer instead.\n',
24
+ 'wb.installer.unableToUninstall': 'Unable to uninstall!',
25
+ 'wb.installer.uninstallApp': 'Uninstall {product}',
26
+ 'wb.installer.uninstallBeforeInstalling': 'Uninstall before installing',
27
+ 'wb.installer.unknown': 'unknown',
28
+ 'wb.installer.webview2AbortError': 'Failed to install WebView2! The app can\'t run without it. Try restarting the installer.',
29
+ 'wb.installer.webview2DownloadError': 'Error: Downloading WebView2 Failed - {error}',
30
+ 'wb.installer.webview2DownloadSuccess': 'WebView2 bootstrapper downloaded successfully',
31
+ 'wb.installer.webview2Downloading': 'Downloading WebView2 bootstrapper...',
32
+ 'wb.installer.webview2InstallError': 'Error: Installing WebView2 failed with exit code {code}',
33
+ 'wb.installer.webview2InstallSuccess': 'WebView2 installed successfully',
34
+ 'wb.installer.deleteAppData': 'Delete the application data',
35
+ };
36
+ //# sourceMappingURL=installerMessages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installerMessages.js","sourceRoot":"","sources":["../../../../../shell/src/installerMessages.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,gGAAgG;AAChG,oGAAoG;AACpG,8FAA8F;AAC9F,iGAAiG;AACjG,oEAAoE;AAEpE,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,6BAA6B,EAAE,0BAA0B;IACzD,+BAA+B,EAAE,mBAAmB;IACpD,mCAAmC,EAAE,gHAAgH;IACrJ,yBAAyB,EAAE,6DAA6D;IACxF,+BAA+B,EAAE,4CAA4C;IAC7E,sCAAsC,EAAE,2CAA2C;IACnF,gCAAgC,EAAE,2CAA2C;IAC7E,4BAA4B,EAAE,yBAAyB;IACvD,4BAA4B,EAAE,kBAAkB;IAChD,qCAAqC,EAAE,iFAAiF;IACxH,8BAA8B,EAAE,gEAAgE;IAChG,iCAAiC,EAAE,wBAAwB;IAC3D,oCAAoC,EAAE,yRAAyR;IAC/T,oBAAoB,EAAE,OAAO;IAC7B,6CAA6C,EAAE,mNAAmN;IAClQ,+BAA+B,EAAE,+IAA+I;IAChL,gCAAgC,EAAE,sBAAsB;IACxD,2BAA2B,EAAE,qBAAqB;IAClD,wCAAwC,EAAE,6BAA6B;IACvE,sBAAsB,EAAE,SAAS;IACjC,iCAAiC,EAAE,0FAA0F;IAC7H,oCAAoC,EAAE,8CAA8C;IACpF,sCAAsC,EAAE,+CAA+C;IACvF,kCAAkC,EAAE,sCAAsC;IAC1E,mCAAmC,EAAE,yDAAyD;IAC9F,qCAAqC,EAAE,iCAAiC;IACxE,4BAA4B,EAAE,6BAA6B;CACnD,CAAC","sourcesContent":["// The Windows installer's words in English (`wb.installer.*`), the source of the framework\n// catalogs (`waybetter/locales/<bcp47>.json`). They are Tauri's NSIS installer messages for the\n// languages Tauri does not ship itself; `packages/waybetter/scripts/installer-languages.mjs` writes\n// them as `windows/languages/<Language>.nsh`, which an app lists under `customLanguageFiles`.\n// Placeholders: `{product}` the app's name, `{version}` its version, `{installed}` the installed\n// version, `{error}` and `{code}` what the WebView2 setup reported.\n\nexport const INSTALLER_MESSAGES = {\n 'wb.installer.addOrReinstall': 'Add/Reinstall components',\n 'wb.installer.alreadyInstalled': 'Already Installed',\n 'wb.installer.alreadyInstalledLong': '{product} {version} is already installed. Select the operation you want to perform and click Next to continue.',\n 'wb.installer.appRunning': '{product} is running! Please close it first then try again.',\n 'wb.installer.appRunningOkKill': '{product} is running!\\nClick OK to kill it',\n 'wb.installer.chooseMaintenanceOption': 'Choose the maintenance option to perform.',\n 'wb.installer.choowHowToInstall': 'Choose how you want to install {product}.',\n 'wb.installer.createDesktop': 'Create desktop shortcut',\n 'wb.installer.dontUninstall': 'Do not uninstall',\n 'wb.installer.dontUninstallDowngrade': 'Do not uninstall (Downgrading without uninstall is disabled for this installer)',\n 'wb.installer.failedToKillApp': 'Failed to kill {product}. Please close it first then try again',\n 'wb.installer.installingWebview2': 'Installing WebView2...',\n 'wb.installer.newerVersionInstalled': 'A newer version of {product} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it\\'s better to uninstall the current version first. Select the operation you want to perform and click Next to continue.',\n 'wb.installer.older': 'older',\n 'wb.installer.olderOrUnknownVersionInstalled': 'An {installed} version of {product} is installed on your system. It\\'s recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue.',\n 'wb.installer.silentDowngrades': 'Downgrades are disabled for this installer, can\\'t proceed with the silent installer, please use the graphical interface installer instead.\\n',\n 'wb.installer.unableToUninstall': 'Unable to uninstall!',\n 'wb.installer.uninstallApp': 'Uninstall {product}',\n 'wb.installer.uninstallBeforeInstalling': 'Uninstall before installing',\n 'wb.installer.unknown': 'unknown',\n 'wb.installer.webview2AbortError': 'Failed to install WebView2! The app can\\'t run without it. Try restarting the installer.',\n 'wb.installer.webview2DownloadError': 'Error: Downloading WebView2 Failed - {error}',\n 'wb.installer.webview2DownloadSuccess': 'WebView2 bootstrapper downloaded successfully',\n 'wb.installer.webview2Downloading': 'Downloading WebView2 bootstrapper...',\n 'wb.installer.webview2InstallError': 'Error: Installing WebView2 failed with exit code {code}',\n 'wb.installer.webview2InstallSuccess': 'WebView2 installed successfully',\n 'wb.installer.deleteAppData': 'Delete the application data',\n} as const;\n\nexport type InstallerKey = keyof typeof INSTALLER_MESSAGES;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"linkDrop.js","sourceRoot":"","sources":["../../../shell/src/linkDrop.ts"],"names":[],"mappings":"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","sourcesContent":["// Pure helpers for dropping a dragged link into the dock as a new tab or split pane.\n// No React, no Tauri, no dockview runtime: the Shell maps dockview drop events through these.\n\nexport const MAX_LINK_LENGTH = 4096;\n\n/** Only plain http(s) links without credentials open as tabs (same rule as the host's `tabs::parse_web_url`). */\nexport function webUrl(value: string | null | undefined): string | null {\n const text = value?.trim();\n if (!text || text.length > MAX_LINK_LENGTH) return null;\n let url: URL;\n try { url = new URL(text); } catch { return null; }\n if ((url.protocol !== 'http:' && url.protocol !== 'https:') || url.username || url.password) return null;\n return url.href;\n}\n\n/**\n * The link carried by a drop: `text/uri-list` (first non-comment line), then `text/x-moz-url`,\n * then the first line of `text/plain`; else the URL the source tab reported on dragstart.\n */\nexport function dropUrl(getData: (type: string) => string, reported?: string | null): string | null {\n const read = (type: string) => { try { return getData(type) || ''; } catch { return ''; } };\n const firstLine = (text: string, skipComments: boolean) =>\n text.split(/\\r?\\n/).map(line => line.trim()).find(line => line && !(skipComments && line.startsWith('#'))) ?? '';\n return webUrl(firstLine(read('text/uri-list'), true))\n ?? webUrl(firstLine(read('text/x-moz-url'), false))\n ?? webUrl(firstLine(read('text/plain'), false))\n ?? webUrl(reported);\n}\n\n/** Drag types that may carry a link. File drags are left to the page (e.g. a composer). */\nexport function carriesLink(types: readonly string[]): boolean {\n if (types.includes('Files')) return false;\n return types.includes('text/uri-list') || types.includes('text/x-moz-url');\n}\n\nexport type DropPosition = 'top' | 'bottom' | 'left' | 'right' | 'center';\nexport type DropDirection = 'left' | 'right' | 'above' | 'below';\nexport type Placement =\n | { referenceGroup: string; direction: 'within' | DropDirection; index?: number }\n | { direction: DropDirection };\n\nconst DIRECTIONS: Record<Exclude<DropPosition, 'center'>, DropDirection> = { top: 'above', bottom: 'below', left: 'left', right: 'right' };\n\n/**\n * Where a dropped link opens. `groupId`: the group under the pointer (missing for the dock's outer\n * edges). `tabIndex`: the tab dropped on, if any. `undefined`: the default (active group, or a new\n * group in an empty dock).\n */\nexport function placementFor(target: { position: DropPosition; groupId?: string; tabIndex?: number }): Placement | undefined {\n const { position, groupId, tabIndex } = target;\n if (!groupId) return position === 'center' ? undefined : { direction: DIRECTIONS[position] };\n if (position === 'center') return tabIndex === undefined ? { referenceGroup: groupId, direction: 'within' } : { referenceGroup: groupId, direction: 'within', index: tabIndex };\n return { referenceGroup: groupId, direction: DIRECTIONS[position] };\n}\n"]}
1
+ {"version":3,"file":"linkDrop.js","sourceRoot":"","sources":["../../../../../shell/src/linkDrop.ts"],"names":[],"mappings":"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","sourcesContent":["// Pure helpers for dropping a dragged link into the dock as a new tab or split pane.\n// No React, no Tauri, no dockview runtime: the Shell maps dockview drop events through these.\n\nexport const MAX_LINK_LENGTH = 4096;\n\n/** Only plain http(s) links without credentials open as tabs (same rule as the host's `tabs::parse_web_url`). */\nexport function webUrl(value: string | null | undefined): string | null {\n const text = value?.trim();\n if (!text || text.length > MAX_LINK_LENGTH) return null;\n let url: URL;\n try { url = new URL(text); } catch { return null; }\n if ((url.protocol !== 'http:' && url.protocol !== 'https:') || url.username || url.password) return null;\n return url.href;\n}\n\n/**\n * The link carried by a drop: `text/uri-list` (first non-comment line), then `text/x-moz-url`,\n * then the first line of `text/plain`; else the URL the source tab reported on dragstart.\n */\nexport function dropUrl(getData: (type: string) => string, reported?: string | null): string | null {\n const read = (type: string) => { try { return getData(type) || ''; } catch { return ''; } };\n const firstLine = (text: string, skipComments: boolean) =>\n text.split(/\\r?\\n/).map(line => line.trim()).find(line => line && !(skipComments && line.startsWith('#'))) ?? '';\n return webUrl(firstLine(read('text/uri-list'), true))\n ?? webUrl(firstLine(read('text/x-moz-url'), false))\n ?? webUrl(firstLine(read('text/plain'), false))\n ?? webUrl(reported);\n}\n\n/** Drag types that may carry a link. File drags are left to the page (e.g. a composer). */\nexport function carriesLink(types: readonly string[]): boolean {\n if (types.includes('Files')) return false;\n return types.includes('text/uri-list') || types.includes('text/x-moz-url');\n}\n\nexport type DropPosition = 'top' | 'bottom' | 'left' | 'right' | 'center';\nexport type DropDirection = 'left' | 'right' | 'above' | 'below';\nexport type Placement =\n | { referenceGroup: string; direction: 'within' | DropDirection; index?: number }\n | { direction: DropDirection };\n\nconst DIRECTIONS: Record<Exclude<DropPosition, 'center'>, DropDirection> = { top: 'above', bottom: 'below', left: 'left', right: 'right' };\n\n/**\n * Where a dropped link opens. `groupId`: the group under the pointer (missing for the dock's outer\n * edges). `tabIndex`: the tab dropped on, if any. `undefined`: the default (active group, or a new\n * group in an empty dock).\n */\nexport function placementFor(target: { position: DropPosition; groupId?: string; tabIndex?: number }): Placement | undefined {\n const { position, groupId, tabIndex } = target;\n if (!groupId) return position === 'center' ? undefined : { direction: DIRECTIONS[position] };\n if (position === 'center') return tabIndex === undefined ? { referenceGroup: groupId, direction: 'within' } : { referenceGroup: groupId, direction: 'within', index: tabIndex };\n return { referenceGroup: groupId, direction: DIRECTIONS[position] };\n}\n"]}
@@ -0,0 +1,16 @@
1
+ export declare const SHELL_MESSAGES: {
2
+ readonly 'wb.account.notSignedIn': "Not signed in yet";
3
+ readonly 'wb.account.signedOut': "{handle} · signed out";
4
+ readonly 'wb.account.newName': "New account";
5
+ readonly 'wb.update.readyLabel': "Update ready · restart";
6
+ readonly 'wb.update.readyTitle': "Restart to update to {product} {version}. Tabs are restored.";
7
+ readonly 'wb.update.installingLabel': "Updating…";
8
+ readonly 'wb.update.installingTitle': "Installing {product} {version}";
9
+ readonly 'wb.update.problemLabel': "Update problem";
10
+ readonly 'wb.update.problemTitle': "The last update did not start correctly. Download the current version.";
11
+ };
12
+ export type ShellKey = keyof typeof SHELL_MESSAGES;
13
+ /** A translator for the shell models: the message for `key` (unformatted) or undefined for English. */
14
+ export type ShellText = (key: ShellKey) => string | undefined;
15
+ /** The message for `key` with `{name}` placeholders filled in (values inserted as text). */
16
+ export declare function shellText(key: ShellKey, params?: Record<string, string>, text?: ShellText): string;
@@ -0,0 +1,27 @@
1
+ // The shell models' own words (account labels, the update chip) in English, with `{name}`
2
+ // placeholders. They live in the framework catalogs (`waybetter/locales/<bcp47>.json`, `wb.*`), so
3
+ // every wayBetter app shows them in its language: pass a `text(key)` translator to the models; it
4
+ // returns the translated message (placeholders not yet filled) or undefined for English.
5
+ export const SHELL_MESSAGES = {
6
+ 'wb.account.notSignedIn': 'Not signed in yet',
7
+ 'wb.account.signedOut': '{handle} · signed out',
8
+ 'wb.account.newName': 'New account',
9
+ 'wb.update.readyLabel': 'Update ready · restart',
10
+ 'wb.update.readyTitle': 'Restart to update to {product} {version}. Tabs are restored.',
11
+ 'wb.update.installingLabel': 'Updating…',
12
+ 'wb.update.installingTitle': 'Installing {product} {version}',
13
+ 'wb.update.problemLabel': 'Update problem',
14
+ 'wb.update.problemTitle': 'The last update did not start correctly. Download the current version.',
15
+ };
16
+ /** The message for `key` with `{name}` placeholders filled in (values inserted as text). */
17
+ export function shellText(key, params = {}, text) {
18
+ let message = SHELL_MESSAGES[key];
19
+ try {
20
+ const translated = text?.(key);
21
+ if (typeof translated === 'string' && translated)
22
+ message = translated;
23
+ }
24
+ catch { /* English */ }
25
+ return message.replace(/\{(\w+)\}/g, (whole, name) => (name in params ? params[name] : whole));
26
+ }
27
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../../../shell/src/messages.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,mGAAmG;AACnG,kGAAkG;AAClG,yFAAyF;AAEzF,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,wBAAwB,EAAE,mBAAmB;IAC7C,sBAAsB,EAAE,uBAAuB;IAC/C,oBAAoB,EAAE,aAAa;IACnC,sBAAsB,EAAE,wBAAwB;IAChD,sBAAsB,EAAE,8DAA8D;IACtF,2BAA2B,EAAE,WAAW;IACxC,2BAA2B,EAAE,gCAAgC;IAC7D,wBAAwB,EAAE,gBAAgB;IAC1C,wBAAwB,EAAE,wEAAwE;CAC1F,CAAC;AAKX,4FAA4F;AAC5F,MAAM,UAAU,SAAS,CAAC,GAAa,EAAE,SAAiC,EAAE,EAAE,IAAgB;IAC5F,IAAI,OAAO,GAAW,cAAc,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU;YAAE,OAAO,GAAG,UAAU,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;IACzB,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1G,CAAC","sourcesContent":["// The shell models' own words (account labels, the update chip) in English, with `{name}`\n// placeholders. They live in the framework catalogs (`waybetter/locales/<bcp47>.json`, `wb.*`), so\n// every wayBetter app shows them in its language: pass a `text(key)` translator to the models; it\n// returns the translated message (placeholders not yet filled) or undefined for English.\n\nexport const SHELL_MESSAGES = {\n 'wb.account.notSignedIn': 'Not signed in yet',\n 'wb.account.signedOut': '{handle} · signed out',\n 'wb.account.newName': 'New account',\n 'wb.update.readyLabel': 'Update ready · restart',\n 'wb.update.readyTitle': 'Restart to update to {product} {version}. Tabs are restored.',\n 'wb.update.installingLabel': 'Updating…',\n 'wb.update.installingTitle': 'Installing {product} {version}',\n 'wb.update.problemLabel': 'Update problem',\n 'wb.update.problemTitle': 'The last update did not start correctly. Download the current version.',\n} as const;\nexport type ShellKey = keyof typeof SHELL_MESSAGES;\n/** A translator for the shell models: the message for `key` (unformatted) or undefined for English. */\nexport type ShellText = (key: ShellKey) => string | undefined;\n\n/** The message for `key` with `{name}` placeholders filled in (values inserted as text). */\nexport function shellText(key: ShellKey, params: Record<string, string> = {}, text?: ShellText): string {\n let message: string = SHELL_MESSAGES[key];\n try {\n const translated = text?.(key);\n if (typeof translated === 'string' && translated) message = translated;\n } catch { /* English */ }\n return message.replace(/\\{(\\w+)\\}/g, (whole, name: string) => (name in params ? params[name]! : whole));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"palette.js","sourceRoot":"","sources":["../../../shell/src/palette.ts"],"names":[],"mappings":"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","sourcesContent":["// Command palette core: fuzzy scoring, ranking and selection movement. The app builds its own\n// items (tabs, profiles, settings sections, site destinations); every item is navigation only.\n\nexport type RankedItem = { label: string; keywords?: string; group: string };\n\n/** Subsequence match, case-insensitive. 0 = no match; prefix/word-start/consecutive hits score higher. */\nexport function fuzzyScore(target: string, query: string): number {\n const t = target.toLowerCase();\n const q = query.toLowerCase().replace(/\\s+/g, ' ').trim();\n if (!q) return 1;\n if (!t) return 0;\n if (t.startsWith(q)) return 1000 - t.length;\n const at = t.indexOf(q);\n if (at >= 0) return 600 - at - t.length / 10 + (/[\\s/_-]/.test(t[at - 1] ?? ' ') ? 100 : 0);\n let score = 0;\n let ti = 0;\n let previous = -2;\n for (const char of q) {\n if (char === ' ') continue;\n const found = t.indexOf(char, ti);\n if (found < 0) return 0;\n score += 10;\n if (found === previous + 1) score += 15;\n if (found === 0 || /[\\s/_-]/.test(t[found - 1]!)) score += 20;\n previous = found;\n ti = found + 1;\n }\n return Math.max(1, score - t.length / 10);\n}\n\n/** An item's score: its label, or half of its keywords/group match. */\nexport function scoreItem(item: RankedItem, query: string): number {\n const label = fuzzyScore(item.label, query);\n const extra = Math.max(fuzzyScore(item.keywords ?? '', query), fuzzyScore(item.group, query)) * 0.5;\n return Math.max(label, extra);\n}\n\n/** Matching items, best first; equal scores keep their original order. `skip` items never match. */\nexport function rankItems<T extends RankedItem>(items: readonly T[], query: string, skip: (item: T) => boolean = () => false): T[] {\n return items\n .map((item, index) => ({ item, index, score: skip(item) ? 0 : scoreItem(item, query) }))\n .filter(entry => entry.score > 0)\n .sort((a, b) => b.score - a.score || a.index - b.index)\n .map(entry => entry.item);\n}\n\n/** Wraps selection movement within the list. */\nexport const moveSelection = (index: number, step: number, length: number) =>\n length === 0 ? 0 : (index + step + length) % length;\n"]}
1
+ {"version":3,"file":"palette.js","sourceRoot":"","sources":["../../../../../shell/src/palette.ts"],"names":[],"mappings":"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","sourcesContent":["// Command palette core: fuzzy scoring, ranking and selection movement. The app builds its own\n// items (tabs, profiles, settings sections, site destinations); every item is navigation only.\n\nexport type RankedItem = { label: string; keywords?: string; group: string };\n\n/** Subsequence match, case-insensitive. 0 = no match; prefix/word-start/consecutive hits score higher. */\nexport function fuzzyScore(target: string, query: string): number {\n const t = target.toLowerCase();\n const q = query.toLowerCase().replace(/\\s+/g, ' ').trim();\n if (!q) return 1;\n if (!t) return 0;\n if (t.startsWith(q)) return 1000 - t.length;\n const at = t.indexOf(q);\n if (at >= 0) return 600 - at - t.length / 10 + (/[\\s/_-]/.test(t[at - 1] ?? ' ') ? 100 : 0);\n let score = 0;\n let ti = 0;\n let previous = -2;\n for (const char of q) {\n if (char === ' ') continue;\n const found = t.indexOf(char, ti);\n if (found < 0) return 0;\n score += 10;\n if (found === previous + 1) score += 15;\n if (found === 0 || /[\\s/_-]/.test(t[found - 1]!)) score += 20;\n previous = found;\n ti = found + 1;\n }\n return Math.max(1, score - t.length / 10);\n}\n\n/** An item's score: its label, or half of its keywords/group match. */\nexport function scoreItem(item: RankedItem, query: string): number {\n const label = fuzzyScore(item.label, query);\n const extra = Math.max(fuzzyScore(item.keywords ?? '', query), fuzzyScore(item.group, query)) * 0.5;\n return Math.max(label, extra);\n}\n\n/** Matching items, best first; equal scores keep their original order. `skip` items never match. */\nexport function rankItems<T extends RankedItem>(items: readonly T[], query: string, skip: (item: T) => boolean = () => false): T[] {\n return items\n .map((item, index) => ({ item, index, score: skip(item) ? 0 : scoreItem(item, query) }))\n .filter(entry => entry.score > 0)\n .sort((a, b) => b.score - a.score || a.index - b.index)\n .map(entry => entry.item);\n}\n\n/** Wraps selection movement within the list. */\nexport const moveSelection = (index: number, step: number, length: number) =>\n length === 0 ? 0 : (index + step + length) % length;\n"]}
@@ -1,3 +1,5 @@
1
+ /** `role`: 'column' boxes are deck columns (Power User Mode); they hide the site's chrome themselves
2
+ * and never take part in the rail rules. Missing = an ordinary pane. */
1
3
  export type PaneBox = {
2
4
  id: string;
3
5
  url: string;
@@ -5,6 +7,7 @@ export type PaneBox = {
5
7
  x: number;
6
8
  y: number;
7
9
  visible: boolean;
10
+ role?: 'pane' | 'column';
8
11
  };
9
12
  /** `besideOf`: the source group ids whose "beside" links this group's tabs were opened for. */
10
13
  export type GroupBox = {
@@ -31,3 +34,22 @@ export declare function redundantNavPanes(panes: readonly PaneBox[], isSiteUrl:
31
34
  export declare function withNavRedundant<T extends PaneBox>(boxes: readonly T[], isSiteUrl: (url: string) => boolean, memory: Map<string, boolean>): Array<T & {
32
35
  navRedundant: boolean;
33
36
  }>;
37
+ /**
38
+ * A tab webview's `visible`/`parked` for `tabs_sync`. `shown`: its pane is on screen in the shell;
39
+ * `overlay`: shell overlays open (menus, dialogs, palette, drags); `raiseSupported`: the shell can
40
+ * be raised above the tab webviews for them (`shell_raise`), so panes stay visible under
41
+ * the overlay. Where it cannot, an overlay hides every tab (the shell would draw under them). An
42
+ * overlay never parks (drops to low memory) a tab: only a pane that is not shown is parked.
43
+ */
44
+ export declare function paneVisibility(pane: {
45
+ shown: boolean;
46
+ overlay: number;
47
+ raiseSupported: boolean;
48
+ }): {
49
+ visible: boolean;
50
+ parked: boolean;
51
+ };
52
+ /** `shell_raise`'s startup probe (`probe`: its answer) unless the developer switch turned raising off. */
53
+ export declare function raiseSupported(probe: unknown, devOff: boolean): boolean;
54
+ /** `[r, g, b]` of a computed CSS color (`rgb(...)`/`rgba(...)`), or null (unparsable or fully transparent). */
55
+ export declare function cssRgb(color: string): [number, number, number] | null;