@pikku/skills 0.12.9 → 0.12.11

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 (75) hide show
  1. package/CHANGELOG.md +768 -0
  2. package/dist/skills.gen.js +1 -1
  3. package/package.json +4 -4
  4. package/skills/pikku-addon/SKILL.md +20 -14
  5. package/skills/pikku-addon/references/addon-package-manifest.md +2 -2
  6. package/skills/{pikku-ai-agent → pikku-agent}/SKILL.md +24 -24
  7. package/skills/pikku-ai-vercel/SKILL.md +18 -18
  8. package/skills/pikku-ai-voice/SKILL.md +15 -15
  9. package/skills/pikku-audit/SKILL.md +28 -13
  10. package/skills/pikku-aws/SKILL.md +2 -2
  11. package/skills/pikku-better-auth/SKILL.md +97 -17
  12. package/skills/pikku-build-app/SKILL.md +621 -0
  13. package/skills/pikku-build-app/references/multi-app.md +117 -0
  14. package/skills/pikku-build-app/references/ship.md +98 -0
  15. package/skills/pikku-build-app/references/theming.md +70 -0
  16. package/skills/pikku-build-platform/SKILL.md +239 -0
  17. package/skills/pikku-build-quick/SKILL.md +238 -0
  18. package/skills/pikku-cli/SKILL.md +7 -7
  19. package/skills/pikku-cli/references/complete-example.md +1 -1
  20. package/skills/pikku-concepts/SKILL.md +10 -7
  21. package/skills/pikku-concepts/references/concept-mapping.md +1 -1
  22. package/skills/pikku-config/SKILL.md +5 -3
  23. package/skills/pikku-deploy-azure/SKILL.md +5 -4
  24. package/skills/pikku-deploy-cloudflare/SKILL.md +9 -9
  25. package/skills/pikku-deploy-uws/SKILL.md +5 -2
  26. package/skills/pikku-deps/SKILL.md +42 -3
  27. package/skills/pikku-emails/SKILL.md +5 -5
  28. package/skills/pikku-fabric/SKILL.md +27 -3
  29. package/skills/pikku-fabric-debug/SKILL.md +1 -1
  30. package/skills/pikku-feature/SKILL.md +5 -4
  31. package/skills/pikku-http/SKILL.md +4 -4
  32. package/skills/pikku-http/references/http-options.md +13 -13
  33. package/skills/pikku-i18n/SKILL.md +2 -1
  34. package/skills/pikku-info/SKILL.md +1 -1
  35. package/skills/pikku-knowledge/SKILL.md +13 -13
  36. package/skills/pikku-kysely/SKILL.md +68 -41
  37. package/skills/pikku-machine-auth/SKILL.md +10 -10
  38. package/skills/pikku-mcp/SKILL.md +23 -20
  39. package/skills/pikku-middleware/SKILL.md +19 -12
  40. package/skills/pikku-middleware/references/middleware-patterns.md +14 -8
  41. package/skills/pikku-mongodb/SKILL.md +11 -11
  42. package/skills/pikku-n8n-import/SKILL.md +12 -12
  43. package/skills/pikku-n8n-import/SPEC.md +3 -0
  44. package/skills/pikku-n8n-import/references/addon-mapping.md +14 -8
  45. package/skills/pikku-n8n-import/references/code-translation.md +26 -22
  46. package/skills/pikku-n8n-import/references/loops-and-control.md +7 -7
  47. package/skills/pikku-paraglide/SKILL.md +11 -6
  48. package/skills/pikku-permissions/SKILL.md +19 -15
  49. package/skills/pikku-product-second-opinion/README.md +3 -3
  50. package/skills/pikku-product-second-opinion/SKILL.md +83 -73
  51. package/skills/pikku-product-second-opinion/example/sample-report.md +15 -12
  52. package/skills/pikku-product-second-opinion/references/report-template.md +10 -7
  53. package/skills/pikku-queue/SKILL.md +1 -1
  54. package/skills/pikku-react/SKILL.md +53 -13
  55. package/skills/pikku-realtime/SKILL.md +51 -19
  56. package/skills/pikku-rpc/SKILL.md +1 -1
  57. package/skills/pikku-rtl/SKILL.md +1 -1
  58. package/skills/pikku-scenario/SKILL.md +164 -44
  59. package/skills/pikku-schedule/SKILL.md +6 -1
  60. package/skills/pikku-schema-ajv/SKILL.md +2 -2
  61. package/skills/pikku-schema-cfworker/SKILL.md +1 -1
  62. package/skills/pikku-security/SKILL.md +9 -5
  63. package/skills/pikku-services/SKILL.md +27 -18
  64. package/skills/pikku-services/references/audit-wire-service.md +14 -8
  65. package/skills/pikku-software-archaeology/SKILL.md +27 -23
  66. package/skills/pikku-software-archaeology/references/blueprint.schema.json +580 -102
  67. package/skills/pikku-software-archaeology/scripts/validate.mjs +146 -69
  68. package/skills/pikku-tag-middleware/SKILL.md +1 -0
  69. package/skills/pikku-template-clone/SKILL.md +2 -1
  70. package/skills/pikku-trigger/SKILL.md +3 -3
  71. package/skills/pikku-versioning/SKILL.md +87 -3
  72. package/skills/pikku-websocket/SKILL.md +4 -3
  73. package/skills/pikku-workflow/SKILL.md +2 -2
  74. package/skills/pikku-workflow/references/workflow-reference.md +24 -10
  75. package/skills/pikku-ws/SKILL.md +5 -2
@@ -9,13 +9,15 @@ Pair with `createAuditedKysely` to auto-capture every Kysely query as an audit e
9
9
  import { createInvocationAudit } from '@pikku/core/services'
10
10
  import { createAuditedKysely } from '@pikku/kysely'
11
11
 
12
- export const createWireServices = pikkuWireServices(async (singletonServices, wire) => {
13
- const audit = createInvocationAudit(singletonServices.audit, wire)
14
- const kysely = singletonServices.kysely
15
- ? createAuditedKysely(singletonServices.kysely, { audit })
16
- : undefined
17
- return { audit, ...(kysely ? { kysely } : {}) }
18
- })
12
+ export const createWireServices = pikkuWireServices(
13
+ async (singletonServices, wire) => {
14
+ const audit = createInvocationAudit(singletonServices.audit, wire)
15
+ const kysely = singletonServices.kysely
16
+ ? createAuditedKysely(singletonServices.kysely, { audit })
17
+ : undefined
18
+ return { audit, ...(kysely ? { kysely } : {}) }
19
+ }
20
+ )
19
21
  ```
20
22
 
21
23
  The `audit` wire service is typed as `AuditLog` (from `@pikku/core`). Functions that emit custom events use it directly:
@@ -24,7 +26,11 @@ The `audit` wire service is typed as `AuditLog` (from `@pikku/core`). Functions
24
26
  const deleteUser = pikkuFunc({
25
27
  func: async ({ audit }, { userId }) => {
26
28
  // The user identity comes from the wire session — the payload is metadata.
27
- await audit.write({ type: 'user.deleted', source: 'explicit', metadata: { userId } })
29
+ await audit.write({
30
+ type: 'user.deleted',
31
+ source: 'explicit',
32
+ metadata: { userId },
33
+ })
28
34
  // ...
29
35
  },
30
36
  })
@@ -13,6 +13,7 @@ Extract **intent over implementation**. A repository is a fossil record of produ
13
13
  **You are the parser.** Do not build or rely on regex/AST scanners — read the code with your own tools (Grep, Read, subagents). This is what makes the skill language-agnostic: an Express app, a Rails app, and a Django app all yield the same blueprint shape.
14
14
 
15
15
  **Two layers, never merged silently:**
16
+
16
17
  - **Facts** — behavior directly observed in code, schema, or tests. Cite them.
17
18
  - **Inferred intent** — the product reasoning you reconstruct. Mark it with `confidence` and say what evidence it rests on.
18
19
 
@@ -64,6 +65,7 @@ Work in phases. For small repos (< ~50 source files) do them inline; for larger
64
65
  ### Phase 1 — Survey (facts only)
65
66
 
66
67
  Build an inventory before interpreting anything:
68
+
67
69
  - Manifests (`package.json`, `Gemfile`, `pyproject.toml`, `go.mod`, `composer.json`): dependencies are integration hints; scripts are entry points.
68
70
  - Entry points: servers, route registrations, cron/scheduler setup, queue workers, CLI binaries.
69
71
  - Data layer: migrations, schema files, model classes, raw DDL (check comments too — schemas hide in comments in migration-less repos).
@@ -75,18 +77,19 @@ Build an inventory before interpreting anything:
75
77
 
76
78
  Where intent hides, per ecosystem (read these first):
77
79
 
78
- | Ecosystem | Highest-yield locations |
79
- |---|---|
80
- | Rails | `config/routes.rb`, model validations + callbacks + `aasm`/state machines, `app/policies` (Pundit) / `ability.rb` (CanCan), Sidekiq/ActiveJob workers, `db/schema.rb`, specs (esp. request + model specs) |
81
- | Express/Node | route registration files, middleware chains (auth!), inline `if` guards in handlers, SQL/ORM models, `jobs/`+crontab refs, webhook handlers |
82
- | Django | `urls.py`, model `Meta`/constraints/`clean()`, DRF serializers + permissions classes, celery tasks, admin.py (reveals internal workflows) |
83
- | Laravel | `routes/`, FormRequests (validation), Policies/Gates, Jobs + scheduler in `Kernel.php`, migrations |
84
- | Go | mux/router setup, middleware, struct tags, `cmd/` binaries (each is a component) |
80
+ | Ecosystem | Highest-yield locations |
81
+ | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
82
+ | Rails | `config/routes.rb`, model validations + callbacks + `aasm`/state machines, `app/policies` (Pundit) / `ability.rb` (CanCan), Sidekiq/ActiveJob workers, `db/schema.rb`, specs (esp. request + model specs) |
83
+ | Express/Node | route registration files, middleware chains (auth!), inline `if` guards in handlers, SQL/ORM models, `jobs/`+crontab refs, webhook handlers |
84
+ | Django | `urls.py`, model `Meta`/constraints/`clean()`, DRF serializers + permissions classes, celery tasks, admin.py (reveals internal workflows) |
85
+ | Laravel | `routes/`, FormRequests (validation), Policies/Gates, Jobs + scheduler in `Kernel.php`, migrations |
86
+ | Go | mux/router setup, middleware, struct tags, `cmd/` binaries (each is a component) |
85
87
  | Frontend (React/Vue/etc.) | router config / file-based routes (pages a user reaches), the component tree, the design-system import (`@mantine/*`, `@mui/*`, Tailwind config) to judge consistency, the data layer (react-query/tRPC/fetch wrappers) to tie UI back to backend queries, charts/tables/editors (the `custom-logic` port risk), auth wiring |
86
88
 
87
89
  ### Phase 2 — Test excavation (do not skip)
88
90
 
89
91
  Tests are the closest thing to an executable product spec. For every test file:
92
+
90
93
  - `describe`/`context`/`it` names → **scenarios** (attach to the matching workflow in `workflows.json` under `scenarios[]`, with `fromTest` set).
91
94
  - User-flow/journey harnesses (`pikkuUserFlow` stories, cucumber `.feature` files, Playwright journeys) are the highest-grade scenario source — they already ARE given/when/outcome sequences; extract them verbatim.
92
95
  - Assertions → confirmations of policies and invariants (upgrade their `confidence` to `high`, add the test as evidence).
@@ -126,14 +129,15 @@ Run each lens over the surveyed material. Rules that counter the classic failure
126
129
 
127
130
  **Migration** — map current file clusters → future domain + concepts; list files to drop with reasons; list decisions a human must make before rebuild.
128
131
 
129
- **Interfaces** (`interfaces.json`, optional) — every way the product is CONSUMED, one entry per channel, not per route. A product is usually driven through several: a **web UI** (humans), a **CLI** (developers/operators), an **MCP server** (AI agents — in a Pikku app each MCP tool IS a `pikkuFunc`), an **OpenAPI/REST** surface (developers/external systems, often *generated* from the routes), a **generated SDK**, **realtime** (websocket/SSE), and **webhooks** (in/out). For each: `kind`, `audience`, `purpose`, roughly how many ops it exposes, whether it's `generated` vs hand-written, which domains it serves, and `status` (complete/partial/stub — an MCP server with two tools is `stub`). This layer answers "who can drive this, and how" — it is the map the second-opinion skill needs to explain that the app is usable by people, developers, and agents.
132
+ **Interfaces** (`interfaces.json`, optional) — every way the product is CONSUMED, one entry per channel, not per route. A product is usually driven through several: a **web UI** (humans), a **CLI** (developers/operators), an **MCP server** (AI agents — in a Pikku app each MCP tool IS a `pikkuFunc`), an **OpenAPI/REST** surface (developers/external systems, often _generated_ from the routes), a **generated SDK**, **realtime** (websocket/SSE), and **webhooks** (in/out). For each: `kind`, `audience`, `purpose`, roughly how many ops it exposes, whether it's `generated` vs hand-written, which domains it serves, and `status` (complete/partial/stub — an MCP server with two tools is `stub`). This layer answers "who can drive this, and how" — it is the map the second-opinion skill needs to explain that the app is usable by people, developers, and agents.
130
133
 
131
134
  **Frontend** (`frontend.json` + `frontend-routes.json` + `frontend-components.json`, optional) — the web UI, which needs its own treatment because frontends vary wildly (framework, router, styling, state, data, auth) and the rebuild target is opinionated: **everything in one component system (Mantine), one data layer, one auth**.
135
+
132
136
  - `frontend.json` records the stack as FACTS: framework (e.g. TanStack Start), rendering (SSR/streaming/SPA), router, styling/design system, `designSystemConsistency`, state management, data layer (e.g. pikku-react-query vs REST helpers), auth (e.g. better-auth), i18n. Name the real technologies — the second-opinion skill weighs their tradeoffs, so record them precisely (do NOT editorialize here; this file is facts).
133
137
  - `frontend-routes.json` is the page tree: each route's `purpose` in product terms, `auth`, the `dataFrom` (query/command names it reads — reuse the backend concept names so the UI ties back to the domain), the `usesComponents`, and the `userFlows` it belongs to.
134
- - `frontend.json.designFindings` captures **broken/inconsistent design patterns** as concrete, cited observations (not taste). Actively hunt for: *interaction inconsistency* (the same job done as a modal in one place and a drawer in another; inconsistent confirm dialogs); *theming not tokenized* (hardcoded hex colors, magic spacing/font sizes, inline styles instead of theme tokens/variables — grep for `#[0-9a-f]{3,6}`, `style={{`, raw `px` values); *cross-page inconsistency* (the same element — button, page header, card — styled differently across routes); *component duplication* (three near-identical cards/tables for one purpose); *design-system bypass* (raw HTML/CSS where a library component exists). Each finding gets an example, its impact (feels unpolished / a color change means hunting every file), and a fix (standardize on one pattern / move to tokens / extract one shared component). These are almost always cheap cleanups, and they are exactly what a non-technical owner perceives as "the app looks off" without being able to say why.
138
+ - `frontend.json.designFindings` captures **broken/inconsistent design patterns** as concrete, cited observations (not taste). Actively hunt for: _interaction inconsistency_ (the same job done as a modal in one place and a drawer in another; inconsistent confirm dialogs); _theming not tokenized_ (hardcoded hex colors, magic spacing/font sizes, inline styles instead of theme tokens/variables — grep for `#[0-9a-f]{3,6}`, `style={{`, raw `px` values); _cross-page inconsistency_ (the same element — button, page header, card — styled differently across routes); _component duplication_ (three near-identical cards/tables for one purpose); _design-system bypass_ (raw HTML/CSS where a library component exists). Each finding gets an example, its impact (feels unpolished / a color change means hunting every file), and a fix (standardize on one pattern / move to tokens / extract one shared component). These are almost always cheap cleanups, and they are exactly what a non-technical owner perceives as "the app looks off" without being able to say why.
135
139
  - `frontend-components.json` is where the frontend's real migration cost lives, in the **`rebuild`** field: `mantine-standard` (maps 1:1 to a Mantine component — trivial), `mantine-composition` (built from Mantine primitives — straightforward), `custom-style` (diverges only visually — normalize to Mantine), or **`custom-logic`** (bespoke behavior — a custom chart, a virtualized/complex table, a canvas, drag-and-drop, a rich editor — that must be **ported**, not re-skinned). A `custom-logic` component MUST fill `customLogic` explaining the behavior, and should list the `dependencies` (charting/table/editor libs) that make it a real port. This split — "trivially re-Mantine-able" vs "carries logic that must survive the port" — is the single most useful thing the frontend extraction produces.
136
- - **Server-rendered / non-React frontends still get all three files — do NOT skip them.** The `rebuild` enum is named for the target stack, but the distinction it draws is target-agnostic: *trivial stock element* vs *composed from primitives* vs *visual divergence only* vs **bespoke behavior that must be ported**. A Rails app (Slim/ERB + ViewComponents + Hotwire/Stimulus), a Django app (templates + HTMX), or a Laravel app (Blade + Livewire) all have that same split, and it is just as load-bearing there. Use the enum values verbatim (the validator enforces them), classify by what the thing actually *does*, and record the vocabulary mismatch in `frontend.json.notes`. Concretely: treat a template partial + its behavior controller (Stimulus/Alpine/Livewire) as ONE component and classify the pair; a server-rendered app's `custom-logic` is the same list as a SPA's (maps, charts, video players, payment elements, drag-to-reorder, rich text, QR, live-updating regions), plus anything whose behavior rides on a streaming/partial-update contract (Turbo Streams, HTMX swaps) — get that mapping wrong on rebuild and pages show stale data. Omitting these files because "it isn't a React app" hides the frontend's entire migration cost, which is the one thing this file exists to expose.
140
+ - **Server-rendered / non-React frontends still get all three files — do NOT skip them.** The `rebuild` enum is named for the target stack, but the distinction it draws is target-agnostic: _trivial stock element_ vs _composed from primitives_ vs _visual divergence only_ vs **bespoke behavior that must be ported**. A Rails app (Slim/ERB + ViewComponents + Hotwire/Stimulus), a Django app (templates + HTMX), or a Laravel app (Blade + Livewire) all have that same split, and it is just as load-bearing there. Use the enum values verbatim (the validator enforces them), classify by what the thing actually _does_, and record the vocabulary mismatch in `frontend.json.notes`. Concretely: treat a template partial + its behavior controller (Stimulus/Alpine/Livewire) as ONE component and classify the pair; a server-rendered app's `custom-logic` is the same list as a SPA's (maps, charts, video players, payment elements, drag-to-reorder, rich text, QR, live-updating regions), plus anything whose behavior rides on a streaming/partial-update contract (Turbo Streams, HTMX swaps) — get that mapping wrong on rebuild and pages show stale data. Omitting these files because "it isn't a React app" hides the frontend's entire migration cost, which is the one thing this file exists to expose.
137
141
  - The `designFindings` grep hints above are React-flavored; the server-rendered equivalents are inline `style=` attributes in templates, hardcoded hex in the stylesheet tree, per-locale forked templates instead of i18n, and design-system bypass = raw markup where a component/partial already exists. Same findings, different needles.
138
142
 
139
143
  ### Phase 4 — Cross-check, validate, synthesize
@@ -148,7 +152,7 @@ Run each lens over the surveyed material. Rules that counter the classic failure
148
152
  - `high` — the behavior itself is in the cited code/schema/test.
149
153
  - `medium` — inferred from multiple converging signals (naming + partial code + a test name).
150
154
  - `low` — plausible reconstruction; MUST also be phrased tentatively in blueprint.md and usually deserves a `decisionsNeeded` entry.
151
- - Comments and docs describe *intended* behavior; code describes *actual* behavior. When they disagree, record the code's behavior as the fact and the disagreement as a gap.
155
+ - Comments and docs describe _intended_ behavior; code describes _actual_ behavior. When they disagree, record the code's behavior as the fact and the disagreement as a gap.
152
156
 
153
157
  ## Scaling up (large repos)
154
158
 
@@ -160,18 +164,18 @@ Run each lens over the surveyed material. Rules that counter the classic failure
160
164
 
161
165
  ## Red Flags — you are about to produce a worthless blueprint
162
166
 
163
- | Thought | Reality |
164
- |---|---|
165
- | "I'll write it up as markdown docs" | Only `blueprint.md` is prose. The 14 JSON files ARE the deliverable; a generator consumes them. |
166
- | "The routes are the API contract" | Routes are evidence. Lift each to a command/query or you've documented plumbing, not product. |
167
- | "This is obvious, no citation needed" | Uncited claims are indistinguishable from hallucinations. Evidence on everything. |
168
- | "The folder structure tells me the domains" | Folders are how it grew, not what it is. Derive domains from ownership + vocabulary. |
169
- | "Tests are just tests, skip them" | Tests are the spec. Some rules exist ONLY in tests. Phase 2 is mandatory. |
170
- | "No events are emitted, so events: []" | Reconstruct implicit events from side-effect clusters; mark `explicit: false`. |
171
- | "Cron jobs aren't workflows" | System workflows are workflows. Include schedules, queue consumers, webhook reactions. |
172
- | "The frontend is just the web routes" | The web UI is ONE interface. Inventory the CLI, MCP server, OpenAPI/SDK, realtime, webhooks in `interfaces.json` too — the product is driven by people, developers, AND agents. |
173
- | "A component list is enough" | Without the `rebuild` split, you've hidden the frontend's real cost. Flag every `custom-logic` component (chart/table/canvas/editor) and say what the logic is — that's the port work. |
174
- | "I'll skip the validator, the JSON looks right" | Run it. Missing domains refs, dangling event names, and undescribed custom-logic components are exactly what it catches. |
167
+ | Thought | Reality |
168
+ | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
169
+ | "I'll write it up as markdown docs" | Only `blueprint.md` is prose. The 14 JSON files ARE the deliverable; a generator consumes them. |
170
+ | "The routes are the API contract" | Routes are evidence. Lift each to a command/query or you've documented plumbing, not product. |
171
+ | "This is obvious, no citation needed" | Uncited claims are indistinguishable from hallucinations. Evidence on everything. |
172
+ | "The folder structure tells me the domains" | Folders are how it grew, not what it is. Derive domains from ownership + vocabulary. |
173
+ | "Tests are just tests, skip them" | Tests are the spec. Some rules exist ONLY in tests. Phase 2 is mandatory. |
174
+ | "No events are emitted, so events: []" | Reconstruct implicit events from side-effect clusters; mark `explicit: false`. |
175
+ | "Cron jobs aren't workflows" | System workflows are workflows. Include schedules, queue consumers, webhook reactions. |
176
+ | "The frontend is just the web routes" | The web UI is ONE interface. Inventory the CLI, MCP server, OpenAPI/SDK, realtime, webhooks in `interfaces.json` too — the product is driven by people, developers, AND agents. |
177
+ | "A component list is enough" | Without the `rebuild` split, you've hidden the frontend's real cost. Flag every `custom-logic` component (chart/table/canvas/editor) and say what the logic is — that's the port work. |
178
+ | "I'll skip the validator, the JSON looks right" | Run it. Missing domains refs, dangling event names, and undescribed custom-logic components are exactly what it catches. |
175
179
 
176
180
  ## Quick Reference
177
181