@pikku/skills 0.12.40 → 0.12.42

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.
@@ -1,15 +1,16 @@
1
1
  ---
2
2
  name: pikku-guide
3
3
  description: >-
4
- Use when writing or regenerating a Pikku project's user guide — the end-user documentation
5
- built from the scenario suite with `pikku scenario guide`. Pages are hand-written markdown that
6
- cite features (pikkuFeature); the recordings and screenshots a passing `--screenshots` run
7
- filed for each cited feature are merged in as figures. Covers writing the prose, the
8
- `<!-- pikku:guide feature=… -->` markers, the capture step, `.guide.lock` staleness,
9
- `document: false`, `--allow-undocumented`, `--artifact-base`, and the traps that make a guide
10
- come out empty or refused. TRIGGER when: user asks for a user guide, help pages, docs with
11
- screenshots, or "document the app". DO NOT TRIGGER when: user asks about API reference docs,
12
- README files, or writing the scenarios themselves (use pikku-scenario).
4
+ Use when writing, rewriting or regenerating a Pikku project's user guide — the end-user
5
+ documentation built from the scenario suite with `pikku scenario guide`. Pages are hand-written
6
+ markdown, one section per task, each followed by a `<!-- pikku:guide feature=… scenario=… -->`
7
+ marker that pulls in the screenshot and recording that scenario filed. Covers planning pages
8
+ from the suite, writing task prose in the app's language, per-section markers, the capture step,
9
+ seed data that appears on camera, `.guide.lock` staleness, `document: false`, and the traps that
10
+ make a guide come out empty, refused, or as a wall of videos. TRIGGER when: user asks for a user
11
+ guide, help pages, docs with screenshots, "document the app", or complains that the /docs pages
12
+ are bad, thin, or all videos. DO NOT TRIGGER when: user asks about API reference docs, README
13
+ files, or writing the scenarios themselves (use pikku-scenario).
13
14
  installGroups: [core]
14
15
  ---
15
16
 
@@ -19,193 +20,225 @@ A guide is the app explained to the people who use it, with the scenario suite
19
20
  as its evidence. The suite proves what the product does and photographs it
20
21
  doing it; the pages say what that means for the reader and how to do it.
21
22
 
22
- Three inputs, one output:
23
-
24
23
  | Input | Comes from | Owned by |
25
24
  |---|---|---|
26
25
  | Structure | `pikkuFeature` meta — which features exist, and that every one is cited | the suite |
27
26
  | Evidence | the latest passing run under `.pikku/scenario-runs/` — recordings and screenshots | the run |
28
- | Prose | markdown pages under `docs/` (or `--docs <dir>`) — **every word the reader reads** | a human, or you |
27
+ | Prose | markdown pages under `docs/` (or `--docs <dir>`) — **every word the reader reads** | you |
29
28
 
30
29
  **The run contributes pictures, never words.** Step sentences, scenario
31
- descriptions and feature names are written to prove a test, and none of them
32
- reaches the page. A page that is a two-line intro and a marker publishes as a
33
- wall of videos with no instructions — the most common way a guide comes out
34
- bad. The writing in §2 is the job; the rest of this skill is plumbing.
30
+ descriptions and feature names are written to prove a test; none of them
31
+ reaches the page. The two ways a guide comes out bad are both about that
32
+ split: pages that lean on the figures to explain (a two-line intro and a
33
+ marker — a wall of videos with no instructions), and figures that are not
34
+ beside the words they illustrate (every recording piled at the foot of the
35
+ page). This skill is mostly about avoiding those two.
35
36
 
36
37
  `pikku scenario guide` writes one markdown file per source page into
37
38
  `.pikku/guide/` (or `--output`). It renders no HTML, resolves no asset URLs and
38
- calls no model. Images are ordinary relative `![caption](path)` references into
39
- the run directory; whoever hosts the markdown rewrites them, or you pass
40
- `--artifact-base /docs/_media/` for a host that serves them at a fixed address.
39
+ calls no model. Figures are ordinary relative `![caption](path)` references into
40
+ the run directory; the host rewrites them, or pass `--artifact-base /docs/_media/`.
41
41
 
42
42
  Read **pikku-scenario** first if the project has no features or browser steps
43
43
  yet — the guide cannot be better than the suite under it.
44
44
 
45
- ## 1. A page cites a feature
45
+ ## 1. What a good page looks like
46
46
 
47
- A page is a markdown file with frontmatter and a marker pair where the block
48
- belongs:
47
+ One page per job a reader comes to do; one section per task in that job. Each
48
+ section is the instructions, then the marker for the one scenario that shows
49
+ it:
49
50
 
50
51
  ```markdown
51
52
  ---
52
53
  title: Booking a course
53
- description: Finding a course, taking a place, and what happens after.
54
+ description: Finding a course, taking a place, and what to do when it is full.
54
55
  ---
55
56
 
56
57
  Courses run one evening a week for eight weeks. Book when you know which
57
58
  evening suits you; Intro to Improv is the place to start if you have never
58
59
  done improv before.
59
60
 
61
+ ## Book a place
62
+
60
63
  1. Open **Courses**. Each course shows its evening and how many places are left.
61
64
  2. Choose a course, then **Book a place**.
62
65
  3. Confirm your details and choose **Book**.
63
66
 
64
67
  Your place appears under **My bookings**, and a confirmation email follows.
65
68
 
66
- <!-- pikku:guide feature=bookingsFeature -->
69
+ <!-- pikku:guide feature=bookingsFeature scenario=memberBooksPlaceScenario -->
67
70
  <!-- /pikku:guide -->
68
71
 
69
- ## The course says it is full
72
+ ## The course is full
70
73
 
71
74
  A full course keeps a waiting list. Choose **Join the waiting list** and we
72
75
  email you the moment a place frees up — you are not charged until then.
73
76
 
74
- ## Can I switch to another evening?
77
+ <!-- pikku:guide feature=bookingsFeature scenario=memberJoinsWaitingListScenario -->
78
+ <!-- /pikku:guide -->
79
+
80
+ ## Where next
75
81
 
76
- Email us before the second week and we will move you if there is a place.
82
+ - [Paying for a course](payments.md)
77
83
  ```
78
84
 
79
- - `feature=` is the **exported identifier id** of the `pikkuFeature`, not its
80
- display name.
85
+ The generated block holds that scenario's figures and nothing else: its
86
+ showcase screenshots first, then its recording, then its other screenshots.
87
+
88
+ - `feature=` and `scenario=` are **exported identifiers**, not display names.
89
+ A `scenario=` the feature does not register fails the build and lists the
90
+ ones it does.
91
+ - A marker without `scenario=` drops **every** scenario of the feature in one
92
+ place. Use it only for a page that is a single task. On a page with sections
93
+ it is the wall of videos.
94
+ - A scenario no section needs is simply not cited; its feature still counts as
95
+ documented through the others.
81
96
  - A rebuild rewrites only the region between the markers. Everything around
82
- them is yours and survives every run.
83
- - One page may cite several features; one feature may be cited by several
84
- pages. The mapping is the union of every marker in the tree.
85
- - Frontmatter the compiler does not own (`slug`, `sidebar_position`, `draft`)
86
- passes through untouched.
87
-
88
- The generated block is the feature's **figures and nothing else**: for each
89
- scenario, its recordings first (one per actor), then its screenshots, deduped
90
- across data-driven rows. Two strings from the suite do reach the page, as
91
- captions:
92
-
93
- | Figure | Caption |
94
- |---|---|
95
- | Recording | the scenario's `title`, then ` — ` and the actor's name |
96
- | Screenshot | the `name` it was taken under |
97
-
98
- So those two are user-facing copy: "Take a place on a course", "the course list,
99
- with places left on each ticket" — not "mira books c-intro-1024" or
100
- "courses /app/courses at 1440px". The scenario `description` and the steps are
101
- never rendered.
102
-
103
- A block is indivisible: all of a feature's figures land together, where the
104
- marker sits. Place the marker after the steps it illustrates, not before them.
105
- If one page needs figures beside two separate steps, those steps are two
106
- features.
97
+ them is yours. Frontmatter the compiler does not own (`slug`,
98
+ `sidebar_position`, `draft`) passes through.
107
99
 
108
100
  Organise pages by who reads them, not by feature: `docs/using/`,
109
- `docs/teaching/`, `docs/organising/`. Use the project's own vocabulary, the one
110
- on its screens — not internal table names.
111
-
112
- ## 2. Writing the page
101
+ `docs/teaching/`, `docs/organising/`. One feature may be cited from several
102
+ pages, one page may cite several features.
103
+
104
+ ## 2. Plan from the suite before writing
105
+
106
+ Do this first, in a scratch table. It is what makes every later step
107
+ mechanical, and skipping it is how sections end up with no figure or with a
108
+ figure of something else.
109
+
110
+ 1. **Inventory.** List every `pikkuFeature` and, under each, its scenarios with
111
+ their actor and the screen each one ends on. Read the scenario files, not
112
+ just the names.
113
+ 2. **Outline.** Group the scenarios into reader jobs (pages) and tasks
114
+ (sections). A section is usually one scenario; two scenarios that show the
115
+ same task from two sides (it works / it is refused) can share a section, one
116
+ marker each.
117
+ 3. **Mark what cannot be shown.** A task with no browser scenario gets no
118
+ marker — write it anyway if readers need it, and say in your hand-over which
119
+ sections have no evidence. Never cite a scenario that shows something else
120
+ because it is nearby.
121
+ 4. **Decide the still.** For each cited scenario, name the moment its
122
+ screenshot should capture — the state the section's "what you see
123
+ afterwards" describes. §4 is how it gets taken.
124
+
125
+ ## 3. Writing the section
113
126
 
114
127
  Write it so a reader can do the task **with every figure removed**. The figures
115
128
  confirm; they do not instruct. A reader skims for the step they are stuck on,
116
129
  and cannot search a video.
117
130
 
118
- Before writing, read the screen's component and its copy, then the feature's
119
- scenarios. The screen is what renders; the scenario is what is proven, and its
120
- steps are the user's journey already in order. Write only what you have seen
121
- in one of them — a fluent page describing a flow that does not exist is worse
122
- than no page.
123
-
124
- Each task page carries, in the reader's language (the app's, not English by
125
- default):
126
-
127
- - **Why and when** — one short paragraph: what this is for, and when the reader
128
- would reach for it. Never "This page documents…".
129
- - **The steps** — a numbered list, each one an action in the words on the
130
- screen: "Open **Patienten** and choose **Patient anlegen**." Name buttons and
131
- fields exactly as they read.
132
- - **What you see afterwards** — the state that means it worked.
131
+ Before writing a section, open the screen's component and its message catalog,
132
+ then the scenario. The screen is what renders; the scenario is what is proven,
133
+ and its steps are the reader's journey already in order. Write only what you
134
+ have seen in one of them — a fluent section describing a flow that does not
135
+ exist is worse than none.
136
+
137
+ Write in the app's language — the one on its screens and in its default
138
+ locale, not English by default. Each page carries:
139
+
140
+ - **Why and when** — one short paragraph at the top: what this is for, and when
141
+ the reader would reach for it. Never "This page documents…".
142
+ - **Per section: the steps** — a numbered list, each an action in the words on
143
+ the screen: "Open **Patienten** and choose **Patient anlegen**." Name buttons,
144
+ tabs and fields exactly as they read, in bold.
145
+ - **Per section: what you see afterwards** — the state that means it worked.
146
+ This is the sentence the still illustrates.
133
147
  - **What goes wrong** — the refusal, the empty state, the thing that looks
134
- broken but is not. Every empty state a scenario lands in and every
135
- `expectError` in the feature is a candidate; this is usually the paragraph
136
- readers came for.
148
+ broken but is not. Every `expectError` and every empty state a scenario lands
149
+ in is a candidate; this is usually what readers came for.
137
150
  - **Where next** — links to the pages a reader goes to from here.
138
151
 
139
- Then the marker, after the steps it shows.
152
+ Reassurance is content: "Codes held in reserve cost nothing until a patient
153
+ uses one" is what stops a reader hesitating over the button. Explain the
154
+ confusing thing, not the impressive one.
140
155
 
141
156
  A page that exists only to cite a feature — "every page loads", "acceptance",
142
157
  a smoke suite — is not a page. Cite that feature from the page whose screens it
143
158
  covers, or mark it `document: false`.
144
159
 
145
- Reassurance is content: "Codes held in reserve cost nothing until a patient
146
- uses one" is what stops a reader hesitating over the button. Explain the
147
- confusing thing, not the impressive one.
160
+ ### Captions are copy
148
161
 
149
- ## 3. Every feature is accounted for
162
+ Two strings from the suite reach the page as captions:
150
163
 
151
- Every registered feature must be cited by some page. An uncited feature fails
152
- the command by name:
164
+ | Figure | Caption |
165
+ |---|---|
166
+ | Screenshot | the `name` it was taken under |
167
+ | Recording | the scenario's `title` (plus ` — ` and the actor, when there are several) |
153
168
 
154
- ```
155
- Feature 'barFeature' is cited by no page. Place `<!-- pikku:guide feature=barFeature -->` …
156
- ```
169
+ Write both as a reader-facing caption in the app's language: "Die Buchung mit
170
+ Status, Eckdaten und Reitern", "the course list, with places left on each
171
+ course". Not "booking-detail /admin/bookings/b_1 at 1440px", not "Admin renames
172
+ course — admin". Renaming a scenario `title` changes no behaviour.
157
173
 
158
- Two ways out, both deliberate:
174
+ ## 4. Every cited scenario ends on a still
159
175
 
160
- - Write the page. This is the normal answer.
161
- - The feature is plumbing nobody reads about (a session-health check, an
162
- internal sync): `pikkuFeature({ …, document: false })`. Citing a
163
- `document: false` feature is itself an error.
176
+ A section whose scenario filed only a recording gets a video and no picture —
177
+ the reader has to press play and scrub to find the one frame that matters.
178
+ Every scenario a section cites should take one showcase screenshot of the state
179
+ the section describes. Add the capture step once:
180
+
181
+ ```ts snippet:guideCaptureStep
182
+ ```
164
183
 
165
- `--allow-undocumented` downgrades the uncited-feature error to a warning, for a
166
- guide that is mid-way through being written. Do not hand one over with it on.
184
+ - Without `path` it photographs the screen the flow is on. Call it **after the
185
+ scenario's last assertion**, so the shot is the proven end state (the room
186
+ assigned, the invoice listed) rather than a page reloaded from a URL.
187
+ - With `path` it opens a screen first — for a section about a screen rather
188
+ than an action.
189
+ - The `name` is the caption (see above). `{ showcase: true }` marks it fit to
190
+ publish; `{ fullPage: true }` photographs the whole scrollable page.
191
+ - Contexts open at a pinned 1440×900 viewport with animations off, so two runs
192
+ photograph the same thing. Call `page.setViewportSize` inside a step for a
193
+ phone-width shot.
167
194
 
168
- A page citing an id that is not a registered feature is always an error — it
169
- describes something that no longer exists.
195
+ ### The camera sees your seed data
170
196
 
171
- ## 4. Screenshots come from a capture step
197
+ Every figure shows whatever the scenario's personas and seed rows contain, so
198
+ they are part of the documentation:
172
199
 
173
- The run only files screenshots a step asks for. Add one browser step that opens
174
- a page and takes a shot, and call it from a scenario each feature owns:
200
+ - A persona's display name is in the header of every shot. "Scenario Admin" or
201
+ "test-user-3" is on every page of the guide; give personas plausible names
202
+ and roles.
203
+ - Seed rows are the example data a reader sees: in the app's language, the
204
+ shape real data takes — no lorem ipsum, no English description inside a
205
+ German UI, no `foo`, no ids as names.
206
+ - Changing seed data changes what scenarios assert; run the suite after.
175
207
 
176
- ```ts snippet:guideCaptureStep
177
- ```
208
+ ### Traps that make a figure missing or wrong
178
209
 
179
- - The screenshot `name` is the figure caption. Write it as a caption: "the
180
- course list, with places left on each ticket".
181
- - `{ showcase: true }` marks a shot fit to publish outside the run. `{ fullPage:
182
- true }` photographs the whole scrollable page.
183
- - Contexts open at a pinned 1440×900 viewport with animations off, so two runs
184
- photograph the same thing. Override with `E2E_VIEWPORT_WIDTH` /
185
- `E2E_VIEWPORT_HEIGHT` or the playwright config, or call
186
- `page.setViewportSize` inside the step for a phone-width shot.
187
- - Prefer a shot at the end of a real flow step (after the booking succeeds) over
188
- a standalone "open and photograph" scenario — the figure then shows the state
189
- the section describes.
190
-
191
- ### Traps that make a block come out empty
192
-
193
- - **A feature whose scenarios are RPC-only files no screenshot.** The command
194
- warns `whose run filed no screenshot — the block renders empty`. Fold that
195
- scenario into a feature that has browser coverage, or add a browser capture
196
- to it; do not invent a page just to photograph.
210
+ - **RPC-only scenarios file no screenshot.** The command warns `whose run filed
211
+ no screenshot — the block renders empty`. Add a browser capture, or do not
212
+ cite that scenario.
197
213
  - **A capture loop must iterate a named const.** `for (const s of [ … ])` with
198
- an inline array literal cannot be extracted (PKU679) and the scenario becomes
199
- silently empty. `const screens = [ … ] as const` then `for (const s of screens)`.
200
- - **A closing assertion runs wherever the last capture left the browser.**
201
- Captures appended to the end of a scenario move the page out from under a
202
- `then` that follows them. Capture after the last assertion, or re-navigate.
214
+ an inline array literal cannot be extracted (PKU679) and the scenario is
215
+ silently empty. `const screens = [ … ] as const`, then `for (const s of screens)`.
216
+ - **A capture before an assertion moves the page from under it.** Capture last,
217
+ or re-navigate.
218
+ - **A redirect photographs the wrong screen.** A first-time actor bounced to
219
+ onboarding, a consent dialog, a login — the shot is named "the map" and shows
220
+ something else. Finish the redirecting flow in the scenario first, and look
221
+ at the image.
203
222
  - **Locale.** Playwright reports `navigator.language` as `en-US`. An app that
204
- picks its locale from the browser renders English, and every copy assertion
205
- in another language fails. Set the app's own stored locale with
206
- `page.addInitScript` in **every** step that navigates, not only the first.
223
+ picks its locale from the browser renders English. Set the app's own stored
224
+ locale with `page.addInitScript` in **every** step that navigates.
207
225
 
208
- ## 5. Build it
226
+ ## 5. Every feature is accounted for
227
+
228
+ Every registered feature must be cited by some page, or the command fails by
229
+ name:
230
+
231
+ ```
232
+ Feature 'barFeature' is cited by no page. Place `<!-- pikku:guide feature=barFeature -->` …
233
+ ```
234
+
235
+ Write the page, or — for plumbing nobody reads about (a session-health check,
236
+ an internal sync) — declare `pikkuFeature({ …, document: false })`. Citing a
237
+ `document: false` feature is an error, and so is citing an id that is not a
238
+ registered feature. `--allow-undocumented` downgrades the uncited error to a
239
+ warning for a guide mid-way through; do not hand one over with it on.
240
+
241
+ ## 6. Build it, then look at it
209
242
 
210
243
  ```sh
211
244
  # 1. a full, passing browser run that writes the shots to disk
@@ -215,50 +248,47 @@ bunx --bun pikku scenario run local --run browser --screenshots
215
248
  bunx --bun pikku scenario guide --docs docs
216
249
  ```
217
250
 
218
- - `--screenshots` is what writes files. Without it `browser.screenshot()`
219
- still returns bytes and nothing lands on disk, so every block is empty.
220
- - The run must have **passed**. A failed or killed run is refused — a page is a
221
- claim that the product does what it says.
222
- - The run must be **the whole suite**. A run narrowed with `--flows`,
223
- `--features`, `--tags` or `--exclude-tags` is refused, because pages built
224
- from it would describe missing flows as though they did not exist. An
225
- exclusion that matches nothing still counts — keep every narrowing flag out
226
- of a CI invocation whose run feeds the guide. `--run-id <id>` picks an older
227
- full run.
228
-
229
- ## 6. `.guide.lock` — keeping prose honest
230
-
231
- `docs/.guide.lock` records, per feature, a hash of its scenarios' **step
232
- sentences and artifact ids** — deliberately not the image bytes. Restyling the
233
- UI changes every screenshot and no sentence, so it does not stale a page.
234
- Inserting, renaming or reordering a step changes what the prose around the
235
- block was describing, and the page is reported:
251
+ - `--screenshots` is what writes files. Without it every block is empty.
252
+ - The run must have **passed**, and must be **the whole suite**. A run narrowed
253
+ with `--flows`, `--features`, `--tags` or `--exclude-tags` is refused — keep
254
+ every narrowing flag out of a CI invocation whose run feeds the guide.
255
+ `--run-id <id>` picks an older full run.
256
+
257
+ Then open the generated pages and **look at the images** — read them, do not
258
+ just count them. Most bad figures are only visible this way: the wrong screen,
259
+ a dialog half-open, an empty list because the seed had no rows, English on a
260
+ German page, "Scenario Admin" in the corner.
261
+
262
+ ## 7. `.guide.lock` — keeping prose honest
263
+
264
+ `docs/.guide.lock` records, per feature, a hash of its scenarios' step
265
+ sentences and artifact ids — not image bytes, so restyling the UI stales
266
+ nothing. Inserting, renaming or reordering a step reports the page:
236
267
 
237
268
  ```
238
269
  docs/using/booking.md was written against 'bookingsFeature' at 3f1a…, which is now 9c0e… — the flow moved, so re-read the prose around that block.
239
270
  ```
240
271
 
241
- Re-read that page's hand-written text, fix what the flow change made untrue,
242
- and rebuild. The lock is rewritten on every successful build.
243
-
244
- - **Commit the lock.** It is generated, never hand-edited, never hand-merged. A
245
- tree whose lock is untracked reports every page as current forever.
246
- - The first build after adding pages prints stale warnings for every feature
247
- (there was no lock); they clear on the second build.
248
-
249
- ## 7. Hand-over checklist
250
-
251
- - [ ] Every feature is cited, or declares `document: false` with a reason.
252
- - [ ] No `--allow-undocumented` in the command you report as done.
253
- - [ ] Built from a full, passing `--run browser --screenshots` run.
254
- - [ ] No "block renders empty" warnings.
255
- - [ ] No stale warnings left after the second build.
256
- - [ ] `docs/` pages and `docs/.guide.lock` committed; `.pikku/guide/` is output.
257
- - [ ] Every page reads as instructions with its figures removed: why and when,
258
- numbered steps naming the controls as they read on screen, what goes
259
- wrong.
260
- - [ ] No page exists only to cite a smoke or acceptance feature.
261
- - [ ] Scenario titles and screenshot names read as captions — no routes,
262
- viewport sizes or test ids.
263
- - [ ] Open two generated pages and look at them: the figures are the screens the
264
- text describes, in the app's language.
272
+ Re-read that page's text, fix what the flow change made untrue, rebuild. The
273
+ first build after adding pages warns for every feature (there was no lock);
274
+ the second is clean. Commit the lock; never hand-edit or hand-merge it.
275
+
276
+ ## 8. Hand-over checklist
277
+
278
+ - [ ] Every section with instructions is followed by its own `scenario=`
279
+ marker, or is listed in the hand-over as having no evidence.
280
+ - [ ] No page with sections uses a feature-wide marker.
281
+ - [ ] Every cited scenario takes a showcase screenshot of the state its
282
+ section describes.
283
+ - [ ] Every page reads as instructions with its figures removed, in the app's
284
+ language: why and when, numbered steps naming controls as they read,
285
+ what you see, what goes wrong.
286
+ - [ ] Captions (screenshot names, scenario titles) are reader copy — no routes,
287
+ sizes, test ids or actor names.
288
+ - [ ] Personas and seed data on camera look like real use, in the app's
289
+ language.
290
+ - [ ] Every feature is cited or `document: false`; no `--allow-undocumented`.
291
+ - [ ] Built from a full, passing `--run browser --screenshots` run; no "block
292
+ renders empty" or stale warnings after the second build.
293
+ - [ ] You opened the generated pages and looked at every image.
294
+ - [ ] `docs/` and `docs/.guide.lock` committed; `.pikku/guide/` is output.
@@ -293,7 +293,10 @@ const kysely = createNodeSqliteKysely<DB>({
293
293
  import { createSQLiteKysely } from '@pikku/kysely-sqlite'
294
294
 
295
295
  // Pikku's own tables — returns Kysely<KyselyPikkuDB>, not your DB
296
- const pikkuDb = createSQLiteKysely(database: SqliteDatabase | (() => Promise<SqliteDatabase>))
296
+ const pikkuDb = createSQLiteKysely(
297
+ database: SqliteDatabase | (() => Promise<SqliteDatabase>),
298
+ { plugins: [] } // layered ahead of the always-last SerializePlugin
299
+ )
297
300
  ```
298
301
 
299
302
  These two are not interchangeable. `createSQLiteKysely` is typed to
@@ -3,8 +3,8 @@ name: pikku-meta
3
3
  description: >-
4
4
  Use to inspect or evolve a project you did not just write — `pikku meta` and `pikku info` for
5
5
  what the project declares (functions, schemas, wires, workflows, middleware, permissions) and
6
- `pikku meta apply` to change it, `pikku versions` / `pikku semver` for contract hashes,
7
- breaking-change detection and the semver a release should get, and `pikku audit` / `pikku
6
+ `pikku meta apply` to change it, `pikku versions` / `pikku release` for contract hashes,
7
+ breaking-change detection, the semver a release should get and shipping it, and `pikku audit` / `pikku
8
8
  update` for dependency advisories and moving Pikku forward. TRIGGER when: user asks what
9
9
  functions or routes exist, wants a function's input/output shape, wants to retag a function or
10
10
  set config on a declaration, asks about API versioning, breaking changes, what semver a release
@@ -13,7 +13,7 @@ description: >-
13
13
  Pikku concepts (use pikku-concepts).
14
14
  installGroups: [core]
15
15
  allowed-tools: Bash(yarn pikku meta *), Bash(yarn pikku info *)
16
- argument-hint: '[context|functions|schemas|workflows|middleware|permissions|wires|apply|versions|semver|audit|update]'
16
+ argument-hint: '[context|functions|schemas|workflows|middleware|permissions|wires|apply|versions|release|audit|update]'
17
17
  ---
18
18
 
19
19
  # Pikku Project Metadata
@@ -26,7 +26,7 @@ and change it through the write path rather than by hand.
26
26
  | You are… | Read |
27
27
  | --- | --- |
28
28
  | Asking what exists, or setting config on a declaration | `references/meta.md` |
29
- | Versioning a contract, or deciding a release's semver | `references/versioning.md` |
29
+ | Versioning a contract, or versioning and shipping a release | `references/versioning.md` |
30
30
  | Chasing a dependency advisory, or upgrading Pikku | `references/audit.md` |
31
31
 
32
32
  ## Start with `pikku meta context`
@@ -41,7 +41,7 @@ they are the same ground in two shapes.
41
41
  An input is contravariant (the caller writes it) and an output is covariant (the
42
42
  caller reads it), so the same edit is not the same event on both. Adding a
43
43
  required field breaks an input and is compatible on an output; making a field
44
- optional is the reverse. `pikku semver` reads the generated JSON Schemas with
44
+ optional is the reverse. `pikku release diff` reads the generated JSON Schemas with
45
45
  that asymmetry built in, so let it decide rather than eyeballing a diff.
46
46
 
47
47
  ## What NOT to do