@sempods/apps 0.7.1 → 0.8.0-dev.1

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 (56) hide show
  1. package/CHANGELOG.md +190 -0
  2. package/README.md +6 -3
  3. package/bin/sempods-apps.mjs +1 -0
  4. package/instructions/app-workflow.md +254 -111
  5. package/instructions/publish.md +13 -7
  6. package/instructions/setup.md +33 -23
  7. package/instructions/visual-check.md +43 -0
  8. package/package.json +3 -3
  9. package/scripts/build-site.mjs +15 -3
  10. package/scripts/check.mjs +3 -1
  11. package/scripts/icon.mjs +47 -0
  12. package/scripts/lib/apps.mjs +56 -2
  13. package/scripts/lib/generate.mjs +55 -14
  14. package/scripts/lib/icon.mjs +192 -0
  15. package/scripts/lib/overview.mjs +5 -3
  16. package/scripts/lib/page.mjs +89 -0
  17. package/scripts/lib/themes.mjs +58 -0
  18. package/scripts/migrate.mjs +37 -14
  19. package/scripts/new-app.mjs +43 -10
  20. package/scripts/sdk-update.mjs +16 -1
  21. package/shared/files/{f2fb601d5ebc4ca72274ac9d3fcf7b7a96e27958bb92cd065a9165b501ee94d7 → 44c114d4d2c8b172f4757100f79e8a1a00d30c96ba2ad8f75c3373e52f6b849f} +2 -2
  22. package/shared/files/{31ede0d1a035d8531100ebfd751510c772ab0871309a0b9752a77fb96187eb53 → 843c078e84912158607ebb8ce0042589d676a742bcd3cf8b6c474d62ff3a6845} +3 -2
  23. package/shared/files/{1c29eed0a0297c742ca5814de9081ff8efce3b2da5d9e1bdf90a403873da4aa9 → f30ec6b7f9de16be54919382ab18cdcc33ee64938f7b907d855bcf6740e4c102} +8 -2
  24. package/shared/snapshot.json +4 -4
  25. package/skeleton/app/NOTES.md +11 -1
  26. package/skeleton/app/index.html +7 -3
  27. package/skeleton/app/package.json +6 -6
  28. package/skeleton/app/src/App.tsx +53 -21
  29. package/skeleton/app/src/NewVersionNotice.tsx +6 -11
  30. package/skeleton/app/src/examples/ListScreen.tsx +167 -0
  31. package/skeleton/app/src/index.css +86 -13
  32. package/skeleton/app/src/main.tsx +3 -0
  33. package/skeleton/app/src/pwa.ts +1 -1
  34. package/skeleton/app/src/routes.test.ts +19 -0
  35. package/skeleton/app/src/routes.ts +139 -0
  36. package/skeleton/app/src/texts.test.ts +28 -0
  37. package/skeleton/app/src/texts.ts +35 -0
  38. package/skeleton/app/src/themes/calm.css +11 -0
  39. package/skeleton/app/src/themes/fresh.css +11 -0
  40. package/skeleton/app/src/themes/playful.css +11 -0
  41. package/skeleton/app/src/themes/warm.css +11 -0
  42. package/skeleton/app/src/ui/Composer.tsx +18 -0
  43. package/skeleton/app/src/ui/ContextSwitch.tsx +85 -0
  44. package/skeleton/app/src/ui/Dialog.tsx +103 -0
  45. package/skeleton/app/src/ui/Menu.tsx +118 -0
  46. package/skeleton/app/src/ui/Tabs.tsx +39 -0
  47. package/skeleton/app/src/ui/dismiss.ts +30 -0
  48. package/skeleton/app/src/ui/icons.tsx +53 -0
  49. package/skeleton/app/src/ui/ui.css +240 -0
  50. package/skeleton/app/vite.config.ts +4 -4
  51. package/skills/update/SKILL.md +4 -2
  52. package/skeleton/app/public/favicon.svg +0 -1
  53. package/skeleton/app/public/icon-192.png +0 -0
  54. package/skeleton/app/public/icon-512.png +0 -0
  55. package/skeleton/app/src/start.test.ts +0 -15
  56. package/skeleton/app/src/start.ts +0 -9
package/CHANGELOG.md CHANGED
@@ -4,6 +4,196 @@ Each release lists what changed and **upgrade notes** for the assistant that
4
4
  applies it. The notes cover what an update cannot decide alone: owner files,
5
5
  configuration choices and the SDK migration.
6
6
 
7
+ ## 0.8.0
8
+
9
+ ### Changes
10
+
11
+ SDK:
12
+
13
+ - New repositories use SDK 0.6.0 (`@sempods/app-sdk` and
14
+ `@sempods/client-sdk`), and `@sempods/apps` supports `^0.6.0`. The 0.6.0
15
+ release notes and migration guide name what changes for apps: among others,
16
+ `AppShell` and `ConnectionControls` are gone, row commands move to
17
+ `mutate.for(item)`, SDK texts follow the browser language, lists keep their
18
+ rows while reloading, a cancelled re-authorization keeps the session, and
19
+ the leave confirmation shows above app dialogs.
20
+ - After an SDK update, `sdk-update` and the app workflow point to the
21
+ installed release notes and migration guide
22
+ (`node_modules/@sempods/app-sdk/docs/releases/<version>.md`, `migration.md`)
23
+ instead of GitHub, and the workflow skips a section on adopting the release
24
+ in the apps template.
25
+
26
+ Look:
27
+
28
+ - Four themes in the skeleton's `src/themes/`: calm (the default, graphite on
29
+ white), fresh (teal), warm (terracotta on cream) and playful (violet). Each
30
+ sets the six `--sempods-*` colour tokens in light and dark mode with at
31
+ least 4.5:1 contrast, which a test checks; the SDK components read the same
32
+ tokens, so a theme restyles the whole app. Fonts and corner radii stay the
33
+ SDK's. An app imports one theme in `src/main.tsx`; `new-app --theme <name>`
34
+ chooses it.
35
+ - The skeleton's `src/index.css` styles only the app's own markup and leaves
36
+ SDK components (`[data-sempods-ui]`) alone, so `AppAccess` keeps its
37
+ layout. App buttons read as text in the accent colour with a calm hover, a
38
+ visible focus and 44px touch targets. Inputs have 44px targets; checkboxes
39
+ and radios are a compact 24px box whose wrapping `<label>` is the 44px
40
+ target, as in the SDK. Lists lose the browser's indentation and bullets.
41
+ - The page's `theme-color` follows light and dark mode, and the generated web
42
+ app manifest uses a white background and theme colour instead of green.
43
+ - `new-app` draws the app icon as a monogram, the title's first letter on a
44
+ rounded square in the theme's accent, instead of a plain green square:
45
+ `public/favicon.svg` (in the theme's dark accent in dark mode) and the
46
+ manifest icons `icon-192.png` and `icon-512.png`, all from the same strokes.
47
+ A title that does not start with a letter A–Z, accents aside, gets the plain
48
+ square. `pnpm run icon <id>` (new) draws it again after a rename or a theme
49
+ change.
50
+ - The skeleton's header shows the app's icon and name, room for the app's
51
+ icon actions and a menu (⋮) whose "Pods & sharing" opens `AppAccess`
52
+ management as its dialog (`onClose`), with signing out inside. It replaces
53
+ the "Data access" button. `AppAccess` shows the icon and the app's
54
+ description on the sign-in screen, `<AccessNotice only="write" />` beside it
55
+ says when a context is shared read-only, and the viewport adds
56
+ `viewport-fit=cover` and `interactive-widget=resizes-content`.
57
+ - The skeleton has a small UI kit in `src/ui/`, styled by `ui.css` on the
58
+ `--sempods-*` tokens: `Menu` (a button with a list of actions or choices;
59
+ Escape, a press outside and the arrow keys), `ContextSwitch` (the everyday
60
+ switch between the contexts shared with the app over the SDK's
61
+ `useContexts`, in place of the app's name), `Tabs` (views as links with
62
+ their routes), `Composer` (an input bar fixed at the bottom, above the home
63
+ indicator and, where browsers support it, the on-screen keyboard), `Dialog`
64
+ (modal, a bottom sheet on phones, for example around a `ResourceEditor`)
65
+ and line icons.
66
+ - The skeleton ships `src/examples/ListScreen.tsx`, not mounted: the SDK's
67
+ quickstart screen built with the kit (loading and failed reads, an empty
68
+ state, rows with a labelled checkbox, the item's `ResourceEditor` in a
69
+ `Dialog`, `RemoveButton`, open outcomes and a `Composer`). It compiles with
70
+ every app, so it stays valid against the SDK.
71
+
72
+ Content and configuration:
73
+
74
+ - Apps are international by default. `language` in `apps.json` accepts
75
+ `"auto"`, and `new-app` uses it unless `--language de` or `en` fixes one
76
+ language. The skeleton resolves the UI language and locale from the browser
77
+ with the SDK's `resolveLocale` (German or English, otherwise English, with
78
+ the browser's region for formats), passes both to `SempodsProvider` and
79
+ sets `<html lang>`. For `"auto"` the generated configuration keeps
80
+ `app.language` as `"auto"`, the manifest has no `lang` and the overview
81
+ announces no language for the app.
82
+ - The skeleton keeps the app's own texts in `src/texts.ts`, one typed
83
+ catalogue per language, read with the SDK's `useMessages(texts)` and tested
84
+ in `src/texts.test.ts`; `src/start.ts` and its test are gone.
85
+ - The app title has one source, `apps.json`. The generated
86
+ `vite.sempods.generated.ts` exports the Vite plugin `pageTitle`, which adds
87
+ the title to the head of the served and built page; the skeleton's
88
+ `vite.config.ts` uses it and its `index.html` has no `<title>` of its own.
89
+ `check` reports a page with its own title and a `vite.config.ts` without
90
+ the plugin.
91
+ - `apps.json` accepts an optional `description` (one short sentence), set by
92
+ `new-app --description`. It becomes the generated `app.description`, which
93
+ the skeleton passes to `AppAccess`, the manifest's `description` and the
94
+ overview card's line.
95
+ - Apps can give their views addresses: `routes` in an app's `apps.json` entry
96
+ lists lowercase English segments, for example `"routes": ["bought"]` for
97
+ `/<id>/bought`. The generated `app.routes` lists them, and `build-site`
98
+ writes `<id>/<route>.html`, so the published site answers each route
99
+ without a rewrite and unknown paths still show the not-found page. The
100
+ service worker serves the cached app for the start page and every route,
101
+ and the generated `returnTo` is a function the runtime calls when each
102
+ sign-in starts, so sign-in returns to the route the person is on.
103
+ - The skeleton's `src/routes.ts` provides `useRoute()`: the current route,
104
+ `link(route)` for an `<a>` to it and `go(route)`, which switches views under
105
+ the SDK's leave policy (`useApp().navigate`); back and forward are guarded
106
+ the same way, and staying keeps the view and its address. It shows unknown
107
+ paths as the start page and drops a trailing slash. The runtime's
108
+ `replaceUrl` goes through it, so the return after a sign-in shows the right
109
+ view.
110
+ - `migrate` moves existing apps where that is unambiguous: a `vite.config.ts`
111
+ unchanged from the skeleton gets the `pageTitle` plugin, and a page whose
112
+ only title is the app's title from `apps.json` loses it. It does so, and
113
+ regenerates the apps, also for a release whose starter is unchanged. A page
114
+ or `vite.config.ts` that is a symbolic link stops `update` and `migrate`
115
+ before they change anything.
116
+
117
+ Instructions:
118
+
119
+ - The app workflow starts a new app with a short design conversation
120
+ (purpose, mood as a theme, name and icon), asked as choices with "choose for
121
+ me", and records it under Design in the app's `NOTES.md`; later wishes
122
+ change the recorded choice instead of adding one-off styles. It says which
123
+ parts of the look are shared (layout, kit) and which are chosen per app
124
+ (theme, name, icon).
125
+ - The app workflow settles how an app uses contexts before its first screen:
126
+ one context, several one at a time, read all and write in one, or write
127
+ into several. It infers the shape or asks once in everyday words and starts
128
+ from the SDK's path for it (`AppAccess` or a preset, `useContexts` with
129
+ `ContextSwitch`, the Pod overview with `useCreation`, one `useCreation` per
130
+ context). The skeleton's `NOTES.md` has Design and Data sections, and setup
131
+ asks for one test context per context the shape uses.
132
+ - The app workflow starts a list from the list example, takes only behaviour
133
+ from the SDK's examples, deletes rows with `RemoveButton`, relies on the
134
+ SDK's list refresh when the page becomes visible again, adds kit parts only
135
+ when the app needs them, and describes routes, renaming and themes. It is
136
+ reordered: design conversation and `new-app`, context shape, vocabulary,
137
+ screen, views, configuration.
138
+ - A visual check before handover (`instructions/visual-check.md`): the
139
+ assistant takes screenshots at 375px and desktop width, light and dark, with
140
+ real states (empty, a few items, an open item, a notice), checks them
141
+ against a short checklist, fixes what fails and shows the owner the 375px
142
+ screenshot for a verdict. The app workflow and setup require it; visual
143
+ checks are their own kind of evidence in `NOTES.md`. The docs no longer say
144
+ the screen can be tried without a Pod: only the sign-in screen can.
145
+ - The setup record of new repositories names "Test Pod and contexts" and the
146
+ owner's language for the app texts.
147
+
148
+ ### Upgrade notes
149
+
150
+ 1. The migration does by itself: it adds the root script `icon`, regenerates
151
+ every app (`app.routes`, `app.description` as `null` until set, the
152
+ manifest colours, the `pageTitle` plugin, the service worker's allowlist
153
+ for routes) and moves apps to the generated page title where that is
154
+ unambiguous, listed under "Updated". For any other app, `check` names what
155
+ is left: add `pageTitle` from `./vite.sempods.generated.ts` to the plugins
156
+ in its `vite.config.ts`, as the skeleton does, and remove the `<title>`
157
+ from its `index.html`. A page title other than the one in `apps.json` was
158
+ chosen by hand: ask the owner whether it should be the app's title, put it
159
+ into `apps.json` and run `pnpm run regenerate`. Settle these cases before
160
+ the SDK move: `sdk-update` ends with `check` and stops on them.
161
+ 2. Then move the repository to SDK 0.6.0, on its own branch:
162
+ `pnpm run sdk-update 0.6.0`. Until then `check` reports the SDK as outside
163
+ the supported range, and apps created by `new-app` would use the old SDK
164
+ with a skeleton written for 0.6.0. Then follow the SDK's migration
165
+ checklist (`node_modules/@sempods/app-sdk/docs/migration.md`, "From 0.5.0
166
+ to 0.6.0") for each app: replace `AppShell`/`ConnectionControls` with the
167
+ skeleton's layout, move row commands to `mutate.for(item)`, handle
168
+ `not-sent` results, and check texts and dialogs that tests match. Run
169
+ `pnpm run check --standalone all` and list for the owner what to try on the
170
+ Pod: sign-in, reload, editing, guarded navigation and recovery.
171
+ 3. Existing apps keep their code, look and notes. When working on an app next,
172
+ offer what the owner wants of the new skeleton, from
173
+ `node_modules/@sempods/apps/skeleton/app/`, once the repository is on SDK
174
+ 0.6.0:
175
+ - a theme: copy `src/themes/`, import the chosen one in `src/main.tsx`
176
+ before `index.css`, remove the token block from `index.css`, and run
177
+ `pnpm run icon <id>` for a monogram in its accent;
178
+ - the scoped CSS rules of `src/index.css`, where the app still has global
179
+ `header`, `button`, `input` or `select` rules: they stop shifting the
180
+ sign-in form and placing the `AppAccess` icon beside its title;
181
+ - the header with icon, name and menu, `src/ui/` and `AppAccess` with
182
+ `icon`, `description` and `onClose`, with their texts in `src/texts.ts`;
183
+ - routes, for an app that switches views by itself: copy `src/routes.ts`
184
+ and `src/routes.test.ts`, pass `replaceUrl` to `createBrowserRuntime` as
185
+ `src/App.tsx` does, list the routes in `apps.json` and run
186
+ `pnpm run regenerate`; an app that rewrote its address after a sign-in
187
+ can drop that code;
188
+ - the browser's language: set `language` to `"auto"` in `apps.json`, run
189
+ `pnpm run regenerate` and adopt `uiLocale` from `src/texts.ts` in
190
+ `src/App.tsx` (passed as `language` and `locale`, and
191
+ `document.documentElement.lang`), because `app.language` is then
192
+ `"auto"`; read the app's texts from a catalogue with both languages
193
+ through `useMessages`;
194
+ - Design and Data sections in `NOTES.md`, settling the context shape as the
195
+ app workflow describes.
196
+
7
197
  ## 0.7.1
8
198
 
9
199
  ### Changes
package/README.md CHANGED
@@ -12,6 +12,8 @@ Create a repository with `pnpm create @sempods/apps <directory>`
12
12
  `package.json` runs the other commands through `sempods-apps <command>`:
13
13
 
14
14
  - `pnpm run new-app <id>` creates `apps/<id>` with the root's SDK version.
15
+ - `pnpm run icon <id>` draws an app's monogram icon again in its theme's
16
+ accent.
15
17
  - `pnpm run dev <id>` starts that app.
16
18
  - `pnpm run regenerate` rewrites every app's generated configuration from
17
19
  `apps.json`, for example after a tooling update.
@@ -32,9 +34,10 @@ Create a repository with `pnpm create @sempods/apps <directory>`
32
34
 
33
35
  Contents:
34
36
 
35
- - `instructions/`: the setup procedure, the app workflow and the publish
36
- guide; `skills/` holds the skill entries that route to them.
37
- - `skeleton/app/`: what a new app starts from. Files named `*.generated.ts` in
37
+ - `instructions/`: the setup procedure, the app workflow, the visual check and
38
+ the publish guide; `skills/` holds the skill entries that route to them.
39
+ - `skeleton/app/`: what a new app starts from, with its themes, UI kit and
40
+ list example. Files named `*.generated.ts` in
38
41
  an app are written from `apps.json`; do not edit them. `check` reports any
39
42
  difference, and `regenerate` rewrites them.
40
43
  - `shared/`: the starter of this release, its files stored by content hash in
@@ -7,6 +7,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
7
7
  const COMMANDS = {
8
8
  create: 'create a new apps repository from the starter',
9
9
  'new-app': 'create apps/<id> and add it to apps.json',
10
+ icon: "draw an app's monogram icon again in its theme's accent",
10
11
  dev: 'start the development server of one app',
11
12
  regenerate: "rewrite every app's generated configuration from apps.json",
12
13
  'configure-site': 'record where the apps are published',