@pikku/skills 0.12.52 → 0.12.54

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 (104) hide show
  1. package/dist/skills.gen.js +2 -2
  2. package/package.json +1 -1
  3. package/skills/pikku-a11y/SKILL.md +22 -15
  4. package/skills/pikku-addon/SKILL.md +5 -5
  5. package/skills/pikku-addon/references/addon-package-manifest.md +7 -0
  6. package/skills/pikku-addon/references/openapi.md +11 -0
  7. package/skills/pikku-admin-to-fabric/SKILL.md +7 -21
  8. package/skills/pikku-agent/SKILL.md +6 -6
  9. package/skills/pikku-agent/references/agents.md +8 -1
  10. package/skills/pikku-agent/references/runner-vercel.md +2 -2
  11. package/skills/pikku-agent/references/voice.md +7 -1
  12. package/skills/pikku-architect/SKILL.md +1 -1
  13. package/skills/pikku-architect/references/plan-defects.md +2 -0
  14. package/skills/pikku-auth/SKILL.md +15 -36
  15. package/skills/pikku-auth/references/better-auth.md +22 -45
  16. package/skills/pikku-auth/references/jose.md +6 -0
  17. package/skills/pikku-auth/references/machine-auth.md +6 -0
  18. package/skills/pikku-auth/references/sessions.md +6 -0
  19. package/skills/pikku-blueprint-to-fabric/SKILL.md +6 -21
  20. package/skills/pikku-blueprint-to-fabric/scripts/inventory.mjs +1 -1
  21. package/skills/pikku-build/SKILL.md +29 -26
  22. package/skills/pikku-build/references/app.md +60 -41
  23. package/skills/pikku-build/references/design.md +31 -19
  24. package/skills/pikku-build/references/feature.md +14 -0
  25. package/skills/pikku-build/references/mocks.md +23 -0
  26. package/skills/pikku-build/references/multi-app.md +9 -2
  27. package/skills/pikku-build/references/native-app.md +9 -0
  28. package/skills/pikku-build/references/openapi.md +7 -0
  29. package/skills/pikku-build/references/platform.md +20 -10
  30. package/skills/pikku-build/references/quick.md +14 -4
  31. package/skills/pikku-build/references/scenarios.md +12 -1
  32. package/skills/pikku-build/references/ship.md +6 -1
  33. package/skills/pikku-build/references/theming.md +74 -125
  34. package/skills/pikku-changes/SKILL.md +6 -6
  35. package/skills/pikku-concepts/SKILL.md +8 -17
  36. package/skills/pikku-concepts/references/concept-mapping.md +18 -0
  37. package/skills/pikku-convert-screen/SKILL.md +45 -0
  38. package/skills/pikku-deploy/references/cloudflare.md +8 -0
  39. package/skills/pikku-deploy/references/lambda.md +8 -0
  40. package/skills/pikku-deploy/references/uws.md +1 -1
  41. package/skills/pikku-deploy/references/ws.md +3 -3
  42. package/skills/pikku-emails/SKILL.md +3 -9
  43. package/skills/pikku-fabric/SKILL.md +7 -295
  44. package/skills/pikku-fabric/references/database.md +128 -0
  45. package/skills/pikku-fabric/references/debugging.md +9 -5
  46. package/skills/pikku-fabric/references/deploy.md +179 -0
  47. package/skills/pikku-guide/SKILL.md +10 -10
  48. package/skills/pikku-i18n/SKILL.md +7 -7
  49. package/skills/pikku-i18n/references/enum-labels.md +9 -0
  50. package/skills/pikku-i18n/references/messages.md +16 -3
  51. package/skills/pikku-i18n/references/rtl.md +18 -38
  52. package/skills/pikku-knowledge/SKILL.md +9 -10
  53. package/skills/pikku-kysely/SKILL.md +3 -21
  54. package/skills/pikku-list-query/SKILL.md +2 -2
  55. package/skills/pikku-meta/references/audit.md +9 -0
  56. package/skills/pikku-meta/references/meta.md +6 -0
  57. package/skills/pikku-meta/references/versioning.md +10 -0
  58. package/skills/pikku-middleware/SKILL.md +7 -16
  59. package/skills/pikku-n8n-import/SKILL.md +9 -1
  60. package/skills/pikku-n8n-import/references/addon-mapping.md +6 -0
  61. package/skills/pikku-n8n-import/references/code-translation.md +7 -0
  62. package/skills/pikku-permissions/SKILL.md +41 -10
  63. package/skills/pikku-permissions/references/scopes.md +59 -0
  64. package/skills/pikku-react/SKILL.md +2 -2
  65. package/skills/pikku-react/references/client.md +1 -34
  66. package/skills/pikku-react/references/react-query.md +11 -0
  67. package/skills/pikku-react/references/workflows.md +11 -0
  68. package/skills/pikku-realtime/SKILL.md +9 -3
  69. package/skills/pikku-report/SKILL.md +10 -9
  70. package/skills/pikku-scenario/SKILL.md +11 -17
  71. package/skills/pikku-scenario/references/persona-run.md +11 -1
  72. package/skills/pikku-scenario/references/personas.md +7 -1
  73. package/skills/pikku-seo/SKILL.md +12 -16
  74. package/skills/pikku-service-backends/SKILL.md +0 -10
  75. package/skills/pikku-service-backends/references/aws.md +6 -0
  76. package/skills/pikku-service-backends/references/mongodb.md +7 -0
  77. package/skills/pikku-service-backends/references/redis.md +6 -0
  78. package/skills/pikku-services/references/audit.md +10 -0
  79. package/skills/pikku-services/references/config.md +6 -0
  80. package/skills/pikku-services/references/services.md +8 -1
  81. package/skills/pikku-software-archaeology/SKILL.md +9 -15
  82. package/skills/pikku-software-archaeology/references/blueprint.schema.json +7 -7
  83. package/skills/pikku-software-archaeology/references/pikku-mapping.md +3 -3
  84. package/skills/pikku-software-archaeology/references/second-opinion.md +13 -1
  85. package/skills/pikku-tailwind/SKILL.md +111 -0
  86. package/skills/pikku-theme/SKILL.md +187 -0
  87. package/skills/pikku-theme/references/from-a-reference.md +44 -0
  88. package/skills/pikku-theme/references/presets.md +40 -0
  89. package/skills/pikku-ui/SKILL.md +41 -0
  90. package/skills/pikku-wiring/SKILL.md +13 -12
  91. package/skills/pikku-wiring/references/channel.md +7 -1
  92. package/skills/pikku-wiring/references/cli.md +7 -1
  93. package/skills/pikku-wiring/references/gateway-slack.md +6 -0
  94. package/skills/pikku-wiring/references/http.md +10 -3
  95. package/skills/pikku-wiring/references/mcp.md +8 -0
  96. package/skills/pikku-wiring/references/queue.md +6 -0
  97. package/skills/pikku-wiring/references/realtime.md +34 -4
  98. package/skills/pikku-wiring/references/rpc.md +6 -0
  99. package/skills/pikku-wiring/references/scheduler.md +6 -0
  100. package/skills/pikku-wiring/references/trigger.md +8 -0
  101. package/skills/pikku-workflow/SKILL.md +8 -6
  102. package/skills/pikku-auth/references/permissions.md +0 -261
  103. package/skills/pikku-mantine/SKILL.md +0 -80
  104. package/skills/pikku-wiring/references/realtime-other-routes.md +0 -23
@@ -0,0 +1,179 @@
1
+ # Deploying a Fabric app
2
+
3
+ ## Contents
4
+
5
+ - Deploy commands and organization targeting
6
+ - Rebuilding a disposable stage: `--reset`
7
+ - Exit codes, the approval gate, CI splitting, GitHub adoption and the upstream guard (inside Deploy commands)
8
+ - The first user on a deployed stage
9
+ - Opening a private stage
10
+
11
+ ## Deploy commands and organization targeting
12
+
13
+ ```bash
14
+ pikku fabric login # opens a browser; needs a human, wait for it
15
+ pikku fabric init https://github.com/<owner>/<repo>
16
+ pikku fabric validate # must pass clean
17
+ pikku fabric deploy apply --production -y
18
+ ```
19
+
20
+ `init` and `link` import into whichever organization your session is in. When
21
+ you belong to several — a personal one and a company one, say — name the target
22
+ with `--organization`, taking a slug, a display name or an id:
23
+
24
+ ```bash
25
+ pikku fabric link --organization vlandor
26
+ ```
27
+
28
+ You have to be a member of the organization you name, and its GitHub account
29
+ has to be connected already: importing a `github.com/<owner>/<repo>` repo needs
30
+ the Fabric GitHub App installed on `<owner>` _and_ linked to that organization,
31
+ or the import refuses by name.
32
+
33
+ The branch is positional and defaults to the checked-out one, and `-y` is the
34
+ short form of `--auto-approve`, so a one-shot deploy is:
35
+
36
+ ```bash
37
+ pikku fabric deploy apply -y # the branch you are standing on
38
+ pikku fabric deploy apply my-branch -y # a named one
39
+ ```
40
+
41
+ `-y` answers the prompts and nothing more. It does **not** approve migrations
42
+ that drop or rewrite data — that stays `--allow-destructive`, typed out on
43
+ purpose.
44
+
45
+ ## Rebuilding a disposable stage: `--reset`
46
+
47
+ A non-production stage whose migration history or schema has drifted (an app's
48
+ `develop` branch) can be wiped and rebuilt in one deploy:
49
+
50
+ ```bash
51
+ pikku fabric deploy apply develop --reset # asks first, naming app + stage
52
+ pikku fabric deploy apply develop --reset -y # prints the warning, skips the prompt
53
+ ```
54
+
55
+ It is the deployed counterpart of `pikku db reset`: **all data on that stage is
56
+ deleted**, every migration is re-applied and `db/<engine>-dev-seed.sql` is
57
+ loaded. It is refused for `--production`, for `main`, and with `--deployment-id`
58
+ (it only applies to a deploy it creates). It needs a fabric server that reports
59
+ the reset back on the deployment; against one that does not, the command fails
60
+ naming the deployment it created without a reset, and wipes nothing. `-y` does
61
+ not imply `--allow-destructive`.
62
+
63
+ Inferring the branch is safe because the git safety check refuses any branch
64
+ without an upstream or out of sync with it, so it cannot ship an unpushed
65
+ commit; the branch it picked is printed before the build starts. A detached
66
+ HEAD is refused by name rather than travelling on as a branch called `HEAD`.
67
+
68
+ There is no `deploy plan` subcommand — `apply` runs the same auth, git-safety
69
+ and ref resolution itself, and fabric produces the real plan server-side.
70
+
71
+ `apply` confirms before deploying, and with no TTY to ask — CI, an agent shell —
72
+ it refuses rather than hangs. `--auto-approve` (`-y`) supplies that confirmation;
73
+ drop it only when a human is at a real terminal.
74
+
75
+ `apply` waits for a terminal state and exits non-zero unless the deployment went
76
+ live. `--detach` opts out — it queues the deploy, prints the deployment id and
77
+ returns 0, which tells you nothing about whether it worked:
78
+
79
+ | exit | meaning |
80
+ | ---- | ----------------------------------------------------------------------- |
81
+ | 0 | live (or queued, under `--detach`) |
82
+ | 1 | the command could not run — not logged in, unsafe git state, bad flags |
83
+ | 2 | the deployment failed, errored, timed out server-side, or was cancelled |
84
+ | 3 | the deployment is blocked and nothing the CLI can do will unblock it |
85
+ | 4 | the wait hit `--timeout` with the deployment still in flight |
86
+
87
+ On a failure or timeout, `apply` prints the tail of the builder's own log (and
88
+ carries `buildLog` / `imageBuildLog` on the `--json` result). Read it before
89
+ touching code: `fabric logs` serves the running stage, not the build. When the
90
+ builder recorded nothing, the CLI says so — that is usually fabric-side, so run
91
+ `pikku fabric smoke` before assuming the project is broken.
92
+
93
+ Fabric parks every deploy at a gate after the plan phase (`status: suspended`).
94
+ Why it parked is the whole story, and it is `statusReason`, not `status`:
95
+
96
+ - `awaiting_approval` — the plan is fine, a human has to publish it.
97
+ `-y` does that; without it you get exit 3 and the command to run.
98
+ One exception: if fabric marked any pending migration **destructive** — a
99
+ drop, a truncate, a rewrite — `-y` alone declines and exits 3,
100
+ because a standing yes was given before anyone knew the plan dropped a table.
101
+ The CLI lists the migrations and fabric's reasons; `--allow-destructive`
102
+ accepts them for that deploy, and `-y` implies it.
103
+ - `needs_config` — a declared secret or variable has no value covering the
104
+ stage. The CLI names them. `-y` will **not** force this through;
105
+ set the values and re-attach — `pikku fabric secrets set <name>` for a
106
+ declared secret, `pikku fabric variables set <name> --value <v>` for a declared
107
+ variable. They are separate stores: a secret is sealed to the stage and cannot
108
+ be read back, a variable is stored plainly and can (`variables get`). `set`
109
+ reads the value as JSON when it parses, so `--value true` is the boolean on a
110
+ stage exactly as it is from `.env`, and `--value '"true"'` is the string.
111
+ - `needs_attention` — the plan is red. Nothing to approve.
112
+
113
+ The wait defaults to a 900s ceiling; `--timeout <seconds>` moves it. On timeout
114
+ it prints the deployment id and the re-attach command rather than lying about
115
+ the outcome.
116
+
117
+ Splitting kick-off from waiting across two CI jobs is the reason
118
+ `--deployment-id` exists, and what `--detach` is for — the first job here has to
119
+ return the id and exit rather than wait:
120
+
121
+ ```bash
122
+ id=$(pikku fabric deploy apply --production -y --detach --json | jq -r 'select(.event=="result").deploymentId')
123
+ # …later, in another job…
124
+ pikku fabric deploy apply --deployment-id "$id" -y
125
+ ```
126
+
127
+ `--deployment-id` skips the git safety check entirely (the deployment already
128
+ pins a sha, and the checkout is allowed to have moved on) and refuses to be
129
+ combined with a branch or `--production`, which would let the two disagree.
130
+
131
+ Under `--json`, the wait emits one NDJSON event per line — `created`/`attached`,
132
+ `status` on each transition, `blocked`, `approved` — and the last line is the
133
+ terminal result object, tagged `"event": "result"`.
134
+
135
+ `init` adopts a **GitHub** repo, and adoption goes through the Pikku Fabric
136
+ GitHub App — the app has to be installed on the account or org that owns the
137
+ repo, and if it is installed with "selected repositories" this one must be in
138
+ the selection. There is no CLI flag that works around a missing installation:
139
+ `init` returns "Connect the GitHub account '<owner>'". Send the user to install
140
+ it, or create the project in the console instead (which provisions a Fabric-hosted
141
+ git repo you push to) and clone it — the remote links the checkout, or put
142
+ the id in `fabric.projectId` in `pikku.config.json`.
143
+
144
+ Deploy refuses to run unless the target branch equals its upstream — the guard
145
+ compares `main` against `main@{upstream}`. So the remote you pushed to must be
146
+ the one the branch tracks; a stale `origin` left over from scaffolding blocks
147
+ the deploy with "local HEAD … ≠ remote …" even though your code is pushed.
148
+ `git branch --set-upstream-to=<remote>/main main` before deploying.
149
+
150
+ ## The first user on a deployed stage
151
+
152
+ When sign-up is off, the first account has to come from outside the app.
153
+ `pikku fabric user add <email>` is the CLI form of the console's Add user:
154
+
155
+ ```bash
156
+ pikku fabric user add ada@example.com --name Ada # prompts; blank generates one
157
+ pikku fabric user add ada@example.com --password '<pw>' -b staging
158
+ ```
159
+
160
+ It mints a short-lived operator token for the stage and calls the stage's own
161
+ `admin:createUser`, so the stage must wire `@pikku/addon-admin` as `admin` —
162
+ a 404 is refused by name and nothing is created. A generated password is printed
163
+ once; one you passed is never echoed. With no TTY, pass `--password` or pipe it.
164
+
165
+ ## Opening a private stage
166
+
167
+ A non-production stage is private: without a link it answers "This preview is
168
+ private". `pikku fabric stage link` prints the link that opens it:
169
+
170
+ ```bash
171
+ pikku fabric stage link access -b develop --route /login # use the stage
172
+ pikku fabric stage link changes -b develop # use it with the changes panel
173
+ pikku fabric stage visibility public -b develop # or: private
174
+ ```
175
+
176
+ A stage has one live link of each kind, so asking again returns the same one
177
+ until it expires. A `changes` link turns the panel on first; if that needs a
178
+ deploy, the command says so. `visibility public` opens the stage to anyone with
179
+ its URL — hand out an `access` link instead when that is all you need.
@@ -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
 
@@ -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.
@@ -160,7 +173,7 @@ helper, stop — that helper IS the bug.
160
173
 
161
174
  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
175
 
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.
176
+ 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
177
 
165
178
  ## Compile step
166
179
 
@@ -181,7 +194,7 @@ The gate catches _invalid_ messages but not _inlined_ strings. The `@pikku/manti
181
194
 
182
195
  ## i18n debug mode (find inlined strings)
183
196
 
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.
197
+ `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
198
 
186
199
  **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
200
 
@@ -207,7 +220,7 @@ The wrapper alternative — a module that walks the namespace and pipes each mes
207
220
  - 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
221
  - Don't translate message **keys**. `auth__login__title` stays English in `de.json`; only the value changes.
209
222
  - 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.
223
+ - **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
224
 
212
225
  `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
226
 
@@ -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_.
@@ -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
@@ -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
@@ -1,5 +1,11 @@
1
1
  # Integration stub → Pikku addon
2
2
 
3
+ ## Contents
4
+
5
+ - Inputs
6
+ - Per entry, in order
7
+ - Never
8
+
3
9
  Translate n8n integration nodes (`gmailTool`, `slackTool`, `googleSheetsTool`, plain
4
10
  `gmail` / `slack` action nodes, etc.) that the importer left as throwing stubs into
5
11
  real `ref('<addonRpc>')` references pointing at functions in **installed**
@@ -1,5 +1,12 @@
1
1
  # n8n Code node → Pikku function
2
2
 
3
+ ## Contents
4
+
5
+ - Process
6
+ - Rubric
7
+ - Example
8
+ - Report
9
+
3
10
  Replace a Code-node stub's `throw new Error(...)` body with a faithful TypeScript
4
11
  reimplementation. The original JS is preserved verbatim in the JSDoc above the
5
12
  function. Keep the signature and JSDoc intact; only widen the Zod input/output if