@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.
- package/README.md +1 -1
- package/dist/skills.gen.js +2 -2
- package/dist/snippets.js +1 -1
- package/package.json +1 -1
- package/skills/pikku-a11y/SKILL.md +22 -15
- package/skills/pikku-addon/SKILL.md +5 -5
- package/skills/pikku-addon/references/addon-package-manifest.md +7 -0
- package/skills/pikku-addon/references/openapi.md +11 -0
- package/skills/pikku-agent/SKILL.md +6 -6
- package/skills/pikku-agent/references/agents.md +8 -1
- package/skills/pikku-agent/references/runner-vercel.md +2 -2
- package/skills/pikku-agent/references/voice.md +7 -1
- package/skills/pikku-architect/SKILL.md +2 -2
- package/skills/pikku-architect/references/plan-defects.md +9 -7
- package/skills/pikku-auth/SKILL.md +15 -36
- package/skills/pikku-auth/references/better-auth.md +106 -133
- package/skills/pikku-auth/references/jose.md +6 -0
- package/skills/pikku-auth/references/machine-auth.md +6 -0
- package/skills/pikku-auth/references/sessions.md +6 -0
- package/skills/pikku-build/SKILL.md +37 -34
- package/skills/pikku-build/references/app.md +113 -99
- package/skills/pikku-build/references/design.md +43 -31
- package/skills/pikku-build/references/feature.md +17 -3
- package/skills/pikku-build/references/mocks.md +29 -0
- package/skills/pikku-build/references/multi-app.md +25 -18
- package/skills/pikku-build/references/native-app.md +9 -0
- package/skills/pikku-build/references/openapi.md +41 -34
- package/skills/pikku-build/references/platform.md +23 -14
- package/skills/pikku-build/references/post-clone.md +1 -1
- package/skills/pikku-build/references/quick.md +76 -39
- package/skills/pikku-build/references/scenarios.md +28 -16
- package/skills/pikku-build/references/ship.md +19 -16
- package/skills/pikku-build/references/theming.md +76 -127
- package/skills/pikku-changes/SKILL.md +7 -10
- package/skills/pikku-concepts/SKILL.md +34 -44
- package/skills/pikku-concepts/references/concept-mapping.md +18 -0
- package/skills/pikku-concepts/references/language.md +6 -6
- package/skills/pikku-convert-screen/SKILL.md +45 -0
- package/skills/pikku-deploy/references/cloudflare.md +8 -0
- package/skills/pikku-deploy/references/lambda.md +8 -0
- package/skills/pikku-deploy/references/nextjs.md +1 -1
- package/skills/pikku-deploy/references/uws.md +1 -1
- package/skills/pikku-deploy/references/ws.md +3 -3
- package/skills/pikku-emails/SKILL.md +3 -9
- package/skills/pikku-guide/SKILL.md +28 -27
- package/skills/pikku-i18n/SKILL.md +7 -7
- package/skills/pikku-i18n/references/enum-labels.md +9 -0
- package/skills/pikku-i18n/references/messages.md +21 -9
- package/skills/pikku-i18n/references/rtl.md +18 -38
- package/skills/pikku-knowledge/SKILL.md +12 -13
- package/skills/pikku-kysely/SKILL.md +3 -21
- package/skills/pikku-list-query/SKILL.md +2 -2
- package/skills/pikku-meta/references/audit.md +10 -1
- package/skills/pikku-meta/references/meta.md +6 -0
- package/skills/pikku-meta/references/versioning.md +10 -0
- package/skills/pikku-middleware/SKILL.md +7 -16
- package/skills/pikku-n8n-import/SKILL.md +9 -1
- package/skills/pikku-n8n-import/references/addon-mapping.md +6 -0
- package/skills/pikku-n8n-import/references/code-translation.md +7 -0
- package/skills/pikku-permissions/SKILL.md +41 -10
- package/skills/pikku-permissions/references/scopes.md +59 -0
- package/skills/pikku-react/SKILL.md +20 -22
- package/skills/pikku-react/references/client.md +2 -70
- package/skills/pikku-react/references/react-query.md +11 -0
- package/skills/pikku-react/references/workflows.md +11 -0
- package/skills/pikku-realtime/SKILL.md +9 -3
- package/skills/pikku-report/SKILL.md +17 -16
- package/skills/pikku-scenario/SKILL.md +72 -81
- package/skills/pikku-scenario/references/browser.md +5 -5
- package/skills/pikku-scenario/references/coverage.md +4 -4
- package/skills/pikku-scenario/references/steps.md +31 -30
- package/skills/pikku-scenario/references/{persona-run.md → virtual-user-run.md} +47 -42
- package/skills/pikku-scenario/references/virtual-users.md +114 -0
- package/skills/pikku-seo/SKILL.md +12 -16
- package/skills/pikku-service-backends/SKILL.md +0 -10
- package/skills/pikku-service-backends/references/aws.md +6 -0
- package/skills/pikku-service-backends/references/mongodb.md +7 -0
- package/skills/pikku-service-backends/references/redis.md +6 -0
- package/skills/pikku-services/references/audit-wire-service.md +2 -2
- package/skills/pikku-services/references/audit.md +10 -1
- package/skills/pikku-services/references/config.md +6 -0
- package/skills/pikku-services/references/services.md +9 -2
- package/skills/pikku-software-archaeology/SKILL.md +21 -27
- package/skills/pikku-software-archaeology/references/blueprint.schema.json +16 -16
- package/skills/pikku-software-archaeology/references/pikku-mapping.md +3 -3
- package/skills/pikku-software-archaeology/references/second-opinion.md +13 -1
- package/skills/pikku-tailwind/SKILL.md +111 -0
- package/skills/pikku-theme/SKILL.md +187 -0
- package/skills/pikku-theme/references/from-a-reference.md +44 -0
- package/skills/pikku-theme/references/presets.md +40 -0
- package/skills/pikku-ui/SKILL.md +41 -0
- package/skills/pikku-wiring/SKILL.md +13 -12
- package/skills/pikku-wiring/references/channel.md +7 -1
- package/skills/pikku-wiring/references/cli.md +7 -1
- package/skills/pikku-wiring/references/gateway-slack.md +6 -0
- package/skills/pikku-wiring/references/http.md +10 -3
- package/skills/pikku-wiring/references/mcp.md +8 -0
- package/skills/pikku-wiring/references/queue.md +6 -0
- package/skills/pikku-wiring/references/realtime.md +34 -4
- package/skills/pikku-wiring/references/rpc.md +6 -0
- package/skills/pikku-wiring/references/scheduler.md +6 -0
- package/skills/pikku-wiring/references/trigger.md +8 -0
- package/skills/pikku-workflow/SKILL.md +9 -7
- package/skills/pikku-admin-to-fabric/SKILL.md +0 -212
- package/skills/pikku-auth/references/permissions.md +0 -261
- package/skills/pikku-blueprint-to-fabric/SKILL.md +0 -377
- package/skills/pikku-blueprint-to-fabric/scripts/inventory.mjs +0 -367
- package/skills/pikku-fabric/SKILL.md +0 -619
- package/skills/pikku-fabric/references/debugging.md +0 -110
- package/skills/pikku-mantine/SKILL.md +0 -80
- package/skills/pikku-scenario/references/personas.md +0 -117
- 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,
|
|
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
|
|
6
|
-
the WebSocket server shares a port with an existing HTTP app
|
|
7
|
-
|
|
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
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
24
|
-
|
|
25
|
-
| Structure | `pikkuFeature` meta — which features exist, and that every one is cited
|
|
26
|
-
| Evidence
|
|
27
|
-
| Prose
|
|
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
|
|
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
|
|
165
|
-
|
|
166
|
-
| Screenshot | the `name` it was taken under
|
|
167
|
-
| Recording
|
|
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
|
|
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
|
|
201
|
-
"test-user-3" is on every page of the guide; give
|
|
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
|
-
|
|
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
|
|
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
|
|
288
|
-
- [ ]
|
|
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
|
|
6
|
-
language, generated enum-label maps with @pikku/paraglide, and right-to-left support
|
|
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
|
|
50
|
-
|
|
51
|
-
(`margin-inline-start`, `text-align: start`,
|
|
52
|
-
physical (`margin-left`, `text-align: left`, `ml
|
|
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
|
|
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
|
-
|
|
58
|
-
them by hand:
|
|
70
|
+
Edit the first two by hand:
|
|
59
71
|
|
|
60
72
|
```sh
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
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`
|
|
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
|
|
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
|
|
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
|
|
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 **
|
|
65
|
+
In **Tailwind**, use the logical utilities — they emit the logical CSS above:
|
|
55
66
|
|
|
56
67
|
| Don't | Do |
|
|
57
68
|
| ----------- | ----------- |
|
|
58
|
-
| `ml
|
|
59
|
-
| `pl
|
|
69
|
+
| `ml-*` / `mr-*` | `ms-*` / `me-*` |
|
|
70
|
+
| `pl-*` / `pr-*` | `ps-*` / `pe-*` |
|
|
60
71
|
|
|
61
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
##
|
|
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
|
-
| `
|
|
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 `
|
|
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
|
-
|
|
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
|
|
5
|
-
function body,
|
|
6
|
-
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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:
|
|
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
|