packages/shell/src/panel (waybetter/shell/panel): an app's own tab. An app describes itself
(PanelSite: brand and the home page's words, its own sections and their order, its theme store,
catalog and the preview component a theme document is drawn in, Make's examples and docs, the
install controller, its languages, what its native side serves) and createPanel returns the
component for ShellSite.panel. It is in the shell package because it is drawn in the frame and
shares its stores, native bridge and language.
- Panel.tsx (header, settings search over every settings section, navigation, toasts; Accounts
and Updates), nav.ts (which built-in sections an app gets: each shows only when the app serves
what it needs; the app's sections in its order), Home.tsx (hero, highlights, About from the
app's data), controls.tsx + panel.css.
- Appearance.tsx, ThemeBuilder.tsx + builderModel.ts + builder.css, fonts/ (FontBrowser, FontRoles,
catalog, the offline Google Fonts list; scripts/google-fonts-catalog.mjs regenerates it):
the theme documents are the runtime's, the store, catalog, accents, draft palette, file suffix
and preview are the app's (PanelSite.themes).
- Plugins.tsx (the plugins list and custom CSS over the host's plugins_*/custom_css_*),
StoreSection.tsx, MakePanel.tsx + makeModel.ts + MarkdownDoc.tsx + markdown.ts + make.css (the
examples, the theme file and the docs are the app's), Settings.tsx (links and session over
settings_get/set with `siteLinks`, keyword alerts, the media panel), FeatureToggles.tsx
(useFeatures + FeatureGroups over features_get/set: the app names its flags and groups),
PowerSettings.tsx (deck defaults from site.deck: its flags and presets; DeckPreset gets `name`
and `hint`), BackupPanel.tsx + backup.css, DeveloperPanel.tsx, LanguageSettings.tsx, compare.ts.
- frame: language.ts (createLanguage: follow the site / the system / one language, i18n_set;
moved from the app), appI18n.ts (createAppI18n: the app's typed i18n instance, useT, dates and
numbers; the app passes React's useSyncExternalStore), formatDate in i18n.ts (ShellI18n.date).
- tests/panel.test.ts: every panel key has English and is used, sections per app, the builder
model, the font catalog, plugin header rules, the UI kit demos, Markdown, compare.
- npm package: exports ./shell/panel, ./shell/panel/*, ./shell/panel/*.css; the build is
scripts/build.mjs (the shell is compiled with the runtime sources it imports under one root and
its imports are pointed at dist/runtime; stylesheets and the font list are copied).
Moved from wayBetter for X so every wayBetter app gets the Store UI; the app passes its native
bridge, theme adapter, translator and (optionally) its own controls and button classes.
- storeModel.ts: wire types of the native store commands (InstallPreview, StoreCatalogView,
LinkEvent, StoreItem with `apps`), permission badges in the site's words, categories, item state
(install/installed/update/changed locally/built in), search, free theme ids, versions, previews.
- installController.ts: the install screen's state machine (links incl. those queued before the
shell listened, dropped files, store items, cancel, confirm), generic over the app's theme format
(`ThemeAdapter`: parse, ids, facts, save) and its bridge (`StoreBackend`: invoke/listen).
- InstallDialog.tsx (`InstallHost`): the screen (Install enabled after 1 s, Enter never installs,
tabs hidden via setOverlay) and the window-wide drop target. StoreView.tsx: search, kinds,
categories, cards, permission badges, install/update/remove; default controls or the app's.
- store.css: both, themed with framework `--wb-*` tokens (documented; dark defaults).
- storeMessages.ts + every framework catalog: 120 `wb.store.*`, `wb.install.*`, `wb.permission.*`
messages moved from the app catalogs with all existing translations; the six that named X take
`{site}`; generic words the components need copied with their translations.
- npm package: exports for the new modules and store.css, optional react/react-dom peers; @types
for the typecheck. Tests: models, controller flows with a fake bridge, every looked-up key exists.
Drop private from @waybetter/runtime and @waybetter/shell (root stays
private), add per-module exports with types/import conditions backed by
a tsc build (rewriteRelativeImportExtensions rewrites .ts specifiers to
.js in dist), files/sideEffects/engines/keywords/publishConfig, a
prepublishOnly that builds and tests, and a README + copied LICENSE per
package. Root gains build:packages and pack:check scripts. dist/ is
gitignored; the desktop app keeps importing raw src/*.ts by relative
path, unaffected.