@pikku/skills 0.12.52 → 0.12.55

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 (112) hide show
  1. package/README.md +1 -1
  2. package/dist/skills.gen.js +2 -2
  3. package/dist/snippets.js +1 -1
  4. package/package.json +1 -1
  5. package/skills/pikku-a11y/SKILL.md +22 -15
  6. package/skills/pikku-addon/SKILL.md +5 -5
  7. package/skills/pikku-addon/references/addon-package-manifest.md +7 -0
  8. package/skills/pikku-addon/references/openapi.md +11 -0
  9. package/skills/pikku-agent/SKILL.md +6 -6
  10. package/skills/pikku-agent/references/agents.md +8 -1
  11. package/skills/pikku-agent/references/runner-vercel.md +2 -2
  12. package/skills/pikku-agent/references/voice.md +7 -1
  13. package/skills/pikku-architect/SKILL.md +2 -2
  14. package/skills/pikku-architect/references/plan-defects.md +9 -7
  15. package/skills/pikku-auth/SKILL.md +15 -36
  16. package/skills/pikku-auth/references/better-auth.md +106 -133
  17. package/skills/pikku-auth/references/jose.md +6 -0
  18. package/skills/pikku-auth/references/machine-auth.md +6 -0
  19. package/skills/pikku-auth/references/sessions.md +6 -0
  20. package/skills/pikku-build/SKILL.md +37 -34
  21. package/skills/pikku-build/references/app.md +113 -99
  22. package/skills/pikku-build/references/design.md +43 -31
  23. package/skills/pikku-build/references/feature.md +17 -3
  24. package/skills/pikku-build/references/mocks.md +29 -0
  25. package/skills/pikku-build/references/multi-app.md +25 -18
  26. package/skills/pikku-build/references/native-app.md +9 -0
  27. package/skills/pikku-build/references/openapi.md +41 -34
  28. package/skills/pikku-build/references/platform.md +23 -14
  29. package/skills/pikku-build/references/post-clone.md +1 -1
  30. package/skills/pikku-build/references/quick.md +76 -39
  31. package/skills/pikku-build/references/scenarios.md +28 -16
  32. package/skills/pikku-build/references/ship.md +19 -16
  33. package/skills/pikku-build/references/theming.md +76 -127
  34. package/skills/pikku-changes/SKILL.md +7 -10
  35. package/skills/pikku-concepts/SKILL.md +34 -44
  36. package/skills/pikku-concepts/references/concept-mapping.md +18 -0
  37. package/skills/pikku-concepts/references/language.md +6 -6
  38. package/skills/pikku-convert-screen/SKILL.md +45 -0
  39. package/skills/pikku-deploy/references/cloudflare.md +8 -0
  40. package/skills/pikku-deploy/references/lambda.md +8 -0
  41. package/skills/pikku-deploy/references/nextjs.md +1 -1
  42. package/skills/pikku-deploy/references/uws.md +1 -1
  43. package/skills/pikku-deploy/references/ws.md +3 -3
  44. package/skills/pikku-emails/SKILL.md +3 -9
  45. package/skills/pikku-guide/SKILL.md +28 -27
  46. package/skills/pikku-i18n/SKILL.md +7 -7
  47. package/skills/pikku-i18n/references/enum-labels.md +9 -0
  48. package/skills/pikku-i18n/references/messages.md +21 -9
  49. package/skills/pikku-i18n/references/rtl.md +18 -38
  50. package/skills/pikku-knowledge/SKILL.md +12 -13
  51. package/skills/pikku-kysely/SKILL.md +3 -21
  52. package/skills/pikku-list-query/SKILL.md +2 -2
  53. package/skills/pikku-meta/references/audit.md +10 -1
  54. package/skills/pikku-meta/references/meta.md +6 -0
  55. package/skills/pikku-meta/references/versioning.md +10 -0
  56. package/skills/pikku-middleware/SKILL.md +7 -16
  57. package/skills/pikku-n8n-import/SKILL.md +9 -1
  58. package/skills/pikku-n8n-import/references/addon-mapping.md +6 -0
  59. package/skills/pikku-n8n-import/references/code-translation.md +7 -0
  60. package/skills/pikku-permissions/SKILL.md +41 -10
  61. package/skills/pikku-permissions/references/scopes.md +59 -0
  62. package/skills/pikku-react/SKILL.md +20 -22
  63. package/skills/pikku-react/references/client.md +2 -70
  64. package/skills/pikku-react/references/react-query.md +11 -0
  65. package/skills/pikku-react/references/workflows.md +11 -0
  66. package/skills/pikku-realtime/SKILL.md +9 -3
  67. package/skills/pikku-report/SKILL.md +17 -16
  68. package/skills/pikku-scenario/SKILL.md +72 -81
  69. package/skills/pikku-scenario/references/browser.md +5 -5
  70. package/skills/pikku-scenario/references/coverage.md +4 -4
  71. package/skills/pikku-scenario/references/steps.md +31 -30
  72. package/skills/pikku-scenario/references/{persona-run.md → virtual-user-run.md} +47 -42
  73. package/skills/pikku-scenario/references/virtual-users.md +114 -0
  74. package/skills/pikku-seo/SKILL.md +12 -16
  75. package/skills/pikku-service-backends/SKILL.md +0 -10
  76. package/skills/pikku-service-backends/references/aws.md +6 -0
  77. package/skills/pikku-service-backends/references/mongodb.md +7 -0
  78. package/skills/pikku-service-backends/references/redis.md +6 -0
  79. package/skills/pikku-services/references/audit-wire-service.md +2 -2
  80. package/skills/pikku-services/references/audit.md +10 -1
  81. package/skills/pikku-services/references/config.md +6 -0
  82. package/skills/pikku-services/references/services.md +9 -2
  83. package/skills/pikku-software-archaeology/SKILL.md +21 -27
  84. package/skills/pikku-software-archaeology/references/blueprint.schema.json +16 -16
  85. package/skills/pikku-software-archaeology/references/pikku-mapping.md +3 -3
  86. package/skills/pikku-software-archaeology/references/second-opinion.md +13 -1
  87. package/skills/pikku-tailwind/SKILL.md +111 -0
  88. package/skills/pikku-theme/SKILL.md +187 -0
  89. package/skills/pikku-theme/references/from-a-reference.md +44 -0
  90. package/skills/pikku-theme/references/presets.md +40 -0
  91. package/skills/pikku-ui/SKILL.md +41 -0
  92. package/skills/pikku-wiring/SKILL.md +13 -12
  93. package/skills/pikku-wiring/references/channel.md +7 -1
  94. package/skills/pikku-wiring/references/cli.md +7 -1
  95. package/skills/pikku-wiring/references/gateway-slack.md +6 -0
  96. package/skills/pikku-wiring/references/http.md +10 -3
  97. package/skills/pikku-wiring/references/mcp.md +8 -0
  98. package/skills/pikku-wiring/references/queue.md +6 -0
  99. package/skills/pikku-wiring/references/realtime.md +34 -4
  100. package/skills/pikku-wiring/references/rpc.md +6 -0
  101. package/skills/pikku-wiring/references/scheduler.md +6 -0
  102. package/skills/pikku-wiring/references/trigger.md +8 -0
  103. package/skills/pikku-workflow/SKILL.md +9 -7
  104. package/skills/pikku-admin-to-fabric/SKILL.md +0 -212
  105. package/skills/pikku-auth/references/permissions.md +0 -261
  106. package/skills/pikku-blueprint-to-fabric/SKILL.md +0 -377
  107. package/skills/pikku-blueprint-to-fabric/scripts/inventory.mjs +0 -367
  108. package/skills/pikku-fabric/SKILL.md +0 -619
  109. package/skills/pikku-fabric/references/debugging.md +0 -110
  110. package/skills/pikku-mantine/SKILL.md +0 -80
  111. package/skills/pikku-scenario/references/personas.md +0 -117
  112. package/skills/pikku-wiring/references/realtime-other-routes.md +0 -23
@@ -69,4 +69,4 @@ app.ws('/*', pikkuWebsocketHandler({ logger, logRoutes: true }))
69
69
 
70
70
  Both take `{ logger, logRoutes?, loadSchemas? } & RunHTTPWiringOptions`.
71
71
 
72
- For a WebSocket-only server on the `ws` library instead, see `ws.md`.
72
+ For a WebSocket-only server on the `ws` library instead, use the `ws` runtime.
@@ -2,9 +2,9 @@
2
2
 
3
3
  `@pikku/ws` connects Pikku's channel system to a Node.js WebSocket server built
4
4
  on the [ws](https://github.com/websockets/ws) library. Use it for a
5
- WebSocket-only server; for HTTP and WebSocket on one port see `uws.md`, and when
6
- the WebSocket server shares a port with an existing HTTP app see `express.md` or
7
- `fastify.md`.
5
+ WebSocket-only server; for HTTP and WebSocket on one port use the uWebSockets.js runtime, and when
6
+ the WebSocket server shares a port with an existing HTTP app use the Express or
7
+ Fastify runtime.
8
8
 
9
9
  ```bash
10
10
  yarn add @pikku/ws ws
@@ -1,15 +1,9 @@
1
1
  ---
2
2
  name: pikku-emails
3
3
  description: >-
4
- Use when working with Pikku's file-based email templates: authoring HTML/subject/text templates,
5
- locales, partials and theme, running `pikku emails generate`, and rendering/sending them through
6
- an EmailService. TRIGGER when: code uses renderEmailTemplate, EmailTemplateName, EmailService,
7
- SendTemplateEmailInput, LocalEmailService, or imports from .pikku/email/pikku-emails.gen.
8
- TRIGGER when: the project has an emails/ directory (templates/, locales/, partials/, theme.json)
9
- or emailTemplatesDir in pikku.config.json. TRIGGER when: user asks to add/edit a transactional
10
- email (verification, password reset, invitation, receipt), wire email sending, or translate an
11
- email. DO NOT TRIGGER when: user asks about i18n for the app UI (use pikku-i18n) or auth flows
12
- in general (use pikku-auth).
4
+ Use when working with Pikku's file-based email templates: authoring html, subject and text templates, locales, partials and theme, running `pikku emails generate`, and rendering and sending them through an EmailService.
5
+ TRIGGER when: code uses renderEmailTemplate, EmailTemplateName, EmailService, SendTemplateEmailInput or LocalEmailService, or imports from .pikku/email/pikku-emails.gen; the project has an emails/ directory (templates/, locales/, partials/, theme.json) or emailTemplatesDir in pikku.config.json; or the user asks to add, edit or translate a transactional email (verification, password reset, invitation, receipt) or wire email sending.
6
+ DO NOT TRIGGER when: the task is i18n for the app UI (use pikku-i18n) or sign-in flows in general (use pikku-auth).
13
7
  installGroups: [core]
14
8
  ---
15
9
 
@@ -1,16 +1,16 @@
1
1
  ---
2
2
  name: pikku-guide
3
3
  description: >-
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).
4
+ Use when writing, rewriting or regenerating a Pikku project's end-user guide, built from the
5
+ scenario suite with `pikku scenario guide`. Pages are hand-written markdown, one section per
6
+ task, each followed by a `pikku:guide` HTML-comment marker (feature and scenario attributes) that
7
+ pulls in the screenshot and recording that scenario filed. Covers planning pages from the suite,
8
+ writing task prose in the app's language, per-section markers, the capture step, seed data that
9
+ appears on camera, `.guide.lock` staleness, `document: false`, and the traps that make a guide
10
+ come out empty, refused, or as a wall of videos. TRIGGER when: user asks for a user guide, help
11
+ pages, docs with screenshots, "document the app", or complains that the /docs pages are bad,
12
+ thin, or all videos. DO NOT TRIGGER when: user asks about API reference docs, README files, the
13
+ Pikku framework's own documentation site, or writing the scenarios themselves (use pikku-scenario).
14
14
  installGroups: [core]
15
15
  ---
16
16
 
@@ -20,11 +20,11 @@ A guide is the app explained to the people who use it, with the scenario suite
20
20
  as its evidence. The suite proves what the product does and photographs it
21
21
  doing it; the pages say what that means for the reader and how to do it.
22
22
 
23
- | Input | Comes from | Owned by |
24
- |---|---|---|
25
- | Structure | `pikkuFeature` meta — which features exist, and that every one is cited | the suite |
26
- | Evidence | the latest passing run under `.pikku/scenario-runs/` — recordings and screenshots | the run |
27
- | Prose | markdown pages under `docs/` (or `--docs <dir>`) — **every word the reader reads** | you |
23
+ | Input | Comes from | Owned by |
24
+ | --------- | ---------------------------------------------------------------------------------- | --------- |
25
+ | Structure | `pikkuFeature` meta — which features exist, and that every one is cited | the suite |
26
+ | Evidence | the latest passing run under `.pikku/scenario-runs/` — recordings and screenshots | the run |
27
+ | Prose | markdown pages under `docs/` (or `--docs <dir>`) — **every word the reader reads** | you |
28
28
 
29
29
  **The run contributes pictures, never words.** Step sentences, scenario
30
30
  descriptions and feature names are written to prove a test; none of them
@@ -108,7 +108,7 @@ mechanical, and skipping it is how sections end up with no figure or with a
108
108
  figure of something else.
109
109
 
110
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
111
+ their virtual user and the screen each one ends on. Read the scenario files, not
112
112
  just the names.
113
113
  2. **Outline.** Group the scenarios into reader jobs (pages) and tasks
114
114
  (sections). A section is usually one scenario; two scenarios that show the
@@ -161,10 +161,10 @@ covers, or mark it `document: false`.
161
161
 
162
162
  Two strings from the suite reach the page as captions:
163
163
 
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) |
164
+ | Figure | Caption |
165
+ | ---------- | ------------------------------------------------------------------------------ |
166
+ | Screenshot | the `name` it was taken under |
167
+ | Recording | the scenario's `title` (plus `—` and the virtual user, when there are several) |
168
168
 
169
169
  Write both as a reader-facing caption in the app's language: "Die Buchung mit
170
170
  Status, Eckdaten und Reitern", "the course list, with places left on each
@@ -179,6 +179,7 @@ Every scenario a section cites should take one showcase screenshot of the state
179
179
  the section describes. Add the capture step once:
180
180
 
181
181
  ```ts snippet:guideCaptureStep
182
+
182
183
  ```
183
184
 
184
185
  - Without `path` it photographs the screen the flow is on. Call it **after the
@@ -194,11 +195,11 @@ the section describes. Add the capture step once:
194
195
 
195
196
  ### The camera sees your seed data
196
197
 
197
- Every figure shows whatever the scenario's personas and seed rows contain, so
198
+ Every figure shows whatever the scenario's virtual users and seed rows contain, so
198
199
  they are part of the documentation:
199
200
 
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
201
+ - A virtual user's display name is in the header of every shot. "Scenario Admin" or
202
+ "test-user-3" is on every page of the guide; give virtual users plausible names
202
203
  and roles.
203
204
  - Seed rows are the example data a reader sees: in the app's language, the
204
205
  shape real data takes — no lorem ipsum, no English description inside a
@@ -208,14 +209,14 @@ they are part of the documentation:
208
209
  ### Traps that make a figure missing or wrong
209
210
 
210
211
  - **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
+ no screenshot — the block renders empty`. Add a browser capture, or do not
212
213
  cite that scenario.
213
214
  - **A capture loop must iterate a named const.** `for (const s of [ … ])` with
214
215
  an inline array literal cannot be extracted (PKU679) and the scenario is
215
216
  silently empty. `const screens = [ … ] as const`, then `for (const s of screens)`.
216
217
  - **A capture before an assertion moves the page from under it.** Capture last,
217
218
  or re-navigate.
218
- - **A redirect photographs the wrong screen.** A first-time actor bounced to
219
+ - **A redirect photographs the wrong screen.** A first-time virtual user bounced to
219
220
  onboarding, a consent dialog, a login — the shot is named "the map" and shows
220
221
  something else. Finish the redirecting flow in the scenario first, and look
221
222
  at the image.
@@ -284,8 +285,8 @@ the second is clean. Commit the lock; never hand-edit or hand-merge it.
284
285
  language: why and when, numbered steps naming controls as they read,
285
286
  what you see, what goes wrong.
286
287
  - [ ] 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
288
+ sizes, test ids or virtual user names.
289
+ - [ ] Virtual users and seed data on camera look like real use, in the app's
289
290
  language.
290
291
  - [ ] Every feature is cited or `document: false`; no `--allow-undocumented`.
291
292
  - [ ] Built from a full, passing `--run browser --screenshots` run; no "block
@@ -2,9 +2,9 @@
2
2
  name: pikku-i18n
3
3
  description: >-
4
4
  Use when writing user-facing text in a Pikku frontend, or making one speak another language.
5
- Covers Paraglide JS message functions compiled from messages/<locale>.json, adding a second
6
- language, generated enum-label maps with @pikku/paraglide, and right-to-left support for Arabic,
7
- Hebrew, Farsi and Urdu. TRIGGER when: scaffolding or editing a frontend and writing display
5
+ Covers Paraglide JS message functions compiled from per-locale messages JSON files, adding a second
6
+ language, generated enum-label maps with @pikku/paraglide, and right-to-left support (document direction, flow-relative
7
+ styles) for Arabic, Hebrew, Farsi and Urdu. TRIGGER when: scaffolding or editing a frontend and writing display
8
8
  text, asked to make copy translatable, adding a language, labelling an enum/status/role value,
9
9
  or asked to support RTL / mirror the layout. DO NOT TRIGGER for backend functions, error
10
10
  messages thrown from functions, or log output — none of those are display strings.
@@ -46,10 +46,10 @@ the app is in. Set `defaultLocale` instead.
46
46
 
47
47
  ## Direction is one setting, not per-component work
48
48
 
49
- Set `dir` once at the document root from the active locale and the browser (and
50
- Mantine) mirror everything — provided every custom style is flow-relative
51
- (`margin-inline-start`, `text-align: start`, Mantine `ms`/`me`) rather than
52
- physical (`margin-left`, `text-align: left`, `ml`/`me`'s physical twins). Write
49
+ Set `dir` once at the document root from the active locale and the browser
50
+ mirror everything — provided every custom style is flow-relative
51
+ (`margin-inline-start`, `text-align: start`, Tailwind `ms-*`/`me-*`) rather than
52
+ physical (`margin-left`, `text-align: left`, `ml-*`/`mr-*`). Write
53
53
  logical properties from the start even in an English-only app; that discipline
54
54
  is what makes an RTL language just another locale file.
55
55
 
@@ -1,5 +1,14 @@
1
1
  # Pikku Paraglide enum labels
2
2
 
3
+ ## Contents
4
+
5
+ - [Agent Operating Procedure](#agent-operating-procedure)
6
+ - [The rules that don't change](#the-rules-that-dont-change)
7
+ - [The generated module](#the-generated-module)
8
+ - [Reconciliation against the database](#reconciliation-against-the-database)
9
+ - [Wiring](#wiring)
10
+ - [What NOT to do](#what-not-to-do)
11
+
3
12
  ## Agent Operating Procedure
4
13
 
5
14
  Use this as an execution checklist, not reference material.
@@ -1,5 +1,18 @@
1
1
  # Pikku i18n (Paraglide JS)
2
2
 
3
+ ## Contents
4
+
5
+ - [Agent Operating Procedure](#agent-operating-procedure)
6
+ - [The product's language is not the code's language](#the-products-language-is-not-the-codes-language)
7
+ - [The moving parts (starter-template layout)](#the-moving-parts-starter-template-layout)
8
+ - [Using messages in components](#using-messages-in-components)
9
+ - [Keys only known at runtime (enum labels, status maps)](#keys-only-known-at-runtime-enum-labels-status-maps)
10
+ - [Type safety — and why deploys block on i18n](#type-safety--and-why-deploys-block-on-i18n)
11
+ - [Compile step](#compile-step)
12
+ - [Adding a second language](#adding-a-second-language)
13
+ - [i18n debug mode (find inlined strings)](#i18n-debug-mode-find-inlined-strings)
14
+ - [What NOT to do](#what-not-to-do)
15
+
3
16
  ## Agent Operating Procedure
4
17
 
5
18
  Use this skill as an execution checklist, not reference material.
@@ -36,7 +49,7 @@ like it works, because the app does come up in that language, and then:
36
49
  - a message missing from a locale falls back to a catalogue nobody wrote
37
50
 
38
51
  The setting that actually decides what a first-time visitor sees is
39
- `defaultLocale`, held in `apps/app/src/i18n/active.json` in the Fabric app
52
+ `defaultLocale`, held in `apps/app/src/i18n/active.json` in the app
40
53
  template and read by `src/i18n/config.ts`. It is deliberately a separate file
41
54
  from `settings.json` for exactly this reason — the source language and the
42
55
  served language are different questions.
@@ -54,12 +67,11 @@ So a German medical portal is **three** settings, not one:
54
67
  { "metaLocale": "de" }
55
68
  ```
56
69
 
57
- In the Fabric template both of the first two have a command, so you rarely edit
58
- them by hand:
70
+ Edit the first two by hand:
59
71
 
60
72
  ```sh
61
- fabric i18n --add-locale de # adds "de" to locales, seeds messages/de.json from en.json
62
- fabric i18n --default-locale de # writes active.json — the app now OPENS in German
73
+ # add "de" to locales and seed messages/de.json from en.json
74
+ # set defaultLocale to "de" in active.json — the app now OPENS in German
63
75
  ```
64
76
 
65
77
  ### The failure this is written from
@@ -160,7 +172,7 @@ helper, stop — that helper IS the bug.
160
172
 
161
173
  A message IS a function: a typo'd or deleted key (`m.auth__login__titel()`) is a missing export — a **TypeScript error**, not a silent runtime fallback string. Params are typed too. The deploy pipeline compiles Paraglide then runs each frontend's `tsc` (`"tsc": "tsc --noEmit"` script — keep it in every frontend's `package.json`) **before** building; a type error aborts the deploy. `vite build` does not type-check on its own, so this gate is the only thing standing between a broken message and production.
162
174
 
163
- The gate catches _invalid_ messages but not _inlined_ strings. The `@pikku/mantine` `I18nNode` prop typing catches those: a raw string literal fails to compile on a gated prop, because `I18nString` is a branded type a bare `string` can't satisfy. Between the two, `tsc` is the whole safety net — there is no runtime fallback to inspect, by design.
175
+ The gate catches _invalid_ messages but not _inlined_ strings. The starter template's `I18nNode` prop typing catches those: a raw string literal fails to compile on a gated prop, because `I18nString` is a branded type a bare `string` can't satisfy. Between the two, `tsc` is the whole safety net — there is no runtime fallback to inspect, by design.
164
176
 
165
177
  ## Compile step
166
178
 
@@ -177,11 +189,11 @@ The gate catches _invalid_ messages but not _inlined_ strings. The `@pikku/manti
177
189
  2. Add `"fr"` to `locales` in `project.inlang/settings.json`. **Leave `baseLocale` at `en`** — step 1 only works because there is an English catalogue to mirror.
178
190
  3. Recompile (restart/`vite dev` or the CLI compile). A locale file missing keys falls back to the base locale per message.
179
191
  4. Content is reachable via the `/<lang>` URL prefix (`detectLocale` already resolves it); the base locale needs no prefix. Expose the switcher via `useLocale().setLocale`.
180
- 5. Only if the app should **open** in the new language rather than merely offer it: set `defaultLocale` (`active.json` / `fabric i18n --default-locale fr`). Adding a locale and changing the default are different asks — do the second only when asked.
192
+ 5. Only if the app should **open** in the new language rather than merely offer it: set `defaultLocale` (`active.json`). Adding a locale and changing the default are different asks — do the second only when asked.
181
193
 
182
194
  ## i18n debug mode (find inlined strings)
183
195
 
184
- `tsc` catches invalid messages, and the `@pikku/mantine` gate catches raw strings on gated props — but neither sees a hardcoded string in plain JSX, an `aria-label`, `alt`, `document.title`, or anything passed to a non-Mantine component. Debug mode covers that gap: render every message as block glyphs (`█`), and whatever is still readable never went through a message.
196
+ `tsc` catches invalid messages, and the template's `I18nNode` gate catches raw strings on gated props — but neither sees a hardcoded string in plain JSX, an `aria-label`, `alt`, `document.title`, or anything passed to a component that does not gate its text. Debug mode covers that gap: render every message as block glyphs (`█`), and whatever is still readable never went through a message.
185
197
 
186
198
  **Build it as a generated locale, never as a runtime wrapper.** Masked text is text, and rendering different text per locale is what Paraglide already does:
187
199
 
@@ -207,7 +219,7 @@ The wrapper alternative — a module that walks the namespace and pipes each mes
207
219
  - Don't let a non-English UI reach the identifiers. Functions, components, types, files, tables and columns are English in every project; the product's language lives in `messages/*.json` and nowhere else.
208
220
  - Don't translate message **keys**. `auth__login__title` stays English in `de.json`; only the value changes.
209
221
  - Don't edit or commit anything under `src/paraglide/` — it's regenerated; change `messages/*.json` instead.
210
- - **Don't wrap `m`.** No re-export module, no branding layer, no resolver. Components import `m` from `../paraglide/messages.js` and call it. `@pikku/react`'s `I18nString` is declared as `string & { readonly __brand: 'LocalizedString' }` — deliberately identical to Paraglide's own `LocalizedString` — so `m.some__key()` satisfies the `@pikku/mantine` `I18nNode` gate natively. A wrapper adds nothing and costs per-message tree-shaking.
222
+ - **Don't wrap `m`.** No re-export module, no branding layer, no resolver. Components import `m` from `../paraglide/messages.js` and call it. `@pikku/react`'s `I18nString` is declared as `string & { readonly __brand: 'LocalizedString' }` — deliberately identical to Paraglide's own `LocalizedString` — so `m.some__key()` satisfies the template's `I18nNode` gate natively. A wrapper adds nothing and costs per-message tree-shaking.
211
223
 
212
224
  `packages/console` is the one place in this repo that still wraps it, in `src/i18n/messages.ts`, to keep the debug mask (`█`) it carried over from i18next. That wrapper is a leftover, not a pattern — the generated-locale approach above is how a new app gets the same masking without touching every export. Don't copy it.
213
225
 
@@ -1,5 +1,16 @@
1
1
  # Pikku RTL (Arabic + English)
2
2
 
3
+ ## Contents
4
+
5
+ - [The one idea](#the-one-idea)
6
+ - [Agent Operating Procedure](#agent-operating-procedure)
7
+ - [Flow-relative, not physical — the rules that make it mirror](#flow-relative-not-physical--the-rules-that-make-it-mirror)
8
+ - [Applying direction at the root](#applying-direction-at-the-root)
9
+ - [Directional icons — the manual bit](#directional-icons--the-manual-bit)
10
+ - [Arabic typography niceties](#arabic-typography-niceties)
11
+ - [Adding Arabic to an existing app — checklist](#adding-arabic-to-an-existing-app--checklist)
12
+ - [What NOT to do](#what-not-to-do)
13
+
3
14
  This reference sits **on top of** `references/messages.md`. That one compiles a locale's
4
15
  messages into typed `m.*()` functions; this one adds the second axis: a locale
5
16
  also has a **direction**. Arabic is not special-cased — it is just another
@@ -9,7 +20,7 @@ being told it is `rtl`.
9
20
  ## The one idea
10
21
 
11
22
  Set `dir` **once at the document root** from the active locale, then let the
12
- browser and Mantine mirror everything — _provided_ every custom style is written
23
+ browser mirror everything — _provided_ every custom style is written
13
24
  **flow-relative** (start/end), never **physical** (left/right). Get those two
14
25
  things right and Arabic, Hebrew, Farsi and Urdu all work with zero per-component
15
26
  _layout_ code — directional icons still need one manual step, covered below.
@@ -51,14 +62,14 @@ Use the **inline-axis logical** property; never the physical one:
51
62
  | `border-top-left-radius` | `border-start-start-radius` |
52
63
  | `float: left/right` | `float: inline-start / inline-end` |
53
64
 
54
- In **Mantine**, use the logical style props — they emit the logical CSS above:
65
+ In **Tailwind**, use the logical utilities — they emit the logical CSS above:
55
66
 
56
67
  | Don't | Do |
57
68
  | ----------- | ----------- |
58
- | `ml` / `mr` | `ms` / `me` |
59
- | `pl` / `pr` | `ps` / `pe` |
69
+ | `ml-*` / `mr-*` | `ms-*` / `me-*` |
70
+ | `pl-*` / `pr-*` | `ps-*` / `pe-*` |
60
71
 
61
- Mantine's own components already use logical properties internally, so once the
72
+ shadcn's own components already use logical properties, so once the
62
73
  direction is set they mirror automatically — you only have to be disciplined in
63
74
  **your** styles.
64
75
 
@@ -70,40 +81,9 @@ logical order; let `dir` handle the visual order.
70
81
 
71
82
  ## Applying direction at the root
72
83
 
73
- ### Mantine app (e.g. environment-template)
74
-
75
- Mantine ships first-class RTL: wrap the tree in `DirectionProvider` and set the
76
- matching `dir` on `<html>`.
77
-
78
- ```tsx
79
- import { DirectionProvider, MantineProvider } from '@mantine/core'
80
- import { detectLocale, localeDir } from './i18n/config'
81
-
82
- const locale =
83
- typeof window !== 'undefined' ? detectLocale(window.location.pathname) : 'en'
84
- const dir = localeDir(locale)
85
-
86
- if (typeof document !== 'undefined') {
87
- document.documentElement.lang = locale
88
- document.documentElement.dir = dir // Mantine + browser read this
89
- }
90
-
91
- root.render(
92
- <DirectionProvider initialDirection={dir}>
93
- <MantineProvider theme={theme} defaultColorScheme="dark">
94
- {/* …app… */}
95
- </MantineProvider>
96
- </DirectionProvider>
97
- )
98
- ```
99
-
100
- To flip direction live (a language switcher) call
101
- `document.documentElement.setAttribute('dir', localeDir(next))` and Mantine's
102
- `useDirection().setDirection(dir)`; both read the same value.
103
-
104
84
  ### Plain Vite SPA (kanban, test-harness vite-spa)
105
85
 
106
- No Mantine — just put `dir`/`lang` on `<html>` at bootstrap, after the locale is
86
+ Put `dir`/`lang` on `<html>` at bootstrap, after the locale is
107
87
  detected (the same `detectLocale` the i18n config uses):
108
88
 
109
89
  ```ts
@@ -211,7 +191,7 @@ left` with the flow-relative equivalent; revert any manual `row-reverse`.
211
191
  - Don't fake RTL with `flex-direction: row-reverse`, reversed DOM order, or
212
192
  per-locale `if (rtl)` layout branches. Set `dir` once; let layout follow.
213
193
  - Don't set `dir` on individual components — it belongs on `<html>` so the whole
214
- document (and Mantine) agrees.
194
+ document agrees.
215
195
  - Don't translate Arabic copy outside the message system; an RTL language is a
216
196
  normal locale, governed by `references/messages.md`. There is no `t()` and no i18next in a
217
197
  Pikku frontend — the string comes from `m.some__key()`.
@@ -3,15 +3,14 @@ name: pikku-knowledge
3
3
  description: >-
4
4
  Use when writing, reading, reorganising or validating a project's knowledge/ directory — the
5
5
  notes that say what the app is, in the language its users use. Covers the Open Knowledge Format
6
- note (path-as-identity markdown, YAML frontmatter, only `type` required), the app-project
7
- profile's sections (entities, decisions, questions, wishlist) and what each answers, how notes
8
- become changes (`pikku knowledge gaps`), the changeset plan, the `resource:` URI scheme tying a
9
- note to its code, what is NOT a knowledge base, and `pikku knowledge validate|index|gaps`. TRIGGER when: user asks to
10
- write down a decision, requirement, entity or open question; asks what the app does or is; asks
11
- about knowledge/, notes, an index.md, or a diagram, callout or decision block; or
12
- hands over a product brief to record. DO NOT TRIGGER when: user asks what functions, routes,
13
- tables or permissions exist (that is `pikku meta` / `pikku info`, never a note), or to write a
14
- scenario test (use pikku-scenario).
6
+ note (path-as-identity markdown, only `type` required), the sections (entities, decisions,
7
+ questions, wishlist), how notes become changes (`pikku knowledge
8
+ gaps`), the `resource:` URI scheme tying a note to its code, and `pikku knowledge validate|index|gaps`. TRIGGER when: user asks to write down a decision,
9
+ requirement, entity or open question; asks what the app does or is; asks about knowledge/
10
+ notes or a diagram, callout or decision block; or hands over a product brief to record. DO NOT TRIGGER when: user asks what functions, routes, tables or permissions exist
11
+ (`pikku meta` / `pikku info`, never a note), wants a scenario test (use pikku-scenario), writes a
12
+ changeset plan (use pikku-architect), or extracts a `.knowledge/` blueprint from a legacy repo
13
+ (use pikku-software-archaeology).
15
14
  installGroups: [core]
16
15
  agent:
17
16
  tools: read, write, edit, bash, grep
@@ -31,7 +30,7 @@ The knowledge base is `knowledge/` at the repo root: markdown notes about **what
31
30
 
32
31
  Not to be confused with `.knowledge/` — the dot-prefixed JSON blueprint that `pikku-software-archaeology` extracts from a legacy repo. Different directory, different format, different purpose.
33
32
 
34
- ## Agent Operating Procedure
33
+ ## Operating procedure
35
34
 
36
35
  1. **Read `knowledge/index.md` first**, then the section index for whatever you are about to touch. It is the cheapest way to learn what the app already claims about itself.
37
36
  2. Before writing a note, ask whether `pikku meta` already answers it. If it does, do not write the note — see _What never goes in a note_.
@@ -206,7 +205,7 @@ It is a **summary, not the note** — the argument continues in prose underneath
206
205
  | `table:` | a table name | the generated db schema |
207
206
  | `addon:` | `@pikku/addon-x` or bare `x` | the manifests that declare the dependency |
208
207
  | `scope:` | a scope name | the `scopes:` a function gates itself with, plus the scopes a `defineSystemRole()` confers |
209
- | `persona:` | a persona name | `definePersonas()` |
208
+ | `virtualUser:` | a virtual user name | `defineVirtualUsers()` |
210
209
 
211
210
  Ids are case-sensitive: `createEntry` is not `createentry`.
212
211
 
@@ -220,7 +219,7 @@ These are all things that exist somewhere better, so a note is always the copy t
220
219
 
221
220
  | Do not write | Because it lives in |
222
221
  | ----------------------------------- | ---------------------------------------------------------- |
223
- | a `personas/` section | `definePersonas()` in the project's own code |
222
+ | a `virtual users/` section | `defineVirtualUsers()` in the project's own code |
224
223
  | a `scenarios/` section | the `scenarios` of the plan for the changeset that builds it |
225
224
  | a `permissions/` section | a decision note under `decisions/security/` |
226
225
  | a list of tables, columns or routes | `pikku meta` — the generated schema _is_ the schema |
@@ -271,4 +270,4 @@ Notes are different: they say what the app is now, so they change whenever it do
271
270
 
272
271
  OKF permits frontmatter fields a reader does not know, and the parser ignores them rather than failing. That is the extension point: a tool layered on Pikku can add its own sections and fields on top of everything above without forking the format.
273
272
 
274
- Fabric is the one that exists. It adds `decisions/design/` — rules about how the app looks and behaves — and a `screens/` section. Both are Fabric's to validate; `pikku knowledge validate` passes them through untouched. Everything else in this skill is the same in both.
273
+ One exists: it adds `decisions/design/` — rules about how the app looks and behaves — and a `screens/` section. Both are the extending tool's to validate; `pikku knowledge validate` passes them through untouched. Everything else in this skill is the same in both.
@@ -1,32 +1,14 @@
1
1
  ---
2
2
  name: pikku-kysely
3
3
  description: >-
4
- Use when WRITING KYSELY QUERIES (select/join/aggregate/insert/update/delete) inside a Pikku
5
- function body, or when setting up SQL database services with Kysely. Covers the query builder
6
- API (joins, aggregates + groupBy/having, returning, sql template, expression builder, $if,
7
- transactions, jsonArrayFrom relation helpers), HOW MANY ROUND TRIPS a function body costs and how to
8
- collapse sequential awaits into one statement, AND @pikku/kysely service setup (channel stores,
9
- workflow services, secret services, AI storage, deployment services). TRIGGER when: writing any
10
- non-trivial kysely query (a join, an aggregate/count/sum, groupBy, subquery, transaction, or
11
- conditional query), the injected `kysely` service is used in a function body, or code uses
12
- PikkuKysely, KyselyChannelStore, KyselyWorkflowService, KyselySecretService, a function body
13
- awaits more than one query, or the user asks about SQL setup with Pikku. DO NOT TRIGGER when: user asks about MongoDB or Redis-backed
14
- services (use pikku-service-backends).
4
+ Use when WRITING KYSELY QUERIES (select, join, aggregate, insert, update, delete) inside a Pikku function body, or when setting up SQL database services with Kysely. Covers the query builder API (joins, groupBy/having, returning, sql template, $if, transactions, jsonArrayFrom), how many round trips a function body costs and how to collapse sequential awaits into one statement, and @pikku/kysely service setup (channel stores, workflow, secret, AI storage and deployment services).
5
+ TRIGGER when: writing any non-trivial kysely query (join, count/sum, groupBy, subquery, transaction, conditional query), a function body awaits more than one query, the injected `kysely` service is used, code uses PikkuKysely, KyselyChannelStore, KyselyWorkflowService or KyselySecretService, or the user asks about SQL setup with Pikku.
6
+ DO NOT TRIGGER when: the services are MongoDB or Redis backed (use pikku-service-backends), or the task is the pagination contract rather than the query (use pikku-list-query).
15
7
  installGroups: [core]
16
8
  ---
17
9
 
18
10
  # Pikku Kysely (SQL Database Services)
19
11
 
20
- ## Agent Operating Procedure
21
-
22
- Use this skill as an execution checklist, not reference material.
23
-
24
- 1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
25
- 2. Identify the source files that own the behavior. Do not start by reading generated output, `.pikku`, `node_modules`, vendored packages, or broad build artifacts.
26
- 3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
27
- 4. Validate with the narrowest relevant command first, then run `pikku all` when functions, wirings, schemas, or generated clients may have changed.
28
- 5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
29
-
30
12
  ## Writing Queries — the Kysely query builder
31
13
 
32
14
  In a Pikku function body the injected `kysely` IS the `Kysely<DB>` instance — query it directly. Every connection factory below wires the **CamelCasePlugin** by default, so you write **camelCase everywhere in TS** (columns, aliases) and raw **snake_case ONLY inside a ` sql` `` literal**. If a project opted out (`createNodeSqliteKysely({ camelCase: false })`), that inverts — check how the instance was built before assuming. Kysely is a query builder, NOT an ORM — there are no relations; shape nested data with the JSON helpers below. Never hand-roll SQL strings; never annotate the return type (in Pikku the output zod schema IS the type).
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: pikku-list-query
3
3
  description: >-
4
- Use when building a paginated/infinite-scroll list — any RPC that returns rows a user scrolls through (tables, card grids, search results). Covers pikkuListFunc, the ListInput/ListOutput cursor contract, and the generated usePikkuInfiniteQuery hook.
4
+ Use when building a paginated or infinite-scroll list: any RPC that returns rows a user scrolls through (tables, card grids, search results). Covers the backend pikkuListFunc, the ListInput/ListOutput cursor contract, the filter tree, and the generated usePikkuInfiniteQuery hook.
5
5
  TRIGGER when: user asks for infinite scroll, "load more", a paginated table/list/grid, or a list that could grow beyond a single page.
6
- DO NOT TRIGGER when: the list is small and fixed (e.g. a settings page with 5 items) — a plain pikkuFunc + usePikkuQuery returning a full array is simpler and correct there.
6
+ DO NOT TRIGGER when: the list is small and fixed (for example 5 settings items), where a plain pikkuFunc plus usePikkuQuery returning a full array is correct, or when the task is general React provider and hook setup (use pikku-react).
7
7
  installGroups: [core, client]
8
8
  ---
9
9
 
@@ -1,5 +1,14 @@
1
1
  # Pikku Dependency Audit
2
2
 
3
+ ## Contents
4
+
5
+ - [Agent Operating Procedure](#agent-operating-procedure)
6
+ - [The `pikku audit` command](#the-pikku-audit-command)
7
+ - [The `pikku update` command](#the-pikku-update-command)
8
+ - [Console integration (@pikku/addon-console)](#console-integration-pikkuaddon-console)
9
+ - [Console UI (@pikku/console)](#console-ui-pikkuconsole)
10
+ - [Report shape (SecurityAuditReport)](#report-shape-securityauditreport)
11
+
3
12
  ## Agent Operating Procedure
4
13
 
5
14
  1. The audit is a generated artifact, not live state. `pikku audit` writes the
@@ -106,7 +115,7 @@ is admin-only), so the host must have Better Auth wired — see `pikku-auth`.
106
115
  **remediation slot**.
107
116
  - `renderRemediation({ pkg, version, issue })` — the extension seam. OSS default
108
117
  is `UpdateDependencyButton` (the free bump + `bun install`). Downstream
109
- consoles (Fabric) pass their own sandbox-verified action here — replace the
118
+ consoles pass their own sandbox-verified action here — replace the
110
119
  action, keep the view.
111
120
  - Hooks: `useSecurityAudit` (read), `useRunSecurityAudit` (run),
112
121
  `useUpdateDependency` (bump). All are `useMutation`/`useQuery` — surface
@@ -1,5 +1,11 @@
1
1
  # Pikku Project Metadata
2
2
 
3
+ ## Contents
4
+
5
+ - [Reading](#reading)
6
+ - [Changing](#changing)
7
+ - [Human-readable tables (`pikku info`)](#human-readable-tables-pikku-info)
8
+
3
9
  `pikku meta` is the machine-readable view of the project and the write path to it.
4
10
  `pikku info` is the same ground as human-readable tables. Prefer `meta` when you are
5
11
  going to act on the output; prefer `info` when a person is going to read it.
@@ -1,5 +1,15 @@
1
1
  # Pikku Function Versioning
2
2
 
3
+ ## Contents
4
+
5
+ - [Before You Start](#before-you-start)
6
+ - [Function Versioning](#function-versioning)
7
+ - [Version Manifest (`versions.pikku.json`)](#version-manifest-versionspikkujson)
8
+ - [CLI Commands](#cli-commands)
9
+ - [The `pikku release` command](#the-pikku-release-command)
10
+ - [CI Integration](#ci-integration)
11
+ - [Complete Example](#complete-example)
12
+
3
13
  ## Before You Start
4
14
 
5
15
  ```bash
@@ -1,24 +1,15 @@
1
1
  ---
2
2
  name: pikku-middleware
3
3
  description: >-
4
- Use when adding any middleware to a Pikku app — global HTTP middleware, tag-scoped middleware
5
- (including service-to-service bearer auth), per-route middleware, session-setting middleware, or
6
- understanding middleware execution order and priority. TRIGGER when: user wants middleware on
7
- some or all routes, machine-to-machine auth, tag-scoped cross-cutting concerns, global
8
- interceptors, or middleware priority/order questions. DO NOT TRIGGER when: user asks about
9
- permissions, sessions or auth strategies like authBearer/authCookie (use
10
- pikku-auth), or deployment.
4
+ Use when adding middleware to a Pikku app: global (addGlobalMiddleware), HTTP and prefix (addHTTPMiddleware), tag-scoped (addTagMiddleware), per-wiring, session-setting middleware, and execution order and priority. Covers the pikkuMiddleware factory, where a token is resolved into a session (HTTP middleware, cron tasks), and service-to-service bearer gates.
5
+ TRIGGER when: user wants middleware on some or all routes, tag-scoped cross-cutting concerns, global interceptors, middleware priority or order questions, or middleware that calls setSession for a machine caller.
6
+ DO NOT TRIGGER when: the question is choosing or configuring an auth strategy (authBearer, authCookie, Better Auth, API keys, `pikku login`), permissions or scopes (use pikku-permissions), or deployment.
11
7
  installGroups: [core]
12
8
  ---
13
9
 
14
10
  # Pikku Middleware
15
11
 
16
- ## Agent Operating Procedure
17
-
18
- 1. Discover before editing. Run `pikku info middleware --verbose` and `pikku info tags --json` to understand the existing middleware and tag landscape.
19
- 2. Identify the source files that own the behavior — wirings files, not generated output.
20
- 3. Register middleware at module load time — in a `wirings/*.ts` file, never inside a function body.
21
- 4. Validate: run `pikku all --tsc` after adding or changing middleware — it regenerates and then confirms type safety in one pass.
12
+ Register middleware at module load time in a `wirings/*.ts` file, never inside a function body. After a change, run `pikku all --tsc`.
22
13
 
23
14
  ## The `pikkuMiddleware` Factory
24
15
 
@@ -223,7 +214,7 @@ export const reportSomething = pikkuFunc({
223
214
  })
224
215
  ```
225
216
 
226
- An unresolved token leaves the session unset and the function throws `MissingSessionError` — 401, for free. Declare the scope tree once with `defineScope` (see `pikku-auth`).
217
+ An unresolved token leaves the session unset and the function throws `MissingSessionError` — 401, for free. Declare the scope tree once with `defineScope` (see `pikku-permissions`).
227
218
 
228
219
  ### It MUST be `addHTTPMiddleware`, never `addTagMiddleware`
229
220
 
@@ -255,13 +246,13 @@ Unlike tag middleware over `/rpc`, this works: `runScheduledTask` builds its wir
255
246
 
256
247
  ### The one sessionless exception: bootstrap
257
248
 
258
- An endpoint that runs BEFORE the caller has an identity — registering a new host with a shared bootstrap key, a login, a device-code request — has no session to set. That one stays `pikkuSessionlessFunc` and declares its gate in `permissions` (see `pikku-auth`).
249
+ An endpoint that runs BEFORE the caller has an identity — registering a new host with a shared bootstrap key, a login, a device-code request — has no session to set. That one stays `pikkuSessionlessFunc` and declares its gate in `permissions` (see `pikku-permissions`).
259
250
 
260
251
  ## Service-to-Service Bearer Auth (gate-only pattern)
261
252
 
262
253
  Use this when the callee needs to know only THAT the caller is trusted, not WHICH caller it is. If it needs to know which, use the session pattern above.
263
254
 
264
- A server that exposes RPCs only to a trusted caller (e.g. an API calling a machine-agent). Auth lives in a tag middleware — NOT in the function body. Authorization/permission checks belong in the `permissions` field (see `pikku-auth`), never inside `func`.
255
+ A server that exposes RPCs only to a trusted caller (e.g. an API calling a machine-agent). Auth lives in a tag middleware — NOT in the function body. Authorization/permission checks belong in the `permissions` field (see `pikku-permissions`), never inside `func`.
265
256
 
266
257
  **On the server (the service being called):** tag the function, register a `pikkuMiddleware` that reads the `Authorization` header on that tag.
267
258
 
@@ -1,6 +1,14 @@
1
1
  ---
2
2
  name: pikku-n8n-import
3
- description: 'Use to import an n8n workflow JSON export into a runnable Pikku workflow. Triggers when the user says "import this n8n workflow", "convert this n8n export to pikku", points at an n8n `.json` export or a directory of them, or picks up after `pikku import n8n` left throwing stub functions (`STUB — generated from n8n …`, `— implement me`) or a `<workflow>.integrations.json` manifest. Owns the whole flow: run the importer, triage what it could not map, fill each stub, report any missing `@pikku/addon-*` integrations, and verify the result compiles and runs with no surviving stubs. DO NOT TRIGGER for hand-written addon wiring unrelated to an n8n import (use pikku-addon), or for authoring workflows from scratch (use pikku-workflow).'
3
+ description: >-
4
+ Use when importing an n8n workflow JSON export into a runnable Pikku workflow. Owns the whole
5
+ flow: run `pikku import n8n`, triage what it could not map, fill each stub, report missing
6
+ `@pikku/addon-*` integrations, and verify the result compiles with no surviving stubs. TRIGGER
7
+ when: the user says "import this n8n workflow" or "convert this n8n export to pikku", points at
8
+ an n8n `.json` export or a directory of them, or continues after `pikku import n8n` left throwing
9
+ stub functions (`STUB — generated from n8n …`, `— implement me`) or a `*.integrations.json`
10
+ manifest. DO NOT TRIGGER for hand-written addon wiring unrelated to an n8n import (use
11
+ pikku-addon), or for authoring workflows from scratch (use pikku-workflow).
4
12
  installGroups: [core]
5
13
  metadata:
6
14
  version: 1.0.0