@pikku/skills 0.12.60 → 0.12.61
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/package.json
CHANGED
|
@@ -49,7 +49,7 @@ wireAddon({
|
|
|
49
49
|
rpcEndpoint?: string, // Optional remote RPC endpoint for distributed execution
|
|
50
50
|
auth?: boolean, // Require a session for every function in the addon
|
|
51
51
|
mcp?: boolean | string[], // true: every function the addon declared mcp: true; a list: the tools this app offers, typed against the addon's function names
|
|
52
|
-
expose?: boolean | string[], // what rpc.exposed / POST /rpc may reach
|
|
52
|
+
expose?: boolean | string[], // opt-in: what rpc.exposed / POST /rpc may reach. true = every function the addon declared expose: true, a list = those of them named (typed; PKU343 on unknown or undeclared names), unset/false = none
|
|
53
53
|
tags?: string[], // Tags applied to all addon functions
|
|
54
54
|
scopes?: string[], // Required of every function, on top of its own
|
|
55
55
|
secretOverrides?: Record<string, string>, // Remap secret names (and grant them)
|
|
@@ -279,6 +279,45 @@ everything else. Leave it out and the addon installs fine and fails to typecheck
|
|
|
279
279
|
in every app that depends on it, which is what `pikku validate` is there to
|
|
280
280
|
catch before you publish.
|
|
281
281
|
|
|
282
|
+
### Remote functions and the SDK
|
|
283
|
+
|
|
284
|
+
A `remote: true` function is called over the wire by apps that use
|
|
285
|
+
`wireRemoteAddon`. Those apps build against the addon's SDK, not its source, so
|
|
286
|
+
**a remote function's input and output must be exported zod schemas**. If it
|
|
287
|
+
uses generics (`pikkuSessionlessFunc<In, Out>`) or returns a type declared in
|
|
288
|
+
`src/`, codegen fails with PKU922. Functions that are not remote can keep their
|
|
289
|
+
generics.
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
// src/functions/listNotes.schemas.ts
|
|
293
|
+
import { z } from 'zod'
|
|
294
|
+
|
|
295
|
+
export const NoteRows = z.array(z.object({ id: z.string(), body: z.string() }))
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// src/functions/listNotes.function.ts
|
|
300
|
+
import { pikkuSessionlessFunc } from '#pikku/addon/function'
|
|
301
|
+
import { NoteRows } from './listNotes.schemas.js'
|
|
302
|
+
|
|
303
|
+
export const listNotes = pikkuSessionlessFunc({
|
|
304
|
+
output: NoteRows,
|
|
305
|
+
func: async ({ kysely }) =>
|
|
306
|
+
kysely.selectFrom('notes').select(['id', 'body']).execute(),
|
|
307
|
+
remote: true,
|
|
308
|
+
})
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
yarn pikku all # also writes .pikku/sdk/ + <scope>-<name>-<version>.sdk.tgz
|
|
313
|
+
yarn pikku versions check # fails on a remote contract changed without a new version
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
In an addon, `pikku all` packs the SDK on every run, at the package.json
|
|
317
|
+
version. The SDK carries only the remote RPCs, the `expose: true` workflows and
|
|
318
|
+
the types they reach. Changing a published `remote: true` contract needs a new
|
|
319
|
+
`version` on the function, which `pikku versions check` enforces.
|
|
320
|
+
|
|
282
321
|
### Database tables
|
|
283
322
|
|
|
284
323
|
An addon may **ship** tables. It must never **create** them: it runs inside the
|
|
@@ -361,6 +400,13 @@ covered, and writes only the delta after an addon upgrade. An addon wired with
|
|
|
361
400
|
`wireRemoteAddon` contributes no schema at all: its tables belong to the
|
|
362
401
|
deployment that runs its functions.
|
|
363
402
|
|
|
403
|
+
A `wireRemoteAddon` whose `package` carries a range (`'@scope/name@^1.4.0'`)
|
|
404
|
+
is not installed at all: `pikku all` downloads its SDK into
|
|
405
|
+
`.pikku/remote` and pins it in `pikku-addons.lock` (commit the lock). If
|
|
406
|
+
codegen reports PKU338 for one, run `pikku all`, not an install; to move
|
|
407
|
+
to a newer SDK, edit the range by hand (`pikku update` prints the file:line
|
|
408
|
+
and the new literal; it never rewrites source), then run `pikku all`.
|
|
409
|
+
|
|
364
410
|
### Call via RPC
|
|
365
411
|
|
|
366
412
|
```typescript
|
|
@@ -381,9 +427,10 @@ and the frontend calls `rpc.invoke('todos:listTodos', …)` (over HTTP,
|
|
|
381
427
|
Use `ref('todos:listTodos')` on an HTTP or MCP wiring only when the addon needs
|
|
382
428
|
a route of its own. Don't write an app function that calls `rpc.invoke` and
|
|
383
429
|
returns the result unchanged: it's a second name and a second schema for the
|
|
384
|
-
same thing, and it drifts.
|
|
385
|
-
|
|
386
|
-
|
|
430
|
+
same thing, and it drifts. Nothing in an addon is reachable over `/rpc` until
|
|
431
|
+
the wiring opts in, and it can only open what the addon itself declared
|
|
432
|
+
`expose: true` — an OpenAPI-generated addon declares every operation, so list
|
|
433
|
+
the ones the frontend needs.
|
|
387
434
|
|
|
388
435
|
Write your own function when the app needs the data narrowed, typed, or
|
|
389
436
|
combined (a flag the upstream sends as `"0"`, a total summed from several
|
|
@@ -60,7 +60,7 @@ Most surfaces are switched on by the CLI rather than hand-wired:
|
|
|
60
60
|
bunx --bun pikku enable workflow # workflow workers
|
|
61
61
|
bunx --bun pikku enable agent # public agent endpoints
|
|
62
62
|
bunx --bun pikku enable events # realtime events channel + SSE stream
|
|
63
|
-
bunx --bun pikku enable
|
|
63
|
+
bunx --bun pikku enable mesh-rpc # mesh RPC queue worker + HTTP endpoint
|
|
64
64
|
bunx --bun pikku enable webhook # outgoing webhook delivery queue worker
|
|
65
65
|
bunx --bun pikku enable scenarios # scenario instrumentation
|
|
66
66
|
bunx --bun pikku enable rpc # public RPC endpoint
|
|
@@ -74,7 +74,7 @@ builds anyway (`config`, `logger`, `variables`, `schema`, `secrets`, and the
|
|
|
74
74
|
per-request `rpc`/`mcp`/`channel`/`userSession`). Units are named for that set —
|
|
75
75
|
`svc-todo-store`, `svc-event-hub-todo-store`, `svc-base` for functions needing
|
|
76
76
|
nothing else — and each records it as `servicesKey` in the manifest. On the
|
|
77
|
-
`
|
|
77
|
+
`recipes/functions` app it turns 44 units into 10.
|
|
78
78
|
|
|
79
79
|
The deploy target is part of the key, so a `server` unit is named `-server` and
|
|
80
80
|
can never merge with its serverless twin. That is what keeps `services` from
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
| Method | Purpose |
|
|
14
14
|
| -------------------------------- | ----------------------------------------- |
|
|
15
15
|
| `rpc.invoke(name, data)` | Internal call to any wired function |
|
|
16
|
-
| `rpc.
|
|
16
|
+
| `rpc.mesh(name, data)` | Mesh call via DeploymentService |
|
|
17
17
|
| `rpc.exposed(name, data)` | Call functions marked with `expose: true` |
|
|
18
18
|
| `rpc.startWorkflow(name, input)` | Start a workflow (see `pikku-workflow`) |
|
|
19
19
|
| `rpc.agent.run/stream(...)` | Run an AI agent (see `pikku-agent`) |
|
|
20
20
|
| `rpc.agent.resume/approve(...)` | Answer a tool-approval interrupt |
|
|
21
21
|
| `rpc.agent.interrupt(runId)` | Stop an in-flight run |
|
|
22
22
|
|
|
23
|
-
`rpc.invoke`, `rpc.
|
|
23
|
+
`rpc.invoke`, `rpc.mesh` and `rpc.startWorkflow` are typed off the generated
|
|
24
24
|
RPC map, so the name and the payload are checked. `rpc.exposed` is deliberately
|
|
25
25
|
`(name: string, data: any) => Promise<any>` — it exists to dispatch a name that
|
|
26
26
|
arrived from outside, which by definition cannot be checked at compile time.
|