@pikku/cli 0.12.90 → 0.12.92
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/LICENSE +106 -0
- package/README.md +25 -2
- package/console-app/assets/{index-CSzCJzBb.css → index-D0HG8q0B.css} +1 -1
- package/console-app/assets/{index-C5Bd44e4.js → index-DDpIMCpy.js} +149 -149
- package/console-app/index.html +2 -2
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.js +6 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.json +15 -0
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +43 -0
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
- package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +4 -4
- package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +39 -44
- package/dist/.pikku/function/pikku-functions.gen.js +1 -3
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +9 -0
- package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +9 -0
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
- package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.d.ts +1 -0
- package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +10 -0
- package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.json +1 -0
- package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +4 -0
- package/dist/.pikku/scenarios/pikku-scenario-functions.gen.js +1 -0
- package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.d.ts +1 -0
- package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +10 -0
- package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +4 -0
- package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.js +1 -0
- package/dist/.pikku/scenarios/schemas/register.gen.d.ts +4 -0
- package/dist/.pikku/scenarios/schemas/register.gen.js +4 -0
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +5 -3
- package/dist/.pikku/schemas/schemas/FabricSecretsListOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricSecretsRotateInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricSecretsRotateOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricSecretsSetOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/ScenarioRunInput.schema.json +1 -1
- package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
- package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
- package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
- package/dist/.pikku/workflow/meta/allWorkflow.gen.json +2 -8
- package/dist/.pikku/workflow/pikku-scenario-actors.gen.d.ts +19 -0
- package/dist/.pikku/workflow/pikku-scenario-actors.gen.js +17 -0
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +152 -3
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +39 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
- package/dist/bin/pikku-bin.mjs +2 -2
- package/dist/src/cli.wiring.js +28 -0
- package/dist/src/deploy/analyzer/analyzer.js +22 -5
- package/dist/src/deploy/build-pipeline.js +5 -1
- package/dist/src/fabric/fabric-commands.d.ts +37 -9
- package/dist/src/fabric/fabric-commands.js +12 -0
- package/dist/src/fabric/functions/domains-add.function.d.ts +4 -4
- package/dist/src/fabric/functions/secrets-list.function.d.ts +16 -4
- package/dist/src/fabric/functions/secrets-list.function.js +12 -10
- package/dist/src/fabric/functions/secrets-rotate.function.d.ts +24 -0
- package/dist/src/fabric/functions/secrets-rotate.function.js +36 -0
- package/dist/src/fabric/functions/secrets-set.function.d.ts +8 -4
- package/dist/src/fabric/functions/secrets-set.function.js +18 -7
- package/dist/src/fabric/lib/http.d.ts +7 -1
- package/dist/src/fabric/lib/sealed-box.d.ts +16 -0
- package/dist/src/fabric/lib/sealed-box.js +72 -0
- package/dist/src/functions/commands/dev.js +11 -0
- package/dist/src/functions/commands/load-user-project.d.ts +7 -0
- package/dist/src/functions/commands/load-user-project.js +21 -0
- package/dist/src/functions/commands/pikku-command-bootstrap.js +13 -0
- package/dist/src/functions/commands/scenario-browser.d.ts +84 -0
- package/dist/src/functions/commands/scenario-browser.js +68 -0
- package/dist/src/functions/commands/scenario-environment.d.ts +32 -0
- package/dist/src/functions/commands/scenario-environment.js +61 -0
- package/dist/src/functions/commands/scenario-formatter.d.ts +81 -0
- package/dist/src/functions/commands/scenario-formatter.js +120 -0
- package/dist/src/functions/commands/scenario-ladder.d.ts +66 -0
- package/dist/src/functions/commands/scenario-ladder.js +132 -0
- package/dist/src/functions/commands/scenario-plan.d.ts +61 -0
- package/dist/src/functions/commands/scenario-plan.js +106 -0
- package/dist/src/functions/commands/scenario.d.ts +24 -0
- package/dist/src/functions/commands/scenario.js +322 -50
- package/dist/src/functions/commands/serve.js +2 -0
- package/dist/src/functions/commands/skills.js +27 -61
- package/dist/src/functions/db/db-codegen.d.ts +6 -0
- package/dist/src/functions/db/db-codegen.js +9 -0
- package/dist/src/functions/db/db-migrator.js +14 -0
- package/dist/src/functions/db/local-db.d.ts +8 -0
- package/dist/src/functions/db/local-db.js +24 -2
- package/dist/src/functions/db/migration-identifiers.d.ts +58 -0
- package/dist/src/functions/db/migration-identifiers.js +262 -0
- package/dist/src/functions/db/migration-provenance.d.ts +35 -0
- package/dist/src/functions/db/migration-provenance.js +80 -0
- package/dist/src/functions/db/schema-sql.d.ts +43 -0
- package/dist/src/functions/db/schema-sql.js +135 -0
- package/dist/src/functions/db/sqlite/sqlite-kysely.js +22 -2
- package/dist/src/functions/wirings/functions/pikku-command-functions.js +26 -8
- package/dist/src/functions/wirings/functions/schemas.js +13 -1
- package/dist/src/functions/wirings/functions/serialize-function-types.js +3 -3
- package/dist/src/functions/wirings/rpc/pikku-command-rpc.js +6 -1
- package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.d.ts +10 -0
- package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +102 -0
- package/dist/src/functions/wirings/scenarios/scenario-partition.d.ts +42 -0
- package/dist/src/functions/wirings/scenarios/scenario-partition.js +71 -0
- package/dist/src/functions/wirings/scenarios/scenario-schema-partition.d.ts +33 -0
- package/dist/src/functions/wirings/scenarios/scenario-schema-partition.js +49 -0
- package/dist/src/functions/wirings/scenarios/serialize-feature-meta.d.ts +14 -0
- package/dist/src/functions/wirings/scenarios/serialize-feature-meta.js +29 -0
- package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.d.ts +12 -0
- package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.js +56 -0
- package/dist/src/functions/wirings/scenarios/serialize-scenario-registration.d.ts +7 -0
- package/dist/src/functions/wirings/scenarios/serialize-scenario-registration.js +40 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +43 -8
- package/dist/src/functions/wirings/workflow/serialize-scenario-actors.d.ts +1 -1
- package/dist/src/functions/wirings/workflow/serialize-scenario-actors.js +13 -2
- package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.d.ts +4 -0
- package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.js +62 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-bootstrap-map.js +10 -3
- package/dist/src/functions/wirings/workflow/serialize-workflow-map.js +10 -3
- package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +4 -4
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.d.ts +1 -1
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +232 -3
- package/dist/src/functions/workflows/all.workflow.js +2 -7
- package/dist/src/server/server-ready.d.ts +12 -0
- package/dist/src/server/server-ready.js +12 -0
- package/dist/src/server/spawn-dev-server.d.ts +50 -0
- package/dist/src/server/spawn-dev-server.js +112 -0
- package/dist/src/services.js +12 -1
- package/dist/src/utils/file-writer.js +14 -2
- package/dist/src/utils/meta-diff.js +5 -2
- package/dist/src/utils/pikku-cli-config.d.ts +14 -0
- package/dist/src/utils/pikku-cli-config.js +60 -0
- package/dist/src/utils/remove-legacy-scaffold-file.d.ts +14 -0
- package/dist/src/utils/remove-legacy-scaffold-file.js +23 -0
- package/dist/src/utils/resolve-scenario-actors.d.ts +23 -0
- package/dist/src/utils/resolve-scenario-actors.js +74 -0
- package/dist/src/utils/serialize-schemas.d.ts +3 -1
- package/dist/src/utils/serialize-schemas.js +39 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -8
- package/dist/.pikku/schemas/schemas/PikkuScenarioFunctionsOutput.schema.json +0 -1
- package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.d.ts +0 -1
- package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.js +0 -31
- package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.d.ts +0 -10
- package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.js +0 -104
- package/skills/pikku-addon/SKILL.md +0 -243
- package/skills/pikku-addon/references/addon-package-manifest.md +0 -63
- package/skills/pikku-ai-agent/SKILL.md +0 -231
- package/skills/pikku-ai-vercel/SKILL.md +0 -82
- package/skills/pikku-ai-voice/SKILL.md +0 -88
- package/skills/pikku-audit/SKILL.md +0 -175
- package/skills/pikku-aws/SKILL.md +0 -111
- package/skills/pikku-backblaze/SKILL.md +0 -71
- package/skills/pikku-better-auth/SKILL.md +0 -298
- package/skills/pikku-cli/SKILL.md +0 -198
- package/skills/pikku-cli/references/complete-example.md +0 -82
- package/skills/pikku-concepts/SKILL.md +0 -250
- package/skills/pikku-concepts/references/concept-mapping.md +0 -556
- package/skills/pikku-concepts/references/packages.md +0 -29
- package/skills/pikku-config/SKILL.md +0 -212
- package/skills/pikku-cron/SKILL.md +0 -214
- package/skills/pikku-deploy-azure/SKILL.md +0 -71
- package/skills/pikku-deploy-cloudflare/SKILL.md +0 -82
- package/skills/pikku-deploy-express/SKILL.md +0 -86
- package/skills/pikku-deploy-fastify/SKILL.md +0 -73
- package/skills/pikku-deploy-lambda/SKILL.md +0 -110
- package/skills/pikku-deploy-nextjs/SKILL.md +0 -78
- package/skills/pikku-deploy-uws/SKILL.md +0 -88
- package/skills/pikku-deps/SKILL.md +0 -98
- package/skills/pikku-emails/SKILL.md +0 -163
- package/skills/pikku-fabric/SKILL.md +0 -318
- package/skills/pikku-fabric-debug/SKILL.md +0 -112
- package/skills/pikku-feature/SKILL.md +0 -258
- package/skills/pikku-gateway-slack/SKILL.md +0 -115
- package/skills/pikku-http/SKILL.md +0 -220
- package/skills/pikku-http/references/http-options.md +0 -55
- package/skills/pikku-i18n/SKILL.md +0 -137
- package/skills/pikku-info/SKILL.md +0 -100
- package/skills/pikku-jose/SKILL.md +0 -105
- package/skills/pikku-kysely/SKILL.md +0 -219
- package/skills/pikku-machine-auth/SKILL.md +0 -183
- package/skills/pikku-mcp/SKILL.md +0 -241
- package/skills/pikku-middleware/SKILL.md +0 -231
- package/skills/pikku-middleware/references/middleware-patterns.md +0 -61
- package/skills/pikku-mongodb/SKILL.md +0 -105
- package/skills/pikku-n8n-import/SKILL.md +0 -109
- package/skills/pikku-n8n-import/SPEC.md +0 -84
- package/skills/pikku-n8n-import/references/addon-mapping.md +0 -121
- package/skills/pikku-n8n-import/references/code-translation.md +0 -121
- package/skills/pikku-n8n-import/references/loops-and-control.md +0 -87
- package/skills/pikku-paraglide/SKILL.md +0 -117
- package/skills/pikku-permissions/SKILL.md +0 -192
- package/skills/pikku-pino/SKILL.md +0 -79
- package/skills/pikku-product-second-opinion/README.md +0 -43
- package/skills/pikku-product-second-opinion/SKILL.md +0 -158
- package/skills/pikku-product-second-opinion/example/sample-report.md +0 -90
- package/skills/pikku-product-second-opinion/references/report-template.md +0 -73
- package/skills/pikku-queue/SKILL.md +0 -240
- package/skills/pikku-react/SKILL.md +0 -212
- package/skills/pikku-react-query/SKILL.md +0 -242
- package/skills/pikku-realtime/SKILL.md +0 -236
- package/skills/pikku-realtime/references/other-routes.md +0 -23
- package/skills/pikku-redis/SKILL.md +0 -90
- package/skills/pikku-rpc/SKILL.md +0 -171
- package/skills/pikku-rtl/SKILL.md +0 -219
- package/skills/pikku-scenario/SKILL.md +0 -215
- package/skills/pikku-schedule/SKILL.md +0 -57
- package/skills/pikku-schema-ajv/SKILL.md +0 -62
- package/skills/pikku-schema-cfworker/SKILL.md +0 -63
- package/skills/pikku-security/SKILL.md +0 -108
- package/skills/pikku-services/SKILL.md +0 -248
- package/skills/pikku-services/references/audit-wire-service.md +0 -34
- package/skills/pikku-software-archaeology/README.md +0 -70
- package/skills/pikku-software-archaeology/SKILL.md +0 -186
- package/skills/pikku-software-archaeology/references/blueprint.schema.json +0 -625
- package/skills/pikku-software-archaeology/references/pikku-mapping.md +0 -49
- package/skills/pikku-software-archaeology/scripts/validate.mjs +0 -173
- package/skills/pikku-tag-middleware/SKILL.md +0 -13
- package/skills/pikku-template-clone/SKILL.md +0 -40
- package/skills/pikku-trigger/SKILL.md +0 -181
- package/skills/pikku-versioning/SKILL.md +0 -173
- package/skills/pikku-websocket/SKILL.md +0 -243
- package/skills/pikku-workflow/SKILL.md +0 -172
- package/skills/pikku-workflow/references/workflow-reference.md +0 -63
- package/skills/pikku-workflows-client/SKILL.md +0 -150
- package/skills/pikku-ws/SKILL.md +0 -47
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-websocket
|
|
3
|
-
description: >-
|
|
4
|
-
Use when adding real-time features, WebSocket channels, live updates, chat, or pub/sub to a
|
|
5
|
-
Pikku app. Covers wireChannel, action routing, auth, EventHub pub/sub, channel middleware, and
|
|
6
|
-
generated WebSocket client. TRIGGER when: code uses wireChannel, user asks about WebSocket,
|
|
7
|
-
real-time, live updates, chat, pub/sub, or the generated WebSocket client. DO NOT TRIGGER when:
|
|
8
|
-
user asks about HTTP/REST (use pikku-http), SSE (use pikku-http with sse: true), or WebSocket
|
|
9
|
-
deployment specifics (use pikku-deploy-uws).
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Pikku WebSocket Wiring
|
|
13
|
-
|
|
14
|
-
## Agent Operating Procedure
|
|
15
|
-
|
|
16
|
-
Use this skill as an execution checklist, not reference material.
|
|
17
|
-
|
|
18
|
-
1. Discover before editing. Prefer OpenCode tools such as `pikku-meta` when available; otherwise run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
19
|
-
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.
|
|
20
|
-
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
21
|
-
4. Validate with the narrowest relevant command first, then run `pikku-verify` or `pikku all` when functions, wirings, schemas, or generated clients may have changed.
|
|
22
|
-
5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
23
|
-
|
|
24
|
-
Wire Pikku functions to WebSocket channels with structured message routing, auth per-action, pub/sub via EventHub, and auto-generated type-safe clients.
|
|
25
|
-
|
|
26
|
-
## Before You Start
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
pikku info functions --verbose # See existing functions and their types
|
|
30
|
-
pikku info tags --verbose # Understand project organization
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Follow existing patterns. See `pikku-concepts` for the core mental model.
|
|
34
|
-
|
|
35
|
-
## API Reference
|
|
36
|
-
|
|
37
|
-
### `wireChannel(config)`
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
import { wireChannel } from '@pikku/core/channel'
|
|
41
|
-
|
|
42
|
-
wireChannel({
|
|
43
|
-
name: string, // Channel name (e.g. 'todos')
|
|
44
|
-
onConnect: async () => {}, // Called when client connects
|
|
45
|
-
onDisconnect: async () => {}, // Called when client disconnects
|
|
46
|
-
onMessageWiring: { // Action → function mapping
|
|
47
|
-
[actionName: string]: {
|
|
48
|
-
func: PikkuFunc,
|
|
49
|
-
auth?: boolean, // Override channel-level auth
|
|
50
|
-
permissions?: Record<string, PikkuPermission | PikkuPermission[]>,
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
channelMiddleware?: PikkuChannelMiddleware[],
|
|
54
|
-
})
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### `pikkuChannelMiddleware(fn)`
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
import { pikkuChannelMiddleware } from '@pikku/core'
|
|
61
|
-
|
|
62
|
-
const middleware = pikkuChannelMiddleware(async (services, event, next) => {
|
|
63
|
-
// Transform or filter events before/after
|
|
64
|
-
await next(event) // Pass modified event, or next(null) to drop
|
|
65
|
-
})
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### `addChannelMiddleware(domain, middlewares)`
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
addChannelMiddleware('todos', [addTimestamp, filterSensitive])
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## Usage Patterns
|
|
75
|
-
|
|
76
|
-
### Basic Channel
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
wireChannel({
|
|
80
|
-
name: 'todos',
|
|
81
|
-
onConnect: async () => {},
|
|
82
|
-
onDisconnect: async () => {},
|
|
83
|
-
onMessageWiring: {
|
|
84
|
-
create: { func: createTodo },
|
|
85
|
-
list: { func: listTodos, auth: false },
|
|
86
|
-
},
|
|
87
|
-
})
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Action Routing with Auth
|
|
91
|
-
|
|
92
|
-
Clients send `{ action: 'create', data: {...} }`. Pikku routes to the matching function.
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
const authenticate = pikkuFunc({
|
|
96
|
-
title: 'Authenticate',
|
|
97
|
-
func: async ({ setSession }, { token }) => {
|
|
98
|
-
const session = await verifyJWT(token)
|
|
99
|
-
setSession(session)
|
|
100
|
-
return { success: true }
|
|
101
|
-
},
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
wireChannel({
|
|
105
|
-
name: 'todos',
|
|
106
|
-
onConnect: async () => {},
|
|
107
|
-
onDisconnect: async () => {},
|
|
108
|
-
onMessageWiring: {
|
|
109
|
-
auth: { func: authenticate, auth: false }, // No session required
|
|
110
|
-
subscribe: { func: subscribeTodos }, // Session required
|
|
111
|
-
create: { func: createTodo },
|
|
112
|
-
},
|
|
113
|
-
})
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Pub/Sub with EventHub
|
|
117
|
-
|
|
118
|
-
Use EventHub for real-time broadcasting across connections:
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
wireChannel({
|
|
122
|
-
name: 'todos',
|
|
123
|
-
onConnect: async ({ eventHub, channel }) => {
|
|
124
|
-
eventHub.subscribe('todos:updated', (data) => {
|
|
125
|
-
channel.send(data)
|
|
126
|
-
})
|
|
127
|
-
},
|
|
128
|
-
onDisconnect: async () => {},
|
|
129
|
-
onMessageWiring: {
|
|
130
|
-
create: {
|
|
131
|
-
func: pikkuFunc({
|
|
132
|
-
title: 'Create Todo',
|
|
133
|
-
func: async ({ db, eventHub }, { text }) => {
|
|
134
|
-
const todo = await db.createTodo({ text })
|
|
135
|
-
eventHub.publish('todos:updated', {
|
|
136
|
-
event: 'created',
|
|
137
|
-
todo,
|
|
138
|
-
})
|
|
139
|
-
return { todo }
|
|
140
|
-
},
|
|
141
|
-
}),
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
})
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Channel Middleware
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
const addTimestamp = pikkuChannelMiddleware(
|
|
151
|
-
async ({ logger }, event, next) => {
|
|
152
|
-
logger.info({ phase: 'before-send', event })
|
|
153
|
-
await next({ ...event, sentAt: Date.now() })
|
|
154
|
-
}
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
const filterSensitive = pikkuChannelMiddleware(
|
|
158
|
-
async (_services, event, next) => {
|
|
159
|
-
if (event.internal) return await next(null) // Drop event
|
|
160
|
-
await next(event)
|
|
161
|
-
}
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
// Apply globally to a domain
|
|
165
|
-
addChannelMiddleware('todos', [addTimestamp, filterSensitive])
|
|
166
|
-
|
|
167
|
-
// Or inline on wiring
|
|
168
|
-
wireChannel({
|
|
169
|
-
name: 'todos',
|
|
170
|
-
channelMiddleware: [addTimestamp],
|
|
171
|
-
onConnect: async () => {},
|
|
172
|
-
onDisconnect: async () => {},
|
|
173
|
-
onMessageWiring: { ... },
|
|
174
|
-
})
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Generated WebSocket Client
|
|
178
|
-
|
|
179
|
-
After `npx pikku all`:
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
import { PikkuWebSocket } from '.pikku/pikku-websocket.gen.js'
|
|
183
|
-
|
|
184
|
-
const pikku = new PikkuWebSocket(ws)
|
|
185
|
-
const todosRoute = pikku.getRoute('todos')
|
|
186
|
-
|
|
187
|
-
// Send action (type-safe)
|
|
188
|
-
const result = await todosRoute.send('create', { text: 'Buy milk' })
|
|
189
|
-
|
|
190
|
-
// Subscribe to events
|
|
191
|
-
todosRoute.subscribe('todos:updated', (data) => {
|
|
192
|
-
console.log(data.event, data.todo)
|
|
193
|
-
})
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
## Complete Example
|
|
197
|
-
|
|
198
|
-
```typescript
|
|
199
|
-
// functions/chat.functions.ts
|
|
200
|
-
export const authenticate = pikkuFunc({
|
|
201
|
-
title: 'Authenticate',
|
|
202
|
-
func: async ({ jwt }, { token }, { setSession }) => {
|
|
203
|
-
const payload = await jwt.verify(token)
|
|
204
|
-
setSession({ userId: payload.userId })
|
|
205
|
-
return { success: true }
|
|
206
|
-
},
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
export const sendMessage = pikkuFunc({
|
|
210
|
-
title: 'Send Message',
|
|
211
|
-
func: async ({ db, eventHub }, { text }, { session }) => {
|
|
212
|
-
const message = await db.createMessage({
|
|
213
|
-
text,
|
|
214
|
-
userId: session.userId,
|
|
215
|
-
})
|
|
216
|
-
eventHub.publish('chat:message', { message })
|
|
217
|
-
return { message }
|
|
218
|
-
},
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
export const listMessages = pikkuSessionlessFunc({
|
|
222
|
-
title: 'List Messages',
|
|
223
|
-
func: async ({ db }, { limit }) => {
|
|
224
|
-
return { messages: await db.listMessages(limit) }
|
|
225
|
-
},
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
// wirings/chat.channel.ts
|
|
229
|
-
wireChannel({
|
|
230
|
-
name: 'chat',
|
|
231
|
-
onConnect: async ({ eventHub, channel }) => {
|
|
232
|
-
eventHub.subscribe('chat:message', (data) => {
|
|
233
|
-
channel.send(data)
|
|
234
|
-
})
|
|
235
|
-
},
|
|
236
|
-
onDisconnect: async () => {},
|
|
237
|
-
onMessageWiring: {
|
|
238
|
-
auth: { func: authenticate, auth: false },
|
|
239
|
-
send: { func: sendMessage },
|
|
240
|
-
history: { func: listMessages, auth: false },
|
|
241
|
-
},
|
|
242
|
-
})
|
|
243
|
-
```
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-workflow
|
|
3
|
-
description: >-
|
|
4
|
-
Use when building multi-step workflows, state machines, or orchestration pipelines with Pikku.
|
|
5
|
-
Covers pikkuWorkflowFunc, workflow steps (do, sleep, suspend), graph workflows, and HTTP wiring.
|
|
6
|
-
TRIGGER when: code uses pikkuWorkflowFunc/pikkuWorkflowGraph, user asks about workflows,
|
|
7
|
-
multi-step processes, durable execution, suspend/resume, or DAG orchestration. DO NOT TRIGGER
|
|
8
|
-
when: user asks about simple background jobs (use pikku-queue) or scheduled tasks (use
|
|
9
|
-
pikku-cron).
|
|
10
|
-
installGroups: [core]
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# Pikku Workflow Wiring
|
|
14
|
-
|
|
15
|
-
## Agent Operating Procedure
|
|
16
|
-
|
|
17
|
-
Use this skill as an execution checklist, not reference material.
|
|
18
|
-
|
|
19
|
-
1. Capture baseline. Run `pikku-verify` (or `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
|
-
3. Identify the source files that own the behavior. Do not start from generated output, `.pikku`, `node_modules`, vendored packages, or build artifacts.
|
|
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-verify`. If only files you did not touch still error, those are pre-existing — leave them unless asked.
|
|
24
|
-
6. Call `pikku-workflow-view` only when `pikku-verify` fully passes (codegen AND type check both green) — never after a partial pass.
|
|
25
|
-
|
|
26
|
-
See `pikku-concepts` for the core mental model.
|
|
27
|
-
|
|
28
|
-
Build durable, multi-step workflows with automatic retry, sleep, suspend/resume, and parallel execution. Steps are cached for replay safety.
|
|
29
|
-
|
|
30
|
-
## Choosing the right factory
|
|
31
|
-
|
|
32
|
-
| Factory | When to use | Step-graph view? |
|
|
33
|
-
|---|---|---|
|
|
34
|
-
| `pikkuWorkflowFunc` | **Default for all new workflows.** Sequential + conditional logic; DSL mode (serialisable, replay-safe). ALL `const`/`let` declarations must be at the top level of the function body (not inside blocks). | ✅ Yes |
|
|
35
|
-
| `pikkuWorkflowGraph` | DAG / fan-out with nodes and typed refs between them. | ✅ Yes |
|
|
36
|
-
| `pikkuWorkflowComplexFunc` | Escape hatch only — arbitrary TypeScript, no top-level restriction (e.g. dynamic inline functions the DSL extractor cannot handle). | ❌ No (loses step-graph view) |
|
|
37
|
-
|
|
38
|
-
**Default to `pikkuWorkflowFunc`.** Use `pikkuWorkflowGraph` ONLY with explicit user approval AND only for a genuine cyclic dependency or Node.js-only import DSL cannot express. Use `pikkuWorkflowComplexFunc` ONLY with explicit user approval — a last-resort escape hatch. Never switch to either just to dodge a PKU641 error; restructure the code instead.
|
|
39
|
-
|
|
40
|
-
### PKU641 — DSL static analysis error
|
|
41
|
-
|
|
42
|
-
`pikkuWorkflowFunc` statically analyzes the body: **every `const`/`let` must be top-level, not inside any block (`if`, `for`, `while`, …).** Assignments inside blocks are fine — only declarations trigger it.
|
|
43
|
-
|
|
44
|
-
```typescript
|
|
45
|
-
// ❌ PKU641 — declaration inside block
|
|
46
|
-
if (priority === 'high') {
|
|
47
|
-
const bugCard = await workflow.do(...)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// ✅ hoist the declaration, assign inside the block
|
|
51
|
-
let bugCard: Awaited<ReturnType<typeof workflow.do>>
|
|
52
|
-
if (priority === 'high') {
|
|
53
|
-
bugCard = await workflow.do(...)
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## Import path
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
// CORRECT — workflow factories come from the generated types file
|
|
61
|
-
import { pikkuWorkflowFunc, pikkuWorkflowGraph, pikkuWorkflowComplexFunc } from '#pikku/workflow/pikku-workflow-types.gen.js'
|
|
62
|
-
|
|
63
|
-
// WRONG — '#pikku' does not re-export them (TS2305)
|
|
64
|
-
import { pikkuWorkflowFunc } from '#pikku'
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Defining a workflow
|
|
68
|
-
|
|
69
|
-
Declare input/output as Zod schemas (like any function) — never TypeScript generic params (no `pikkuWorkflowFunc<In, Out>(...)`; that skips runtime validation). `data` is typed from the input schema.
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
import { z } from 'zod'
|
|
73
|
-
import { pikkuWorkflowFunc } from '#pikku/workflow/pikku-workflow-types.gen.js'
|
|
74
|
-
|
|
75
|
-
const ProcessOrderInput = z.object({ orderId: z.string(), amount: z.number() })
|
|
76
|
-
const ProcessOrderOutput = z.object({ status: z.string(), discount: z.number().optional() })
|
|
77
|
-
|
|
78
|
-
export const processOrder = pikkuWorkflowFunc({
|
|
79
|
-
description: 'Process an order through payment and fulfillment',
|
|
80
|
-
tags: ['orders'],
|
|
81
|
-
input: ProcessOrderInput,
|
|
82
|
-
output: ProcessOrderOutput,
|
|
83
|
-
func: async (services, data, { workflow }) => {
|
|
84
|
-
// Declare ALL variables at top level — even those only assigned in branches (PKU641)
|
|
85
|
-
let discount: number | undefined
|
|
86
|
-
let status: string
|
|
87
|
-
|
|
88
|
-
if (data.amount > 1000) {
|
|
89
|
-
const d = await workflow.do('Apply bulk discount', 'calcDiscount', { amount: data.amount })
|
|
90
|
-
discount = d.discountPercent
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const payment = await workflow.do('Charge', 'chargePayment', {
|
|
94
|
-
orderId: data.orderId,
|
|
95
|
-
amount: discount ? data.amount * (1 - discount / 100) : data.amount,
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
if (payment.success) {
|
|
99
|
-
await workflow.do('Fulfill', 'fulfillOrder', { orderId: data.orderId })
|
|
100
|
-
status = 'fulfilled'
|
|
101
|
-
} else {
|
|
102
|
-
status = 'payment-failed'
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return { status, discount }
|
|
106
|
-
},
|
|
107
|
-
})
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Workflow step types
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
// RPC step — run a registered Pikku function as a step (opts: retries, retryDelay, description)
|
|
114
|
-
const result = await workflow.do('Step name', 'rpcFunctionName', { ...data }, { retries: 3, retryDelay: '1s' })
|
|
115
|
-
|
|
116
|
-
// Inline closure step — immediate execution, cached for replay
|
|
117
|
-
const msg = await workflow.do('Generate', async () => `Welcome, ${data.email}!`)
|
|
118
|
-
|
|
119
|
-
// Sleep — durable pause (duration: '30s', '5min', '1h', '1d')
|
|
120
|
-
await workflow.sleep('Wait 5 minutes', '5min')
|
|
121
|
-
|
|
122
|
-
// Suspend — pause until externally resumed (e.g. awaiting approval), then continue
|
|
123
|
-
await workflow.suspend('Awaiting approval')
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Parallel fan-out
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
const users = await Promise.all(
|
|
130
|
-
data.userIds.map((userId) => workflow.do(`Fetch user ${userId}`, 'getUser', { userId }))
|
|
131
|
-
)
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Graph workflow (DAG)
|
|
135
|
-
|
|
136
|
-
`pikkuWorkflowGraph` derives types from the RPC map — no explicit `input`/`output`. Nodes map `nodeName → Pikku function name`; `config.<node>.next` lists nodes to run after it (in parallel); `config.<node>.input: (ref) => ...` transforms input using refs to prior node outputs.
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
import { pikkuWorkflowGraph } from '#pikku/workflow/pikku-workflow-types.gen.js'
|
|
140
|
-
|
|
141
|
-
export const userOnboarding = pikkuWorkflowGraph({
|
|
142
|
-
description: 'Onboard a new user',
|
|
143
|
-
nodes: {
|
|
144
|
-
createProfile: 'createUserProfile',
|
|
145
|
-
sendWelcome: 'sendEmail',
|
|
146
|
-
setupDefaults: 'createDefaultTodos',
|
|
147
|
-
},
|
|
148
|
-
config: {
|
|
149
|
-
createProfile: { next: ['sendWelcome', 'setupDefaults'] }, // run in parallel
|
|
150
|
-
sendWelcome: {
|
|
151
|
-
input: (ref) => ({ to: ref('createProfile', 'email'), subject: 'Welcome!' }),
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
})
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## File conventions
|
|
158
|
-
|
|
159
|
-
- Place workflows in `packages/functions/src/wirings/*.workflow.ts`; export the variable so the inspector discovers it (no manual registration).
|
|
160
|
-
- HTTP start/run/status routes are auto-scaffolded via `scaffold.workflow` in `pikku.config.json`.
|
|
161
|
-
|
|
162
|
-
## Step dispatch & HTTP wiring
|
|
163
|
-
|
|
164
|
-
For per-step inline-vs-queue dispatch (`inline: false` and the `dispatchStep` rules), the manual `workflowStart`/`workflow`/`workflowStatus` HTTP wirings, and a suspend/resume example, read `references/workflow-reference.md`.
|
|
165
|
-
|
|
166
|
-
## After writing
|
|
167
|
-
|
|
168
|
-
1. `pikku-verify` (codegen + tsc).
|
|
169
|
-
2. PKU641 → a `const`/`let` is inside a block; hoist it to the top of the function body.
|
|
170
|
-
3. Import errors → use `#pikku/workflow/pikku-workflow-types.gen.js`, not `#pikku`.
|
|
171
|
-
4. Type errors only in files you did not touch → pre-existing template errors; safe to ignore.
|
|
172
|
-
5. Both green → call `pikku-workflow-view` with the workflow name.
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# Pikku Workflow Reference
|
|
2
|
-
|
|
3
|
-
## Step execution: inline vs queue dispatch
|
|
4
|
-
|
|
5
|
-
Whether a step runs **inline** (same process/session, no queue round-trip) or is **dispatched to the queue** is decided **purely by the step's function** — there is no workflow-level or per-call `inline` flag. `workflow.do(...)` options are only `retries`/`retryDelay`/`description`.
|
|
6
|
-
|
|
7
|
-
- **Steps default to inline.** Most steps don't need their own worker; running them inline avoids a queue round-trip per step, so a normally-started workflow executes its whole chain in one orchestrator pass.
|
|
8
|
-
- **`inline: false` opts a function out.** Set `inline: false` on the **function config** (`pikkuFunc` / `pikkuSessionlessFunc`, same level as `auth`/`expose`) to dispatch that step via the queue — for expensive/long-running steps that deserve their own worker, retry isolation, and concurrency limits.
|
|
9
|
-
- **Run-level `inline` is separate** and only controls whether the *whole run* executes in-process without queue infrastructure (set automatically when there is no `queueService`, or via `startWorkflow(..., { inline: true })`). It governs sleep handling, not per-step dispatch.
|
|
10
|
-
|
|
11
|
-
The rule (`dispatchStep`):
|
|
12
|
-
|
|
13
|
-
| Function `inline` | `queueService` present? | Result |
|
|
14
|
-
|---|---|---|
|
|
15
|
-
| default / `true` | any | **inline** |
|
|
16
|
-
| `false` | yes | **queued** (own worker) |
|
|
17
|
-
| `false` | no | **inline + a `logger.warn`** (misconfiguration: can't dispatch) |
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
// Push this one expensive step onto the queue; every other step stays inline:
|
|
21
|
-
export const renderLargeReport = pikkuSessionlessFunc({
|
|
22
|
-
inline: false, // dispatch via queue instead of running inline
|
|
23
|
-
input: ReportInput,
|
|
24
|
-
output: ReportOutput,
|
|
25
|
-
func: async (services, data) => { /* ... */ },
|
|
26
|
-
})
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
`inline: false` requires a `queueService`; without one the step still runs (so the workflow progresses) but emits a `logger.warn` so the misconfiguration is visible.
|
|
30
|
-
|
|
31
|
-
## HTTP workflow wiring (manual)
|
|
32
|
-
|
|
33
|
-
Usually auto-scaffolded via `scaffold.workflow`. To wire by hand:
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
// Start a workflow
|
|
37
|
-
wireHTTP({ method: 'post', route: '/onboard', func: workflowStart('onboardUser') })
|
|
38
|
-
|
|
39
|
-
// Execute workflow steps (called by the orchestrator)
|
|
40
|
-
wireHTTP({ method: 'post', route: '/onboard/run', func: workflow('onboardUser') })
|
|
41
|
-
|
|
42
|
-
// Check workflow status
|
|
43
|
-
wireHTTP({ method: 'get', route: '/onboard/status/:runId', func: workflowStatus('onboardUser') })
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Suspend / resume example
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
import { z } from 'zod'
|
|
50
|
-
import { pikkuWorkflowFunc } from '#pikku/workflow/pikku-workflow-types.gen.js'
|
|
51
|
-
|
|
52
|
-
export const approval = pikkuWorkflowFunc({
|
|
53
|
-
description: 'Submit a request and wait for approval',
|
|
54
|
-
input: z.object({ requestId: z.string() }),
|
|
55
|
-
output: z.object({ approved: z.boolean() }),
|
|
56
|
-
func: async (services, data, { workflow }) => {
|
|
57
|
-
await workflow.do('Submit request', 'submitRequest', data)
|
|
58
|
-
await workflow.suspend('Awaiting approval') // pauses here until externally resumed
|
|
59
|
-
const result = await workflow.do('Check result', 'getApprovalResult', data)
|
|
60
|
-
return { approved: result.approved }
|
|
61
|
-
},
|
|
62
|
-
})
|
|
63
|
-
```
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-workflows-client
|
|
3
|
-
description: 'Run Pikku workflows from a React frontend and track their progress. Covers `useRunWorkflow` (run-and-wait), `useStartWorkflow` (fire-and-poll), and `useWorkflowStatus` (live status). TRIGGER when: a React component needs to invoke or display the status of a Pikku workflow, the user mentions long-running tasks / background jobs / progress UI tied to a workflow, or asks how to start/track a workflow from the client. DO NOT TRIGGER when: the user is wiring the workflow itself (use pikku-workflow) or only making regular RPC calls (use pikku-react-query).'
|
|
4
|
-
installGroups: [core]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Pikku Workflows — Client Hooks
|
|
8
|
-
|
|
9
|
-
## Agent Operating Procedure
|
|
10
|
-
|
|
11
|
-
Use this skill as an execution checklist, not reference material.
|
|
12
|
-
|
|
13
|
-
1. Discover before editing. Prefer OpenCode tools such as `pikku-meta` when available; otherwise run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
14
|
-
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.
|
|
15
|
-
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
16
|
-
4. Validate with the narrowest relevant command first, then run `pikku-verify` or `pikku all` when functions, wirings, schemas, or generated clients may have changed.
|
|
17
|
-
5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
18
|
-
|
|
19
|
-
When a project has `pikkuWorkflowGraph` workflows, three React Query
|
|
20
|
-
hooks are auto-generated alongside the standard RPC hooks. They handle
|
|
21
|
-
the two common shapes: **run-and-wait** (short workflows where the
|
|
22
|
-
client waits for the result) and **fire-and-poll** (long workflows where
|
|
23
|
-
the client gets a `runId` and polls status).
|
|
24
|
-
|
|
25
|
-
## Discover what workflows exist
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
yarn pikku meta clients --json | jq '.workflows'
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Each entry has `name`, `description`, `mode` (inline | distributed), plus
|
|
32
|
-
`input` / `output` type names. Pass the workflow **name** to the hooks
|
|
33
|
-
below.
|
|
34
|
-
|
|
35
|
-
## Setup
|
|
36
|
-
|
|
37
|
-
These hooks are generated into the same `api.gen.ts` as `usePikkuQuery` —
|
|
38
|
-
no extra setup beyond `PikkuProvider` + `QueryClientProvider` (see the
|
|
39
|
-
**pikku-react** and **pikku-react-query** skills).
|
|
40
|
-
|
|
41
|
-
## `useRunWorkflow(name, options?)` — run and wait
|
|
42
|
-
|
|
43
|
-
For short, synchronous-feeling workflows. Returns a mutation that
|
|
44
|
-
resolves to the workflow's output.
|
|
45
|
-
|
|
46
|
-
```tsx
|
|
47
|
-
import { useRunWorkflow } from './pikku/api.gen'
|
|
48
|
-
|
|
49
|
-
function ChargeButton({ orderId }: { orderId: string }) {
|
|
50
|
-
const run = useRunWorkflow('chargeOrder', {
|
|
51
|
-
onSuccess: (output) => toast.success(`Charged: $${output.amount}`),
|
|
52
|
-
})
|
|
53
|
-
return (
|
|
54
|
-
<button onClick={() => run.mutate({ orderId })} disabled={run.isPending}>
|
|
55
|
-
{run.isPending ? 'Charging…' : 'Charge'}
|
|
56
|
-
</button>
|
|
57
|
-
)
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Use this when the workflow finishes in seconds and the UI can hold open
|
|
62
|
-
a loading state until done.
|
|
63
|
-
|
|
64
|
-
## `useStartWorkflow(name, options?)` — fire-and-poll
|
|
65
|
-
|
|
66
|
-
Returns a mutation that resolves to `{ runId: string }` immediately. The
|
|
67
|
-
workflow keeps running on the server. Pair with `useWorkflowStatus` to
|
|
68
|
-
render progress.
|
|
69
|
-
|
|
70
|
-
```tsx
|
|
71
|
-
const start = useStartWorkflow('processVideo', {
|
|
72
|
-
onSuccess: ({ runId }) => setActiveRunId(runId),
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
start.mutate({ videoId: '123' })
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Use this for long-running workflows (uploads, batch jobs, AI generation,
|
|
79
|
-
anything you'd want a progress bar for).
|
|
80
|
-
|
|
81
|
-
## `useWorkflowStatus(workflowName, runId, options?)` — observe
|
|
82
|
-
|
|
83
|
-
Polls the workflow runtime for a run's status. Returns a typed status
|
|
84
|
-
object with `status`, optional `output`, and optional `error`.
|
|
85
|
-
|
|
86
|
-
```tsx
|
|
87
|
-
import { useWorkflowStatus } from './pikku/api.gen'
|
|
88
|
-
|
|
89
|
-
function VideoStatus({ runId }: { runId: string }) {
|
|
90
|
-
const { data: status } = useWorkflowStatus('processVideo', runId, {
|
|
91
|
-
refetchInterval: (query) =>
|
|
92
|
-
query.state.data?.status === 'running' ? 1000 : false,
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
if (!status) return null
|
|
96
|
-
if (status.status === 'running') return <Spinner />
|
|
97
|
-
if (status.status === 'completed') return <Result {...status.output} />
|
|
98
|
-
if (status.status === 'failed')
|
|
99
|
-
return <Error message={status.error?.message} />
|
|
100
|
-
return null
|
|
101
|
-
}
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
Status values: `'running' | 'suspended' | 'completed' | 'failed' | 'cancelled'`.
|
|
105
|
-
|
|
106
|
-
The hook stops auto-polling when the run reaches a terminal state (set
|
|
107
|
-
`refetchInterval` to false in those cases — pattern shown above).
|
|
108
|
-
|
|
109
|
-
## Putting it together — start + observe
|
|
110
|
-
|
|
111
|
-
```tsx
|
|
112
|
-
function ProcessVideoFlow({ videoId }: { videoId: string }) {
|
|
113
|
-
const [runId, setRunId] = useState<string>()
|
|
114
|
-
const start = useStartWorkflow('processVideo', {
|
|
115
|
-
onSuccess: ({ runId }) => setRunId(runId),
|
|
116
|
-
})
|
|
117
|
-
const status = useWorkflowStatus('processVideo', runId)
|
|
118
|
-
|
|
119
|
-
if (!runId) {
|
|
120
|
-
return (
|
|
121
|
-
<button
|
|
122
|
-
onClick={() => start.mutate({ videoId })}
|
|
123
|
-
disabled={start.isPending}
|
|
124
|
-
>
|
|
125
|
-
Start
|
|
126
|
-
</button>
|
|
127
|
-
)
|
|
128
|
-
}
|
|
129
|
-
return <ProgressBar status={status.data?.status} />
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## Backend: streaming richer progress
|
|
134
|
-
|
|
135
|
-
The status hook returns a coarse-grained state machine (`running`,
|
|
136
|
-
`completed`, etc.). For step-by-step updates inside a long workflow,
|
|
137
|
-
publish events from the workflow itself via `eventHub` or open a
|
|
138
|
-
WebSocket channel — out of scope for this skill (see workflow + channel
|
|
139
|
-
docs).
|
|
140
|
-
|
|
141
|
-
## What NOT to do
|
|
142
|
-
|
|
143
|
-
- Don't poll status manually — use `useWorkflowStatus` with
|
|
144
|
-
`refetchInterval`. It dedupes and stops on terminal states.
|
|
145
|
-
- Don't call `useRunWorkflow` for workflows that take more than a few
|
|
146
|
-
seconds. The user-facing component will hold a long-running pending
|
|
147
|
-
state with no progress indication; use start + status instead.
|
|
148
|
-
- Don't use these hooks for non-workflow RPCs — they only resolve
|
|
149
|
-
workflow-shaped names. Regular RPCs go through `usePikkuQuery` /
|
|
150
|
-
`usePikkuMutation`.
|
package/skills/pikku-ws/SKILL.md
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-ws
|
|
3
|
-
description: >-
|
|
4
|
-
Use when setting up a WebSocket server with the ws library in a Pikku app. Covers the ws runtime
|
|
5
|
-
adapter for Pikku channels. TRIGGER when: code uses @pikku/ws, user asks about ws library
|
|
6
|
-
WebSocket server, or Node.js WebSocket runtime. DO NOT TRIGGER when: user asks about WebSocket
|
|
7
|
-
wiring/channels (use pikku-websocket) or uWebSockets (use pikku-deploy-uws).
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Pikku WS (WebSocket Server Runtime)
|
|
11
|
-
|
|
12
|
-
## Agent Operating Procedure
|
|
13
|
-
|
|
14
|
-
Use this skill as an execution checklist, not reference material.
|
|
15
|
-
|
|
16
|
-
1. Discover before editing. Prefer OpenCode tools such as `pikku-meta` when available; otherwise run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
17
|
-
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.
|
|
18
|
-
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
19
|
-
4. Validate with the narrowest relevant command first, then run `pikku-verify` or `pikku all` when functions, wirings, schemas, or generated clients may have changed.
|
|
20
|
-
5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
21
|
-
|
|
22
|
-
`@pikku/ws` provides a WebSocket server runtime using the [ws](https://github.com/websockets/ws) library, connecting Pikku's channel system to a Node.js WebSocket server.
|
|
23
|
-
|
|
24
|
-
## Installation
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
yarn add @pikku/ws ws
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Usage Patterns
|
|
31
|
-
|
|
32
|
-
### Basic Setup
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
import { PikkuWSServer } from '@pikku/ws'
|
|
36
|
-
|
|
37
|
-
const wsServer = new PikkuWSServer({
|
|
38
|
-
server: httpServer, // Node.js HTTP server
|
|
39
|
-
singletonServices,
|
|
40
|
-
createWireServices,
|
|
41
|
-
channelStore,
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
await wsServer.init()
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
This runtime bridges the `ws` WebSocket library with Pikku's channel wiring. See `pikku-websocket` for channel wiring details and `pikku-deploy-fastify`/`pikku-deploy-express` for integrating with HTTP servers.
|