@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,241 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-mcp
|
|
3
|
-
description: >-
|
|
4
|
-
Use when exposing Pikku functions as MCP tools, resources, or prompts for AI assistants. Covers
|
|
5
|
-
mcp: true flag, pikkuMCPResourceFunc, pikkuMCPPromptFunc, and MCP wire object. TRIGGER when:
|
|
6
|
-
code uses mcp: true or pikkuMCPResourceFunc/pikkuMCPPromptFunc, user asks about MCP, Model
|
|
7
|
-
Context Protocol, AI tool integration, or exposing functions to Claude/ChatGPT. DO NOT TRIGGER
|
|
8
|
-
when: user asks about AI agents (use pikku-ai-agent) or general function definitions (use
|
|
9
|
-
pikku-concepts).
|
|
10
|
-
installGroups: [core]
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# Pikku MCP Wiring
|
|
14
|
-
|
|
15
|
-
## Agent Operating Procedure
|
|
16
|
-
|
|
17
|
-
Use this skill as an execution checklist, not reference material.
|
|
18
|
-
|
|
19
|
-
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.
|
|
20
|
-
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.
|
|
21
|
-
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
22
|
-
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.
|
|
23
|
-
5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
24
|
-
|
|
25
|
-
Expose Pikku functions as Model Context Protocol (MCP) tools, resources, and prompts for AI assistants like Claude, ChatGPT, and others.
|
|
26
|
-
|
|
27
|
-
## Before You Start
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
pikku info functions --verbose # See existing functions that could become MCP tools
|
|
31
|
-
pikku info tags --verbose # Understand project organization
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
See `pikku-concepts` for the core mental model.
|
|
35
|
-
|
|
36
|
-
## API Reference
|
|
37
|
-
|
|
38
|
-
### MCP Tools (simplest approach)
|
|
39
|
-
|
|
40
|
-
Add `mcp: true` to any existing `pikkuFunc` to expose it as an MCP tool:
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
const myFunc = pikkuFunc({
|
|
44
|
-
description: string, // Used as MCP tool description
|
|
45
|
-
input: ZodSchema, // Becomes MCP tool input schema
|
|
46
|
-
output: ZodSchema, // Return type
|
|
47
|
-
mcp: true, // ← Expose as MCP tool
|
|
48
|
-
func: async (services, data) => { ... },
|
|
49
|
-
})
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### MCP Resources (`pikkuMCPResourceFunc`)
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
import { pikkuMCPResourceFunc } from '#pikku'
|
|
56
|
-
|
|
57
|
-
const resource = pikkuMCPResourceFunc({
|
|
58
|
-
uri: string, // URI template, e.g. 'todos/{id}'
|
|
59
|
-
title: string, // Human-readable title
|
|
60
|
-
description?: string,
|
|
61
|
-
func: async (services, data, { mcp }) => {
|
|
62
|
-
// Must return array of { uri, text } or { uri, blob, mimeType }
|
|
63
|
-
return [{ uri: mcp.uri!, text: JSON.stringify(result) }]
|
|
64
|
-
},
|
|
65
|
-
})
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### MCP Prompts (`pikkuMCPPromptFunc`)
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
import { pikkuMCPPromptFunc } from '#pikku'
|
|
72
|
-
|
|
73
|
-
const prompt = pikkuMCPPromptFunc({
|
|
74
|
-
name: string,
|
|
75
|
-
description: string,
|
|
76
|
-
func: async (services, data) => {
|
|
77
|
-
// Must return array of MCP messages
|
|
78
|
-
return [
|
|
79
|
-
{
|
|
80
|
-
role: 'user',
|
|
81
|
-
content: { type: 'text', text: '...' },
|
|
82
|
-
},
|
|
83
|
-
]
|
|
84
|
-
},
|
|
85
|
-
})
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### MCP Wire Object
|
|
89
|
-
|
|
90
|
-
Inside MCP-enabled functions, `wire.mcp` provides:
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
mcp.uri // Current resource URI (for resources)
|
|
94
|
-
mcp.sendResourceUpdated(uri) // Notify clients a resource changed
|
|
95
|
-
mcp.enableTools({ toolName: true }) // Dynamically enable/disable tools
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Usage Patterns
|
|
99
|
-
|
|
100
|
-
### Expose Existing Functions as MCP Tools
|
|
101
|
-
|
|
102
|
-
The simplest path — add `mcp: true` to any function:
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
export const createTodo = pikkuFunc({
|
|
106
|
-
description: 'Create a new todo item',
|
|
107
|
-
input: CreateTodoInput,
|
|
108
|
-
output: CreateTodoOutput,
|
|
109
|
-
mcp: true,
|
|
110
|
-
func: async ({ db }, { text, priority }) => {
|
|
111
|
-
return await db.createTodo({ text, priority })
|
|
112
|
-
},
|
|
113
|
-
})
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### MCP Resources with URI Templates
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
export const getTodo = pikkuMCPResourceFunc({
|
|
120
|
-
uri: 'todos/{id}',
|
|
121
|
-
title: 'Todo Details',
|
|
122
|
-
description: 'Get a todo by ID',
|
|
123
|
-
func: async ({ db }, { id }, { mcp }) => {
|
|
124
|
-
const todo = await db.getTodo(id)
|
|
125
|
-
return [{ uri: mcp.uri!, text: JSON.stringify(todo) }]
|
|
126
|
-
},
|
|
127
|
-
})
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### MCP Prompts
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
export const codeReview = pikkuMCPPromptFunc({
|
|
134
|
-
name: 'codeReview',
|
|
135
|
-
description: 'Generate a code review prompt',
|
|
136
|
-
func: async ({}, { filePath, context }) => {
|
|
137
|
-
return [
|
|
138
|
-
{
|
|
139
|
-
role: 'user',
|
|
140
|
-
content: {
|
|
141
|
-
type: 'text',
|
|
142
|
-
text: `Review ${filePath}. Context: ${context}`,
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
]
|
|
146
|
-
},
|
|
147
|
-
})
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Dynamic Tool Control
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
export const manageTodos = pikkuFunc({
|
|
154
|
-
description: 'Manage todo items',
|
|
155
|
-
input: ManageTodosInput,
|
|
156
|
-
output: ManageTodosOutput,
|
|
157
|
-
mcp: true,
|
|
158
|
-
func: async ({ db }, { action, id }, { mcp }) => {
|
|
159
|
-
if (action === 'delete') {
|
|
160
|
-
await db.deleteTodo(id)
|
|
161
|
-
mcp.sendResourceUpdated(`todos/${id}`)
|
|
162
|
-
await mcp.enableTools({ archiveTodos: true })
|
|
163
|
-
return { deleted: true }
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
})
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### MCP Server Setup
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
// start.ts
|
|
173
|
-
import { PikkuMCPServer } from '@pikku/modelcontextprotocol'
|
|
174
|
-
|
|
175
|
-
const server = new PikkuMCPServer(config, singletonServices, createWireServices)
|
|
176
|
-
await server.init()
|
|
177
|
-
await server.start()
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## Complete Example
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
// functions/todos.functions.ts
|
|
184
|
-
export const listTodos = pikkuSessionlessFunc({
|
|
185
|
-
description: 'List all todo items',
|
|
186
|
-
input: ListTodosInput,
|
|
187
|
-
output: ListTodosOutput,
|
|
188
|
-
mcp: true,
|
|
189
|
-
func: async ({ db }, { status }) => {
|
|
190
|
-
return { todos: await db.listTodos(status) }
|
|
191
|
-
},
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
export const createTodo = pikkuFunc({
|
|
195
|
-
description: 'Create a new todo item',
|
|
196
|
-
input: CreateTodoInput,
|
|
197
|
-
output: CreateTodoOutput,
|
|
198
|
-
mcp: true,
|
|
199
|
-
func: async ({ db }, { text, priority }) => {
|
|
200
|
-
return await db.createTodo({ text, priority })
|
|
201
|
-
},
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
export const completeTodo = pikkuFunc({
|
|
205
|
-
description: 'Mark a todo as complete',
|
|
206
|
-
input: CompleteTodoInput,
|
|
207
|
-
output: CompleteTodoOutput,
|
|
208
|
-
mcp: true,
|
|
209
|
-
func: async ({ db }, { todoId }) => {
|
|
210
|
-
return await db.completeTodo(todoId)
|
|
211
|
-
},
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
// functions/todos.mcp.ts
|
|
215
|
-
export const getTodoResource = pikkuMCPResourceFunc({
|
|
216
|
-
uri: 'todos/{id}',
|
|
217
|
-
title: 'Todo Details',
|
|
218
|
-
description: 'Get details of a specific todo',
|
|
219
|
-
func: async ({ db }, { id }, { mcp }) => {
|
|
220
|
-
const todo = await db.getTodo(id)
|
|
221
|
-
return [{ uri: mcp.uri!, text: JSON.stringify(todo) }]
|
|
222
|
-
},
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
export const planDayPrompt = pikkuMCPPromptFunc({
|
|
226
|
-
name: 'planDay',
|
|
227
|
-
description: 'Create a daily plan based on pending todos',
|
|
228
|
-
func: async ({ db }, {}) => {
|
|
229
|
-
const { todos } = await db.listTodos('pending')
|
|
230
|
-
return [
|
|
231
|
-
{
|
|
232
|
-
role: 'user',
|
|
233
|
-
content: {
|
|
234
|
-
type: 'text',
|
|
235
|
-
text: `Plan my day. Here are my pending todos:\n${todos.map((t) => `- ${t.text} (${t.priority})`).join('\n')}`,
|
|
236
|
-
},
|
|
237
|
-
},
|
|
238
|
-
]
|
|
239
|
-
},
|
|
240
|
-
})
|
|
241
|
-
```
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-middleware
|
|
3
|
-
description: >-
|
|
4
|
-
Use when adding any middleware to a Pikku app — global HTTP middleware, tag-scoped middleware
|
|
5
|
-
(including service-to-service bearer auth), per-route middleware, session-setting middleware, or
|
|
6
|
-
understanding middleware execution order and priority. TRIGGER when: user wants middleware on
|
|
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/authorization checks (use pikku-permissions), auth strategies like
|
|
10
|
-
authBearer/authCookie (use pikku-security), or deployment.
|
|
11
|
-
installGroups: [core]
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
# Pikku Middleware
|
|
15
|
-
|
|
16
|
-
## Agent Operating Procedure
|
|
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.
|
|
22
|
-
|
|
23
|
-
## The `pikkuMiddleware` Factory
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
import { pikkuMiddleware } from '#pikku'
|
|
27
|
-
|
|
28
|
-
// Simple: just a function
|
|
29
|
-
const myMiddleware = pikkuMiddleware(async (services, wire, next) => {
|
|
30
|
-
// runs before the function
|
|
31
|
-
await next()
|
|
32
|
-
// runs after the function (optional)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
// With metadata (name + priority)
|
|
36
|
-
const telemetryMiddleware = pikkuMiddleware({
|
|
37
|
-
name: 'my-telemetry',
|
|
38
|
-
priority: 'highest',
|
|
39
|
-
func: async (services, wire, next) => {
|
|
40
|
-
const start = performance.now()
|
|
41
|
-
try {
|
|
42
|
-
await next()
|
|
43
|
-
} finally {
|
|
44
|
-
services.logger.info({ duration: Math.round(performance.now() - start) })
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
})
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
The `wire` object gives you:
|
|
51
|
-
- `wire.http` — inbound HTTP context (headers, URL, cookies)
|
|
52
|
-
- `wire.setSession(session)` — set the session for this request
|
|
53
|
-
- `wire.getSession()` — read the current session
|
|
54
|
-
- `wire.session` — the session set so far (may be undefined)
|
|
55
|
-
|
|
56
|
-
Throw a typed error to abort: `UnauthorizedError`, `ForbiddenError`, etc. from `@pikku/core/errors`.
|
|
57
|
-
|
|
58
|
-
## Scoping: Five Levels
|
|
59
|
-
|
|
60
|
-
From broadest to narrowest:
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
// 1. Wire-agnostic global: all wire types (HTTP, Queue, Channel, Trigger, Workflow, ...)
|
|
64
|
-
addGlobalMiddleware([telemetryOuter()])
|
|
65
|
-
|
|
66
|
-
// 2. HTTP global: all HTTP routes
|
|
67
|
-
addHTTPMiddleware('*', [cors(), authBearer()])
|
|
68
|
-
|
|
69
|
-
// 3. Prefix-based: URL pattern
|
|
70
|
-
addHTTPMiddleware('/admin/*', [auditLog])
|
|
71
|
-
|
|
72
|
-
// 4. Tag-based: any wiring with matching tag
|
|
73
|
-
addTagMiddleware('machine-agent', [bearerAuth]) // tag on function or wire
|
|
74
|
-
|
|
75
|
-
// 5. Inline: per-wiring
|
|
76
|
-
wireHTTP({
|
|
77
|
-
route: '/books/:id',
|
|
78
|
-
func: getBook,
|
|
79
|
-
middleware: [cacheControl],
|
|
80
|
-
})
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Global Middleware (`addGlobalMiddleware`)
|
|
84
|
-
|
|
85
|
-
Runs before everything else, across every wire type: HTTP, Queue, Channel, Trigger, Scheduler, Workflow, Agent, CLI, MCP. Use it for cross-cutting concerns (e.g. telemetry) that must wrap every invocation regardless of transport.
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
import { addGlobalMiddleware } from '@pikku/core'
|
|
89
|
-
import { telemetryOuter, telemetryInner } from '@pikku/core/middleware'
|
|
90
|
-
|
|
91
|
-
addGlobalMiddleware([telemetryOuter({ environmentId: env.STAGE_ID })]) // wraps the full call
|
|
92
|
-
addGlobalMiddleware([telemetryInner({ environmentId: env.STAGE_ID })]) // closest to the function body
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
`telemetryOuter` ships with `priority: 'highest'`, `telemetryInner` with `priority: 'lowest'` — so priority sorting places outer first regardless of array/call order.
|
|
96
|
-
|
|
97
|
-
## HTTP & Prefix Middleware (`addHTTPMiddleware`)
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
import { addHTTPMiddleware } from '@pikku/core/http'
|
|
101
|
-
import { cors, authBearer } from '@pikku/core/middleware'
|
|
102
|
-
|
|
103
|
-
// All routes
|
|
104
|
-
addHTTPMiddleware('*', [cors({ origin: 'https://app.example.com', credentials: true })])
|
|
105
|
-
|
|
106
|
-
// Scoped to /api/* prefix
|
|
107
|
-
addHTTPMiddleware('/api/*', [rateLimit({ maxRequests: 100, windowMs: 60_000 })])
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Tag Middleware (`addTagMiddleware`)
|
|
111
|
-
|
|
112
|
-
Tag middleware fires for any wiring (function or wire object) that carries a matching tag. This is the canonical approach for service-to-service bearer auth, rate limiting a group, or any cross-cutting concern scoped to a subset of routes.
|
|
113
|
-
|
|
114
|
-
### Setting Tags
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
// On the function definition
|
|
118
|
-
export const myFunc = pikkuSessionlessFunc({
|
|
119
|
-
auth: false,
|
|
120
|
-
tags: ['machine-agent'],
|
|
121
|
-
func: async (services, input) => { ... },
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
// On the wire object
|
|
125
|
-
wireHTTP({
|
|
126
|
-
route: '/internal/action',
|
|
127
|
-
method: 'post',
|
|
128
|
-
auth: false,
|
|
129
|
-
tags: ['internal'],
|
|
130
|
-
func: myFunc,
|
|
131
|
-
})
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
Tags from the function definition and the wire object are merged — middleware from both tag sets runs.
|
|
135
|
-
|
|
136
|
-
### Registering Tag Middleware
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
import { addTagMiddleware } from '.pikku/pikku-types.gen.js'
|
|
140
|
-
|
|
141
|
-
addTagMiddleware('machine-agent', [machineAgentBearerAuth])
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
Call at module load time — typically in the same `wirings/*.ts` file as the `wireHTTP` calls that use the tag.
|
|
145
|
-
|
|
146
|
-
## Middleware Execution Order
|
|
147
|
-
|
|
148
|
-
**Scope resolution order (broadest → narrowest):**
|
|
149
|
-
|
|
150
|
-
```text
|
|
151
|
-
global → httpGroup/* → httpGroup/prefix → wiringTags → wiringMiddleware → funcTags → funcMiddleware → function body
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
**Within each scope, sorted by priority:**
|
|
155
|
-
|
|
156
|
-
```text
|
|
157
|
-
highest → high → medium (default) → low → lowest
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
Set priority using the config-object form of `pikkuMiddleware`:
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
const earlyMiddleware = pikkuMiddleware({
|
|
164
|
-
name: 'early',
|
|
165
|
-
priority: 'highest', // 'highest' | 'high' | 'medium' | 'low' | 'lowest'
|
|
166
|
-
func: async (services, wire, next) => { ... },
|
|
167
|
-
})
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
Priority is the primary sort key; within the same level, registration order is preserved. Use priority when a middleware must run before/after others regardless of registration order (e.g. telemetry wrapping everything, session extraction before auth checks).
|
|
171
|
-
|
|
172
|
-
## Service-to-Service Bearer Auth (canonical pattern)
|
|
173
|
-
|
|
174
|
-
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`.
|
|
175
|
-
|
|
176
|
-
**On the server (the service being called):** tag the function, register a `pikkuMiddleware` that reads the `Authorization` header on that tag.
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
// lib/host-token.ts
|
|
180
|
-
let _token: string | null = null
|
|
181
|
-
export const setToken = (t: string) => { _token = t }
|
|
182
|
-
export const getToken = () => _token
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
// wirings/http.wiring.ts
|
|
187
|
-
import { timingSafeEqual } from 'node:crypto'
|
|
188
|
-
import { addTagMiddleware, pikkuMiddleware } from '../../.pikku/pikku-types.gen.js'
|
|
189
|
-
import { UnauthorizedError } from '@pikku/core/errors'
|
|
190
|
-
import { getToken } from '../lib/host-token.js'
|
|
191
|
-
|
|
192
|
-
const bearerAuth = pikkuMiddleware(async (_services, { http }, next) => {
|
|
193
|
-
const authHeader = http?.request?.header?.('authorization') || http?.request?.header?.('Authorization')
|
|
194
|
-
const token = getToken()
|
|
195
|
-
const expected = token ? `Bearer ${token}` : null
|
|
196
|
-
if (
|
|
197
|
-
!expected ||
|
|
198
|
-
!authHeader ||
|
|
199
|
-
authHeader.length !== expected.length ||
|
|
200
|
-
!timingSafeEqual(Buffer.from(authHeader), Buffer.from(expected))
|
|
201
|
-
) {
|
|
202
|
-
throw new UnauthorizedError()
|
|
203
|
-
}
|
|
204
|
-
return next()
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
addTagMiddleware('machine-agent', [bearerAuth])
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
```typescript
|
|
211
|
-
// functions/my.function.ts
|
|
212
|
-
export const myFunc = pikkuSessionlessFunc({
|
|
213
|
-
expose: true,
|
|
214
|
-
auth: false,
|
|
215
|
-
tags: ['machine-agent'],
|
|
216
|
-
func: async (services, input) => { ... },
|
|
217
|
-
})
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
**On the client (the caller):** use the generated `RPCInvoke` type — never hand-write a `fetch` wrapper's types. See `references/middleware-patterns.md`.
|
|
221
|
-
|
|
222
|
-
## More patterns
|
|
223
|
-
|
|
224
|
-
`references/middleware-patterns.md` covers the client-side `RPCInvoke` caller, session-setting middleware (set a session from an API key), and request logging / audit middleware.
|
|
225
|
-
|
|
226
|
-
## After Changes
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
pikku all # regenerate metadata so new tags are picked up
|
|
230
|
-
pikku all --tsc # regenerate, then type-check (fails on type errors)
|
|
231
|
-
```
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# Middleware Patterns (extended)
|
|
2
|
-
|
|
3
|
-
Detailed, less-common middleware recipes. The common-path bearer-auth pattern lives inline in SKILL.md; this file holds the client-side caller, session-setting, and audit recipes.
|
|
4
|
-
|
|
5
|
-
## Service-to-Service: the client (caller) side
|
|
6
|
-
|
|
7
|
-
Use the generated `RPCInvoke` type from `.pikku/rpc/pikku-rpc-wirings-map.gen.d.ts` — never hand-write the input/output types:
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
import type { RPCInvoke } from '../../backends/my-service/.pikku/rpc/pikku-rpc-wirings-map.gen.d.js'
|
|
11
|
-
|
|
12
|
-
export function getServiceRPC(baseUrl: string, token: string): RPCInvoke {
|
|
13
|
-
return async (name: string, data?: unknown) => {
|
|
14
|
-
const res = await fetch(`${baseUrl}/rpc/${String(name)}`, {
|
|
15
|
-
method: 'POST',
|
|
16
|
-
headers: {
|
|
17
|
-
'Content-Type': 'application/json',
|
|
18
|
-
Authorization: `Bearer ${token}`,
|
|
19
|
-
},
|
|
20
|
-
body: JSON.stringify({ data: data ?? {} }),
|
|
21
|
-
})
|
|
22
|
-
if (!res.ok) {
|
|
23
|
-
const text = await res.text().catch(() => '')
|
|
24
|
-
throw new Error(`rpc ${String(name)} failed: ${res.status} ${text}`)
|
|
25
|
-
}
|
|
26
|
-
return res.json()
|
|
27
|
-
} as RPCInvoke
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Session-Setting Middleware
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
const apiKeyAuth = pikkuMiddleware(async ({ kysely }, { http, setSession, session }, next) => {
|
|
35
|
-
if (session) return next() // already authenticated
|
|
36
|
-
|
|
37
|
-
const header = http?.request?.header?.('x-api-key')
|
|
38
|
-
if (!header) return next()
|
|
39
|
-
|
|
40
|
-
const row = await kysely.selectFrom('apiKey').select('userId').where('key', '=', header).executeTakeFirst()
|
|
41
|
-
if (row) setSession?.({ userId: row.userId })
|
|
42
|
-
|
|
43
|
-
return next()
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
addTagMiddleware('api-key-auth', [apiKeyAuth])
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Functions tagged `'api-key-auth'` with `auth: true` reject requests without a valid key; those with `auth: false` can inspect the session but won't reject.
|
|
50
|
-
|
|
51
|
-
## Request Logging / Audit
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
const auditLog = pikkuMiddleware(async ({ logger, db }, wire, next) => {
|
|
55
|
-
const start = Date.now()
|
|
56
|
-
await next()
|
|
57
|
-
await db.createAuditLog({ duration: Date.now() - start })
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
addHTTPMiddleware('/admin/*', [auditLog])
|
|
61
|
-
```
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-mongodb
|
|
3
|
-
description: >-
|
|
4
|
-
Use when setting up MongoDB database services in a Pikku app. Covers PikkuMongoDB connection,
|
|
5
|
-
channel stores, workflow services, secret services, AI storage, agent runs, and deployment
|
|
6
|
-
services. TRIGGER when: code uses PikkuMongoDB, MongoDBChannelStore, MongoDBWorkflowService,
|
|
7
|
-
MongoDBSecretService, or user asks about MongoDB setup with Pikku. DO NOT TRIGGER when: user
|
|
8
|
-
asks about SQL databases (use pikku-kysely) or Redis (use pikku-redis).
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Pikku MongoDB
|
|
12
|
-
|
|
13
|
-
## Agent Operating Procedure
|
|
14
|
-
|
|
15
|
-
Use this skill as an execution checklist, not reference material.
|
|
16
|
-
|
|
17
|
-
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.
|
|
18
|
-
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.
|
|
19
|
-
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
20
|
-
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.
|
|
21
|
-
5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
22
|
-
|
|
23
|
-
`@pikku/mongodb` provides MongoDB-backed implementations of Pikku's core service interfaces.
|
|
24
|
-
|
|
25
|
-
## Installation
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
yarn add @pikku/mongodb
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## API Reference
|
|
32
|
-
|
|
33
|
-
### `PikkuMongoDB` (Connection Wrapper)
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
import { PikkuMongoDB } from '@pikku/mongodb'
|
|
37
|
-
|
|
38
|
-
const mongo = new PikkuMongoDB(
|
|
39
|
-
logger: Logger,
|
|
40
|
-
clientOrUri: MongoClient | string,
|
|
41
|
-
dbName: string,
|
|
42
|
-
options?: MongoClientOptions
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
await mongo.init()
|
|
46
|
-
mongo.db // Db instance for queries
|
|
47
|
-
await mongo.close()
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Available Services
|
|
51
|
-
|
|
52
|
-
| Service | Interface | Purpose |
|
|
53
|
-
| --------------------------- | ------------------------------------- | ---------------------------------------------- |
|
|
54
|
-
| `MongoDBChannelStore` | `ChannelStore` | WebSocket channel state persistence |
|
|
55
|
-
| `MongoDBEventHubStore` | `EventHubStore` | Event hub state persistence |
|
|
56
|
-
| `MongoDBWorkflowService` | `PikkuWorkflowService` | Workflow definition storage |
|
|
57
|
-
| `MongoDBWorkflowRunService` | `WorkflowRunService` | Workflow execution tracking |
|
|
58
|
-
| `MongoDBDeploymentService` | `DeploymentService` | Deployment state management |
|
|
59
|
-
| `MongoDBAIStorageService` | `AIStorageService, AIRunStateService` | AI conversation/run storage |
|
|
60
|
-
| `MongoDBAgentRunService` | `AgentRunService` | Agent execution tracking |
|
|
61
|
-
| `MongoDBSecretService` | `SecretService` | Encrypted secret storage (envelope encryption) |
|
|
62
|
-
|
|
63
|
-
All services take a `Db` instance in their constructor and have an `init()` method that creates collections/indexes.
|
|
64
|
-
|
|
65
|
-
### Secret Service
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
import { MongoDBSecretService } from '@pikku/mongodb'
|
|
69
|
-
|
|
70
|
-
const secrets = new MongoDBSecretService(mongo.db, {
|
|
71
|
-
kekSecret: 'your-key-encryption-key',
|
|
72
|
-
salt: 'your-salt',
|
|
73
|
-
})
|
|
74
|
-
await secrets.init()
|
|
75
|
-
|
|
76
|
-
await secrets.setSecret('api-key', { key: 'sk-...' })
|
|
77
|
-
const value = await secrets.getSecret<{ key: string }>('api-key')
|
|
78
|
-
await secrets.rotateKEK()
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Usage Patterns
|
|
82
|
-
|
|
83
|
-
### Full Setup
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
import {
|
|
87
|
-
PikkuMongoDB,
|
|
88
|
-
MongoDBChannelStore,
|
|
89
|
-
MongoDBWorkflowService,
|
|
90
|
-
} from '@pikku/mongodb'
|
|
91
|
-
|
|
92
|
-
const createSingletonServices = pikkuServices(async (config) => {
|
|
93
|
-
const logger = new PinoLogger()
|
|
94
|
-
const mongo = new PikkuMongoDB(logger, config.mongoUri, 'myapp')
|
|
95
|
-
await mongo.init()
|
|
96
|
-
|
|
97
|
-
const channelStore = new MongoDBChannelStore(mongo.db)
|
|
98
|
-
await channelStore.init()
|
|
99
|
-
|
|
100
|
-
const workflowService = new MongoDBWorkflowService(mongo.db)
|
|
101
|
-
await workflowService.init()
|
|
102
|
-
|
|
103
|
-
return { config, logger, database: mongo, channelStore, workflowService }
|
|
104
|
-
})
|
|
105
|
-
```
|