@pikku/skills 0.12.34 → 0.12.37
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 +9 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +9 -5
- package/dist/skills.gen.d.ts +1 -0
- package/dist/skills.gen.js +5 -3
- package/dist/snippets.d.ts +26 -0
- package/dist/snippets.js +148 -0
- package/package.json +2 -2
- package/skills/pikku-addon/SKILL.md +41 -30
- package/skills/pikku-addon/references/addon-package-manifest.md +9 -4
- package/skills/pikku-addon/references/openapi.md +99 -0
- package/skills/pikku-agent/references/agents.md +3 -1
- package/skills/pikku-architect/SKILL.md +12 -0
- package/skills/pikku-auth/references/better-auth.md +16 -0
- package/skills/pikku-build/SKILL.md +29 -0
- package/skills/pikku-build/references/app.md +52 -4
- package/skills/pikku-build/references/feature.md +23 -96
- package/skills/pikku-build/references/quick.md +12 -3
- package/skills/pikku-changes/SKILL.md +172 -0
- package/skills/pikku-concepts/SKILL.md +33 -138
- package/skills/pikku-concepts/references/bootstrap.md +58 -0
- package/skills/pikku-concepts/references/concept-mapping.md +16 -0
- package/skills/pikku-concepts/references/language.md +87 -0
- package/skills/pikku-deploy/SKILL.md +1 -1
- package/skills/pikku-fabric/SKILL.md +26 -13
- package/skills/pikku-guide/SKILL.md +264 -0
- package/skills/pikku-knowledge/SKILL.md +10 -0
- package/skills/pikku-kysely/SKILL.md +1 -1
- package/skills/pikku-mantine/SKILL.md +80 -0
- package/skills/pikku-n8n-import/SKILL.md +4 -3
- package/skills/pikku-react/references/client.md +12 -0
- package/skills/pikku-realtime/SKILL.md +6 -6
- package/skills/pikku-report/SKILL.md +143 -0
- package/skills/pikku-scenario/SKILL.md +71 -563
- package/skills/pikku-scenario/references/browser.md +59 -0
- package/skills/pikku-scenario/references/coverage.md +70 -0
- package/skills/pikku-scenario/references/personas.md +87 -0
- package/skills/pikku-scenario/references/steps.md +366 -0
- package/skills/pikku-service-backends/SKILL.md +1 -1
- package/skills/pikku-wiring/SKILL.md +1 -1
- package/skills/pikku-wiring/references/http.md +8 -0
- package/skills/pikku-wiring/references/mcp.md +59 -0
- package/skills/pikku-workflow/SKILL.md +7 -8
|
@@ -186,6 +186,63 @@ When you add a tool, tell whoever asked for it the URL. An assistant that cannot
|
|
|
186
186
|
be pointed at an endpoint has not been connected to anything, and `/mcp` is the
|
|
187
187
|
whole answer.
|
|
188
188
|
|
|
189
|
+
## Authentication
|
|
190
|
+
|
|
191
|
+
An MCP endpoint is not gated as a whole. Pikku already knows, tool by tool, which
|
|
192
|
+
calls need a session, and the endpoint answers accordingly:
|
|
193
|
+
|
|
194
|
+
| Declaration | Anonymous call |
|
|
195
|
+
| ---------------------------------------- | ------------------- |
|
|
196
|
+
| `pikkuSessionlessFunc` with `mcp: true` | runs |
|
|
197
|
+
| the same, plus `auth: true` | `401` + a challenge |
|
|
198
|
+
| `pikkuFunc` with `mcp: true` | `401` + a challenge |
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// public: anyone connecting to /mcp can call this
|
|
202
|
+
export const searchCatalog = pikkuSessionlessFunc<Query, Results>({
|
|
203
|
+
mcp: true,
|
|
204
|
+
func: async (services, data) => services.catalog.search(data),
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
// private: an anonymous caller is challenged, never dispatched
|
|
208
|
+
export const myOrders = pikkuFunc<void, Order[]>({
|
|
209
|
+
mcp: true,
|
|
210
|
+
func: async (services, _data, session) =>
|
|
211
|
+
services.orders.forUser(session.userId),
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The `401` carries a `WWW-Authenticate` header naming the endpoint's RFC 9728
|
|
216
|
+
Protected Resource Metadata document, which the server also serves — `/mcp` is
|
|
217
|
+
described at `/.well-known/oauth-protected-resource/mcp`. That pair is what an
|
|
218
|
+
MCP client needs to discover an authorization server and start an OAuth flow;
|
|
219
|
+
a refusal delivered as a JSON-RPC result instead reads to a client as a tool that
|
|
220
|
+
failed, and no discovery happens.
|
|
221
|
+
|
|
222
|
+
`tools/list` is never gated, so a client can still see what exists before it has
|
|
223
|
+
a token.
|
|
224
|
+
|
|
225
|
+
Nothing needs configuring: the metadata document defaults to advertising the
|
|
226
|
+
origin the request arrived on, which is right whenever the app is its own
|
|
227
|
+
authorization server. To point elsewhere, pass `mcpAuth` to the runtime:
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
new PikkuNodeHTTPServer(config, logger, {
|
|
231
|
+
mcpJson,
|
|
232
|
+
mcpAuth: {
|
|
233
|
+
authorizationServers: ['https://auth.example.com'],
|
|
234
|
+
scopesSupported: ['mcp'],
|
|
235
|
+
resourceName: 'Example API',
|
|
236
|
+
},
|
|
237
|
+
})
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The transport never verifies a token itself — session resolution stays with the
|
|
241
|
+
app's own middleware, exactly as it works over HTTP. One consequence: only a
|
|
242
|
+
request carrying *no* credentials is challenged. A token that is present but
|
|
243
|
+
expired is dispatched, and the runner's refusal reaches the client as a tool
|
|
244
|
+
error.
|
|
245
|
+
|
|
189
246
|
## Red flags
|
|
190
247
|
|
|
191
248
|
| Symptom | Cause |
|
|
@@ -195,3 +252,5 @@ whole answer.
|
|
|
195
252
|
| Resource returning `{ uri, blob, mimeType }` | Resources are text only: `{ uri, text }` |
|
|
196
253
|
| Client sees a tool with no description | `mcp: true` without a `description` — check the codegen warning |
|
|
197
254
|
| `/mcp` 404s | Nothing to serve yet — the mount is skipped until one tool, resource or prompt exists |
|
|
255
|
+
| A tool an assistant should be able to call returns `401` | It is a `pikkuFunc`, or declares `auth: true` — make it a `pikkuSessionlessFunc` if it is genuinely public |
|
|
256
|
+
| A private tool returns a result rather than a challenge | The request carried a credential, so it was dispatched; only a call with none is refused at the door |
|
|
@@ -16,12 +16,12 @@ installGroups: [core]
|
|
|
16
16
|
|
|
17
17
|
Use this skill as an execution checklist, not reference material.
|
|
18
18
|
|
|
19
|
-
1. Capture baseline. Run `pikku
|
|
20
|
-
2. Discover before editing. Prefer `pikku
|
|
19
|
+
1. Capture baseline. Run `pikku all` BEFORE writing code; note existing errors — only NEW errors are yours to fix.
|
|
20
|
+
2. Discover before editing. Prefer `pikku meta` / `pikku info functions --verbose` and `pikku info tags --verbose` to see functions usable as steps and project organization; inspect only the focused output you need.
|
|
21
21
|
3. Identify the source files that own the behavior. Do not start from generated output, `.pikku`, `node_modules`, vendored packages, or build artifacts.
|
|
22
22
|
4. Make the smallest source change. Keep generated files generated — never hand-edit SDKs, schema output, or typegen to paper over errors; fix the source cause.
|
|
23
|
-
5. Validate with the narrowest relevant command, then re-run `pikku
|
|
24
|
-
6.
|
|
23
|
+
5. Validate with the narrowest relevant command, then re-run `pikku all`. If only files you did not touch still error, those are pre-existing — leave them unless asked.
|
|
24
|
+
6. Only claim success when `pikku all` and `tsc` both pass (codegen AND type check green) — never after a partial pass.
|
|
25
25
|
|
|
26
26
|
See `pikku-concepts` for the core mental model.
|
|
27
27
|
|
|
@@ -33,7 +33,7 @@ The deciding question is: **does any part of this cross an external boundary tha
|
|
|
33
33
|
|
|
34
34
|
- **Checkout WITH payment → workflow.** Get cart → compute total → **(atomic: create order + order items, deduct stock, clear cart)** → **charge payment through the provider** → send confirmation email. It's a workflow because the payment leg (and the email) are external and must be **retried, not lost, and not charged twice** across a restart — and the user benefits from seeing where the run is.
|
|
35
35
|
- **Checkout with NO external payment** — e.g. it just records the order and decrements stock in one transaction, nothing leaves the process — is a **single-shot algorithm**: a plain `pikkuFunc` wrapping one `kysely.transaction`. Not a workflow. A workflow here would add durability machinery for a thing that already commits atomically in one shot.
|
|
36
|
-
- **One durable step is NOT a workflow — it's a queue worker.** A lone side-effect that must be retried / not lost (send one email, fire one webhook, one external charge) → a **queue worker** (`pikku-queue
|
|
36
|
+
- **One durable step is NOT a workflow — it's a queue worker.** A lone side-effect that must be retried / not lost (send one email, fire one webhook, one external charge) → a **queue worker** (see `pikku-wiring`'s queue reference), enqueued fire-and-forget. A workflow adds a step graph for a thing that has no steps to orchestrate. (A single non-durable step is just a direct RPC call.)
|
|
37
37
|
- Also workflows: onboarding sequences, settlements/payouts, digests and batch sends, anything that waits (`sleep`/`suspend`) or fans out with retries — the common thread is **multiple** steps or a durable wait, never a single step.
|
|
38
38
|
|
|
39
39
|
**HARD RULE — never a single-RPC (one-step) workflow.** A workflow whose body is one `workflow.do('x', 'someRpc', …)` is a mislabeled durable function, not orchestration. Route by durability, NOT into a workflow:
|
|
@@ -310,12 +310,11 @@ export const userOnboarding = pikkuWorkflowGraph({
|
|
|
310
310
|
|
|
311
311
|
## Step dispatch & HTTP wiring
|
|
312
312
|
|
|
313
|
-
For per-step inline-vs-queue dispatch (`workflowQueued: true` and the `dispatchStep` rules)
|
|
313
|
+
For per-step inline-vs-queue dispatch (`workflowQueued: true` and the `dispatchStep` rules) and a suspend/resume example, read `references/workflow-reference.md`.
|
|
314
314
|
|
|
315
315
|
## After writing
|
|
316
316
|
|
|
317
|
-
1. `pikku
|
|
317
|
+
1. `pikku all`, then `tsc --noEmit` (codegen + type check).
|
|
318
318
|
2. PKU641 → a `const`/`let` is inside a block; hoist it to the top of the function body.
|
|
319
319
|
3. Import errors → use `#pikku/workflow/pikku-workflow-types.gen.js`, not `#pikku`.
|
|
320
320
|
4. Type errors only in files you did not touch → pre-existing template errors; safe to ignore.
|
|
321
|
-
5. Both green → call `pikku-workflow-view` with the workflow name.
|