@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,115 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-gateway-slack
|
|
3
|
-
description: >-
|
|
4
|
-
Use when integrating Slack with a Pikku app. Covers SlackGatewayAdapter, slash commands, OAuth
|
|
5
|
-
flow, message handling, and signature verification. TRIGGER when: code uses SlackGatewayAdapter,
|
|
6
|
-
parseSlashCommand, buildSlackInstallUrl, or user asks about Slack integration, Slack bots, or
|
|
7
|
-
@pikku/gateway-slack. DO NOT TRIGGER when: user asks about general gateway/webhook patterns (use
|
|
8
|
-
pikku-trigger).
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Pikku Gateway Slack
|
|
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/gateway-slack` provides a Slack Events API gateway adapter, slash command handling, OAuth installation flow, and message utilities.
|
|
24
|
-
|
|
25
|
-
## Installation
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
yarn add @pikku/gateway-slack @slack/web-api
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## API Reference
|
|
32
|
-
|
|
33
|
-
### `SlackGatewayAdapter`
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
import { SlackGatewayAdapter } from '@pikku/gateway-slack'
|
|
37
|
-
|
|
38
|
-
const adapter = new SlackGatewayAdapter(options: SlackGatewayAdapterOptions)
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Bridges Slack Events API webhooks with Pikku's gateway system for processing Slack events as Pikku functions.
|
|
42
|
-
|
|
43
|
-
### `SlackGatewayHelper`
|
|
44
|
-
|
|
45
|
-
Helper for handling Slack messages and metadata within gateway functions.
|
|
46
|
-
|
|
47
|
-
### Slash Commands
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
import { parseSlashCommand, respondToSlashCommand } from '@pikku/gateway-slack'
|
|
51
|
-
|
|
52
|
-
const command = parseSlashCommand(request)
|
|
53
|
-
await respondToSlashCommand(responseUrl, { text: 'Done!' })
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### OAuth Flow
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
import {
|
|
60
|
-
buildSlackInstallUrl,
|
|
61
|
-
exchangeSlackOAuthCode,
|
|
62
|
-
RECOMMENDED_BOT_SCOPES,
|
|
63
|
-
} from '@pikku/gateway-slack'
|
|
64
|
-
|
|
65
|
-
const installUrl = buildSlackInstallUrl({
|
|
66
|
-
clientId: config.slackClientId,
|
|
67
|
-
scopes: RECOMMENDED_BOT_SCOPES,
|
|
68
|
-
redirectUri: config.slackRedirectUri,
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
const tokens = await exchangeSlackOAuthCode({
|
|
72
|
-
clientId: config.slackClientId,
|
|
73
|
-
clientSecret: config.slackClientSecret,
|
|
74
|
-
code: oauthCode,
|
|
75
|
-
redirectUri: config.slackRedirectUri,
|
|
76
|
-
})
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Signature Verification
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
import { verifySlackSignature } from '@pikku/gateway-slack'
|
|
83
|
-
|
|
84
|
-
verifySlackSignature(signingSecret, timestamp, body, signature)
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Usage Patterns
|
|
88
|
-
|
|
89
|
-
### Slack Bot Gateway
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
import { SlackGatewayAdapter } from '@pikku/gateway-slack'
|
|
93
|
-
|
|
94
|
-
const slackGateway = new SlackGatewayAdapter({
|
|
95
|
-
signingSecret: config.slackSigningSecret,
|
|
96
|
-
botToken: config.slackBotToken,
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
// Register with your HTTP runner to handle /slack/events endpoint
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Slash Command Handler
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
const handleSlashCommand = pikkuSessionlessFunc({
|
|
106
|
-
title: 'Handle Slack Command',
|
|
107
|
-
func: async ({ db }, data) => {
|
|
108
|
-
const command = parseSlashCommand(data)
|
|
109
|
-
// Process command...
|
|
110
|
-
await respondToSlashCommand(command.response_url, {
|
|
111
|
-
text: `Processed: ${command.text}`,
|
|
112
|
-
})
|
|
113
|
-
},
|
|
114
|
-
})
|
|
115
|
-
```
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-http
|
|
3
|
-
description: >-
|
|
4
|
-
Use when adding HTTP routes, REST APIs, web endpoints, or SSE streams to a Pikku app. Covers
|
|
5
|
-
wireHTTP, defineHTTPRoutes, route groups, auth, middleware, SSE, and generated
|
|
6
|
-
fetch client. TRIGGER when: code uses wireHTTP/defineHTTPRoutes/wireHTTPRoutes, user asks about
|
|
7
|
-
REST endpoints, API routes, SSE, or the generated fetch client. DO NOT TRIGGER when: user asks
|
|
8
|
-
about WebSocket (use pikku-websocket), queue workers (use pikku-queue), or deployment (use
|
|
9
|
-
pikku-deploy-*).
|
|
10
|
-
installGroups: [core]
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# Pikku HTTP 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
|
-
Wire Pikku functions to HTTP endpoints. Supports single routes, composable route groups, auth, middleware, SSE, and auto-generated type-safe clients. (Authorization lives on the function, not the wiring — see `pikku-permissions`.)
|
|
26
|
-
|
|
27
|
-
## Before You Start
|
|
28
|
-
|
|
29
|
-
Run these commands to understand the current project:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
pikku info functions --verbose # See existing functions, their types, tags, middleware
|
|
33
|
-
pikku info tags --verbose # Understand project organization and naming conventions
|
|
34
|
-
pikku info middleware --verbose # See what middleware is already applied
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Follow existing patterns you find (naming, tag usage, file organization). See `pikku-concepts` for the core mental model.
|
|
38
|
-
|
|
39
|
-
## API Reference
|
|
40
|
-
|
|
41
|
-
- `wireHTTP(config)` (from `@pikku/core/http`) — wire one function to one endpoint.
|
|
42
|
-
- `defineHTTPRoutes(config)` + `wireHTTPRoutes(config)` (from `.pikku/pikku-types.gen.js`) — group routes with shared config; composable/nestable.
|
|
43
|
-
|
|
44
|
-
Function input/output types come from the function's own `input:`/`output:` zod schemas — never declared in the wiring. Route `:params`, query params, and body are merged into the function's `data` arg (see Data Flow).
|
|
45
|
-
|
|
46
|
-
Config cascading across groups: `basePath` concatenates down the chain, `tags` merge (union), `auth` child overrides parent.
|
|
47
|
-
|
|
48
|
-
For the full option tables (every `wireHTTP` field, the `defineHTTPRoutes`/`wireHTTPRoutes` config shape), read `references/http-options.md`.
|
|
49
|
-
|
|
50
|
-
### `addHTTPMiddleware(pattern, middlewares)`
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
addHTTPMiddleware('*', [authBearer()]) // All routes
|
|
54
|
-
addHTTPMiddleware('/api/*', [rateLimit()]) // Pattern match
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
> HTTP-route-level permissions (`addHTTPPermission`, a `permissions` field on the wiring) were removed in #972. Declare authorization on the function definition (`pikkuFunc({ permissions })`, see `pikku-permissions`), or app-wide via `addGlobalPermission`. Tags/patterns are for *middleware* only now.
|
|
58
|
-
|
|
59
|
-
## Data Flow
|
|
60
|
-
|
|
61
|
-
Pikku merges route params, query params, and request body into a single `data` object:
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
// POST /books/42?format=pdf with body { title: "New Title" }
|
|
65
|
-
wireHTTP({ method: 'post', route: '/books/:bookId', func: updateBook })
|
|
66
|
-
// → updateBook receives: { bookId: "42", format: "pdf", title: "New Title" }
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Usage Patterns
|
|
70
|
-
|
|
71
|
-
### Single Route
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
wireHTTP({
|
|
75
|
-
method: 'get',
|
|
76
|
-
route: '/books/:bookId',
|
|
77
|
-
func: getBook,
|
|
78
|
-
})
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Route Groups (Recommended for CRUD)
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
const booksRoutes = defineHTTPRoutes({
|
|
85
|
-
tags: ['books'],
|
|
86
|
-
routes: {
|
|
87
|
-
list: { method: 'get', route: '/books', func: listBooks, auth: false }, // per-route override
|
|
88
|
-
get: { method: 'get', route: '/books/:bookId', func: getBook },
|
|
89
|
-
create: { method: 'post', route: '/books', func: createBook },
|
|
90
|
-
delete: { method: 'delete', route: '/books/:bookId', func: deleteBook },
|
|
91
|
-
},
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
const todosRoutes = defineHTTPRoutes({
|
|
95
|
-
auth: false, // group-level default, overridable per-route
|
|
96
|
-
tags: ['todos'],
|
|
97
|
-
routes: {
|
|
98
|
-
list: { method: 'get', route: '/todos', func: listTodos },
|
|
99
|
-
},
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
wireHTTPRoutes({
|
|
103
|
-
basePath: '/api/v1',
|
|
104
|
-
middleware: [cors()],
|
|
105
|
-
routes: { books: booksRoutes, todos: todosRoutes },
|
|
106
|
-
})
|
|
107
|
-
// Results in: GET /api/v1/books, POST /api/v1/books, GET /api/v1/todos, etc.
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Auth
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
// Public route (no auth)
|
|
114
|
-
wireHTTP({ method: 'get', route: '/books', func: listBooks, auth: false })
|
|
115
|
-
|
|
116
|
-
// Authenticated route (default when a global auth middleware is set)
|
|
117
|
-
wireHTTP({ method: 'delete', route: '/books/:bookId', func: deleteBook })
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Authorization is not a wiring concern — declare it on the function via `permissions` (see `pikku-permissions`), or app-wide via `addGlobalPermission`.
|
|
121
|
-
|
|
122
|
-
### Middleware
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
import { cors, authBearer } from '@pikku/core/middleware'
|
|
126
|
-
|
|
127
|
-
// Global middleware
|
|
128
|
-
addHTTPMiddleware('*', [
|
|
129
|
-
cors({ origin: 'https://app.example.com', credentials: true }),
|
|
130
|
-
authBearer(),
|
|
131
|
-
])
|
|
132
|
-
|
|
133
|
-
// Scoped middleware
|
|
134
|
-
addHTTPMiddleware('/api/*', [rateLimit({ maxRequests: 100, windowMs: 60_000 })])
|
|
135
|
-
|
|
136
|
-
// Per-route middleware
|
|
137
|
-
wireHTTP({
|
|
138
|
-
method: 'delete',
|
|
139
|
-
route: '/books/:bookId',
|
|
140
|
-
func: deleteBook,
|
|
141
|
-
middleware: [auditLog],
|
|
142
|
-
})
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### SSE (Server-Sent Events)
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
wireHTTP({
|
|
149
|
-
method: 'get',
|
|
150
|
-
route: '/todos',
|
|
151
|
-
func: getTodos,
|
|
152
|
-
sse: true,
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
const getTodos = pikkuFunc({
|
|
156
|
-
title: 'Get Todos',
|
|
157
|
-
func: async ({ db, channel }, {}) => {
|
|
158
|
-
const todos = await db.getTodos()
|
|
159
|
-
|
|
160
|
-
if (channel) {
|
|
161
|
-
for (const todo of todos) {
|
|
162
|
-
channel.send({ todo })
|
|
163
|
-
await sleep(100)
|
|
164
|
-
}
|
|
165
|
-
return
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return { todos }
|
|
169
|
-
},
|
|
170
|
-
})
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Generated Fetch Client
|
|
174
|
-
|
|
175
|
-
After `npx pikku all`, a type-safe client is generated:
|
|
176
|
-
|
|
177
|
-
```typescript
|
|
178
|
-
import { pikkuFetch } from '.pikku/pikku-fetch.gen.js'
|
|
179
|
-
|
|
180
|
-
pikkuFetch.setServerUrl('http://localhost:4002')
|
|
181
|
-
|
|
182
|
-
const books = await pikkuFetch.get('/api/v1/books', {})
|
|
183
|
-
const book = await pikkuFetch.get('/api/v1/books/:bookId', { bookId: '42' })
|
|
184
|
-
const created = await pikkuFetch.post('/api/v1/books', {
|
|
185
|
-
title: 'The Pikku Guide',
|
|
186
|
-
author: 'You',
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
pikkuFetch.setAuthorizationJWT(token)
|
|
190
|
-
const deleted = await pikkuFetch.delete('/api/v1/books/:bookId', {
|
|
191
|
-
bookId: created.bookId,
|
|
192
|
-
})
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
## Complete Example
|
|
196
|
-
|
|
197
|
-
Functions live in their own files (one per file) and supply behavior + `permissions`; the wiring file imports them and wires routes. Sessionless funcs need no session; `pikkuFunc` does.
|
|
198
|
-
|
|
199
|
-
```typescript
|
|
200
|
-
// functions/books.functions.ts
|
|
201
|
-
import { pikkuFunc, pikkuSessionlessFunc } from '#pikku'
|
|
202
|
-
|
|
203
|
-
export const listBooks = pikkuSessionlessFunc({
|
|
204
|
-
title: 'List Books',
|
|
205
|
-
func: async ({ db }, { limit }) => ({ books: await db.listBooks(limit) }),
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
export const getBook = pikkuFunc({
|
|
209
|
-
title: 'Get Book',
|
|
210
|
-
description: 'Retrieve a book by ID',
|
|
211
|
-
func: async ({ db }, { bookId }) => await db.getBook(bookId),
|
|
212
|
-
permissions: { user: isAuthenticated },
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
// wirings/books.http.ts — same defineHTTPRoutes/wireHTTPRoutes shape as the Route Groups example above
|
|
216
|
-
import { addHTTPMiddleware } from '@pikku/core/http'
|
|
217
|
-
import { cors, authBearer } from '@pikku/core/middleware'
|
|
218
|
-
|
|
219
|
-
addHTTPMiddleware('*', [cors(), authBearer()])
|
|
220
|
-
```
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# wireHTTP / defineHTTPRoutes / wireHTTPRoutes — full option reference
|
|
2
|
-
|
|
3
|
-
## `wireHTTP(config)`
|
|
4
|
-
|
|
5
|
-
Wire a single function to an HTTP endpoint. Import from `@pikku/core/http`.
|
|
6
|
-
|
|
7
|
-
| Option | Type | Notes |
|
|
8
|
-
| --- | --- | --- |
|
|
9
|
-
| `method` | `'get' \| 'post' \| 'put' \| 'patch' \| 'delete' \| 'head'` | HTTP verb |
|
|
10
|
-
| `route` | `string` | e.g. `/books/:bookId` — `:params` become `data` fields |
|
|
11
|
-
| `func` | `PikkuFunc` | The function to call |
|
|
12
|
-
| `auth?` | `boolean` | Override default auth (`true` = require session) |
|
|
13
|
-
| `tags?` | `string[]` | For grouping, middleware targeting |
|
|
14
|
-
| `middleware?` | `PikkuMiddleware[]` | Per-route middleware |
|
|
15
|
-
| `sse?` | `boolean` | Enable Server-Sent Events |
|
|
16
|
-
| `contentType?` | `'xml' \| 'json'` | Response content type |
|
|
17
|
-
| `timeout?` | `number` | Request timeout in ms |
|
|
18
|
-
| `headers?` | `HTTPHeadersSchema` | Expected headers schema |
|
|
19
|
-
| `docs?` | `HTTPRouteDocsConfig` | OpenAPI docs config |
|
|
20
|
-
|
|
21
|
-
## `defineHTTPRoutes(config)` + `wireHTTPRoutes(config)`
|
|
22
|
-
|
|
23
|
-
Group routes with shared configuration. Groups are composable and nestable. Import from `.pikku/pikku-types.gen.js`.
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
const routes = defineHTTPRoutes({
|
|
27
|
-
basePath?: string, // Prepended to all route paths
|
|
28
|
-
tags?: string[], // Applied to all routes in group
|
|
29
|
-
auth?: boolean, // Default auth for all routes (overridable per-route)
|
|
30
|
-
middleware?: PikkuMiddleware[],
|
|
31
|
-
routes: {
|
|
32
|
-
[key: string]: {
|
|
33
|
-
method: string,
|
|
34
|
-
route: string,
|
|
35
|
-
func: PikkuFunc,
|
|
36
|
-
auth?: boolean, // Override group auth
|
|
37
|
-
middleware?: PikkuMiddleware[],
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
wireHTTPRoutes({
|
|
43
|
-
basePath?: string, // Top-level prefix (e.g. '/api/v1')
|
|
44
|
-
middleware?: PikkuMiddleware[],
|
|
45
|
-
routes: {
|
|
46
|
-
[key: string]: ReturnType<typeof defineHTTPRoutes>,
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Config cascading rules:
|
|
52
|
-
|
|
53
|
-
- `basePath` — concatenates down the chain
|
|
54
|
-
- `tags` — merge (union)
|
|
55
|
-
- `auth` — child overrides parent
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-i18n
|
|
3
|
-
description: 'Wire i18n into a Pikku frontend with Paraglide JS (inlang). English by default, every user-facing string is a typed message function (`m.some__key()`) compiled from `messages/<locale>.json`, and additional languages are served under `/fr` `/de` URL prefixes. TRIGGER when: scaffolding or editing a frontend and writing user-facing text, adding a second language, or asked to "make this translatable / use tokens / add i18n". DO NOT TRIGGER for backend functions, error messages thrown from functions, or log output.'
|
|
4
|
-
installGroups: [core]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Pikku i18n (Paraglide JS)
|
|
8
|
-
|
|
9
|
-
## Agent Operating Procedure
|
|
10
|
-
|
|
11
|
-
Use this skill as an execution checklist, not reference material.
|
|
12
|
-
|
|
13
|
-
1. Every user-facing string in a frontend is a message. Never hardcode display text — add a key to `messages/en.json` and render `m.the__key()`. This holds even when the app ships only English; the messages are the seam a second language slots into later.
|
|
14
|
-
2. One `messages/<locale>.json` per language at the app root (NOT under `src/`), declared in `project.inlang/settings.json`. English (`en`) is `baseLocale` and the only locale until someone adds another.
|
|
15
|
-
3. Messages compile to typed ESM functions in `src/paraglide/` (generated, self-gitignored — never edit or commit it). The Vite plugin compiles during `dev`/`build` with HMR on message edits; run the CLI compile only when you need `tsc` before Vite has ever run.
|
|
16
|
-
4. Validate with the app's own `tsc` then its `build`. The deploy pipeline compiles Paraglide and runs each frontend's `tsc` before building it — an i18n mistake blocks the deploy.
|
|
17
|
-
|
|
18
|
-
## The moving parts (starter-template layout)
|
|
19
|
-
|
|
20
|
-
- `messages/en.json` — flat keys, `{param}` interpolation, inlang message-format:
|
|
21
|
-
```json
|
|
22
|
-
{
|
|
23
|
-
"$schema": "https://inlang.com/schema/inlang-message-format",
|
|
24
|
-
"auth__login__title": "Sign in",
|
|
25
|
-
"auth__login__description": "Welcome back to {name}."
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
Key convention: lower snake_case, `__` (double underscore) between namespace segments, `_` within a segment — `auth__login__title`, `common__email_placeholder`.
|
|
29
|
-
- `project.inlang/settings.json` — `baseLocale`, `locales`, the `@inlang/plugin-message-format` module, `pathPattern: "./messages/{locale}.json"`.
|
|
30
|
-
- `vite.config.ts` — `paraglideVitePlugin({ project: './project.inlang', outdir: './src/paraglide' })` from `@inlang/paraglide-js` (devDependency), FIRST in the plugins array.
|
|
31
|
-
- `src/paraglide/` — compiled output (`messages.js`, `runtime.js`, per-locale `messages/*.js`). Generated; it writes its own `.gitignore`.
|
|
32
|
-
- `src/i18n/config.ts` — locale plumbing, and the ONLY hand-written i18n module: `supportedLocales`/`defaultLocale` (re-exported from `../paraglide/runtime.js`), `detectLocale`, `localeDir` (RTL for ar/he/fa/ur), a reactive locale store (`overwriteGetLocale` bridged to `useSyncExternalStore`), `setActiveLocale`, `useLocale()`. This is not a wrapper over messages — Paraglide's `getLocale()` is a module global with no React reactivity, and this bridges it. Wire `overwriteGetLocale` or `m.*()` will resolve a different locale than the app thinks is active.
|
|
33
|
-
- `tsconfig.json` — `"allowJs": true, "checkJs": false` so `tsc` can consume Paraglide's JSDoc-typed JS output.
|
|
34
|
-
|
|
35
|
-
## Using messages in components
|
|
36
|
-
|
|
37
|
-
```tsx
|
|
38
|
-
import { m } from '../paraglide/messages.js'
|
|
39
|
-
import { useLocale } from '@/i18n/config'
|
|
40
|
-
|
|
41
|
-
function LoginPage() {
|
|
42
|
-
useLocale() // subscribe: re-render m.*() when the locale switches
|
|
43
|
-
return (
|
|
44
|
-
<>
|
|
45
|
-
<Title>{m.auth__login__title()}</Title>
|
|
46
|
-
<Text>{m.auth__login__description({ name: m.app__name() })}</Text>
|
|
47
|
-
</>
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
- Params: `{name}` in the JSON → `m.auth__login__description({ name })`. Params are typed per message.
|
|
53
|
-
- Any component that renders `m.*()` calls `useLocale()` (bare call is enough); it also returns `{ locale, dir, setLocale }` for switchers.
|
|
54
|
-
- Non-component helpers (formatters, status maps) call `m.some__key()` directly — the functions are plain ESM, no hook needed; the render-time subscription lives in the component that displays the result.
|
|
55
|
-
- Locale switching: the root route persists to localStorage, sets `<html lang dir>` (`localeDir`), and calls `setActiveLocale` — in-SPA re-render, no page reload. Mirror `routes/__root.tsx` in the starter template.
|
|
56
|
-
|
|
57
|
-
## Keys only known at runtime (enum labels, status maps)
|
|
58
|
-
|
|
59
|
-
A DB value picking a label (`enums__document_status__${status}`) is the one case a
|
|
60
|
-
generated message can't express. Paraglide's README (§ "What about dynamic or
|
|
61
|
-
CMS-driven keys?") is explicit: use an **explicit mapping from value to message
|
|
62
|
-
function**. Key it on the enum type, never `string`:
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
import { m } from '../paraglide/messages.js'
|
|
66
|
-
|
|
67
|
-
const DOCUMENT_STATUS_LABEL: Record<DocumentStatus, () => string> = {
|
|
68
|
-
completed: m.enums__document_status__completed,
|
|
69
|
-
in_progress: m.enums__document_status__in_progress,
|
|
70
|
-
required: m.enums__document_status__required,
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// call site — no fallback, because there is no missing case
|
|
74
|
-
DOCUMENT_STATUS_LABEL[status]()
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
`Record<DocumentStatus, …>` is exhaustive: add a value to the enum without a
|
|
78
|
-
label and the build fails. That is the entire point.
|
|
79
|
-
|
|
80
|
-
Do NOT write `Record<string, () => string>` with a `?? status` fallback, and do
|
|
81
|
-
NOT index the namespace with a computed key (`m[\`enums__${name}__${value}\`]`).
|
|
82
|
-
Both compile, both render the raw identifier to users when a label is missing,
|
|
83
|
-
and both reintroduce exactly the silent-fallback failure Paraglide exists to
|
|
84
|
-
eliminate. If you find yourself writing a `resolveDynamicKey(key: string)`
|
|
85
|
-
helper, stop — that helper IS the bug.
|
|
86
|
-
|
|
87
|
-
## Type safety — and why deploys block on i18n
|
|
88
|
-
|
|
89
|
-
A message IS a function: a typo'd or deleted key (`m.auth__login__titel()`) is a missing export — a **TypeScript error**, not a silent runtime fallback string. Params are typed too. The deploy pipeline compiles Paraglide then runs each frontend's `tsc` (`"tsc": "tsc --noEmit"` script — keep it in every frontend's `package.json`) **before** building; a type error aborts the deploy. `vite build` does not type-check on its own, so this gate is the only thing standing between a broken message and production.
|
|
90
|
-
|
|
91
|
-
The gate catches _invalid_ messages but not _inlined_ strings. The `@pikku/mantine` `I18nNode` prop typing catches those: a raw string literal fails to compile on a gated prop, because `I18nString` is a branded type a bare `string` can't satisfy. Between the two, `tsc` is the whole safety net — there is no runtime fallback to inspect, by design.
|
|
92
|
-
|
|
93
|
-
## Compile step
|
|
94
|
-
|
|
95
|
-
- **Dev/build:** the Vite plugin compiles automatically; editing `messages/*.json` under a running dev server recompiles + HMRs.
|
|
96
|
-
- **Standalone `tsc` before Vite has run** (fresh clone, CI):
|
|
97
|
-
```sh
|
|
98
|
-
npx @inlang/paraglide-js compile --project ./project.inlang --outdir ./src/paraglide
|
|
99
|
-
```
|
|
100
|
-
This is exactly what the deploy CI does before the per-app `tsc`.
|
|
101
|
-
|
|
102
|
-
## Adding a second language
|
|
103
|
-
|
|
104
|
-
1. `messages/fr.json` mirroring `en.json`'s keys (translate the values, keep `{param}` names identical).
|
|
105
|
-
2. Add `"fr"` to `locales` in `project.inlang/settings.json`.
|
|
106
|
-
3. Recompile (restart/`vite dev` or the CLI compile). A locale file missing keys falls back to the base locale per message.
|
|
107
|
-
4. Content is reachable via the `/<lang>` URL prefix (`detectLocale` already resolves it); the base locale needs no prefix. Expose the switcher via `useLocale().setLocale`.
|
|
108
|
-
|
|
109
|
-
## i18n debug mode (find inlined strings)
|
|
110
|
-
|
|
111
|
-
`tsc` catches invalid messages, and the `@pikku/mantine` gate catches raw strings on gated props — but neither sees a hardcoded string in plain JSX, an `aria-label`, `alt`, `document.title`, or anything passed to a non-Mantine component. Debug mode covers that gap: render every message as block glyphs (`█`), and whatever is still readable never went through a message.
|
|
112
|
-
|
|
113
|
-
**Build it as a generated locale, never as a runtime wrapper.** Masked text is text, and rendering different text per locale is what Paraglide already does:
|
|
114
|
-
|
|
115
|
-
1. A script generates `messages/zz.json` from `en.json`, replacing `\S` with `█` while leaving `{placeholders}` intact (they are message inputs — mangling them changes the compiled signature). Run it before `paraglide-js compile`; gitignore the output.
|
|
116
|
-
2. Add `"zz"` to `locales` in `project.inlang/settings.json`.
|
|
117
|
-
3. Switch to it in the locale bridge:
|
|
118
|
-
```ts
|
|
119
|
-
overwriteGetLocale(() => (isI18nDebug() ? 'zz' : activeLocale))
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Keep `zz` out of the app's own `supportedLocales` — that drives URL prefixes, hreflang and any backend `locale` param, none of which should see it.
|
|
123
|
-
|
|
124
|
-
Generate the catalogue in dev only. With `messages/zz.json` absent, Paraglide compiles `zz` to an alias of the base locale (`const zz_x = en_x` — one line per message, no duplicated strings), so a production bundle carries the locale at effectively zero cost.
|
|
125
|
-
|
|
126
|
-
Both the generator and the store bridge are being upstreamed (pikkujs/pikku#1036, #1035).
|
|
127
|
-
|
|
128
|
-
The wrapper alternative — a module that walks the namespace and pipes each message through a `mask()` — is what this replaces. It defeats tree-shaking (touching every export), adds a check on every call, and forces every component to import `m` from the wrapper instead of Paraglide.
|
|
129
|
-
|
|
130
|
-
## What NOT to do
|
|
131
|
-
|
|
132
|
-
- Don't hardcode display strings "just for now" — the message is the work.
|
|
133
|
-
- Don't edit or commit anything under `src/paraglide/` — it's regenerated; change `messages/*.json` instead.
|
|
134
|
-
- **Don't wrap `m`.** No re-export module, no branding layer, no resolver. Components import `m` from `../paraglide/messages.js` and call it. `@pikku/react`'s `I18nString` is declared as `string & { readonly __brand: 'LocalizedString' }` — deliberately identical to Paraglide's own `LocalizedString` — so `m.some__key()` satisfies the `@pikku/mantine` `I18nNode` gate natively. A wrapper adds nothing and costs per-message tree-shaking.
|
|
135
|
-
- Don't re-resolve messages by string key or re-implement `{param}` interpolation. A key-string resolver turns a missing key back into silent runtime text, surrendering the type safety that is the entire reason to use Paraglide.
|
|
136
|
-
- Don't reach for i18next/react-i18next or a runtime-fetch translation loader — Paraglide's compiled functions are the whole delivery mechanism.
|
|
137
|
-
- Don't tokenize backend error messages or logs here — those are not frontend display strings.
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-info
|
|
3
|
-
description: >-
|
|
4
|
-
Discover what exists in a Pikku project — functions, tags, middleware, permissions, HTTP routes,
|
|
5
|
-
channels, schedulers, queues, and more. Use when you need to understand the project structure,
|
|
6
|
-
find existing functions, or check what middleware and permissions are defined. TRIGGER when:
|
|
7
|
-
user asks "what functions exist?", "show me the project structure", "list
|
|
8
|
-
routes/middleware/permissions", or needs to understand an existing Pikku codebase. DO NOT
|
|
9
|
-
TRIGGER when: user is writing new code (use the specific wiring skill) or asking about Pikku
|
|
10
|
-
concepts (use pikku-concepts).
|
|
11
|
-
installGroups: [core]
|
|
12
|
-
allowed-tools: Bash(yarn pikku info *)
|
|
13
|
-
argument-hint: '[functions|tags|middleware|permissions] [--verbose] [--limit N]'
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
# Pikku Project Discovery
|
|
17
|
-
|
|
18
|
-
## Agent Operating Procedure
|
|
19
|
-
|
|
20
|
-
Use this skill as an execution checklist, not reference material.
|
|
21
|
-
|
|
22
|
-
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.
|
|
23
|
-
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.
|
|
24
|
-
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
25
|
-
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.
|
|
26
|
-
5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
27
|
-
|
|
28
|
-
Use the `pikku info` CLI commands to inspect this Pikku project. Run the commands below and present the results to the user in a clear summary.
|
|
29
|
-
|
|
30
|
-
## Available Commands
|
|
31
|
-
|
|
32
|
-
Always use `--silent` to suppress the banner and inspector logs.
|
|
33
|
-
|
|
34
|
-
### Functions
|
|
35
|
-
|
|
36
|
-
List all registered pikku functions:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
yarn pikku info functions --silent
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
For full details including transport type (http/channel/scheduler/queue/workflow/mcp/cli/trigger), middleware, permissions, and source file:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
yarn pikku info functions --verbose --silent
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Tags
|
|
49
|
-
|
|
50
|
-
List all tags with counts of associated functions and middleware:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
yarn pikku info tags --silent
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
For full names instead of counts:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
yarn pikku info tags --verbose --silent
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Middleware
|
|
63
|
-
|
|
64
|
-
List all middleware definitions:
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
yarn pikku info middleware --silent
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
For full details including source file, required services, and description:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
yarn pikku info middleware --verbose --silent
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Permissions
|
|
77
|
-
|
|
78
|
-
List all permission definitions:
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
yarn pikku info permissions --silent
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
For full details including source file, required services, and description:
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
yarn pikku info permissions --verbose --silent
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Instructions
|
|
91
|
-
|
|
92
|
-
1. If the user specifies a subcommand (e.g., `/pikku-info functions`), run only that command.
|
|
93
|
-
2. If no subcommand is specified, run all four commands to give a complete project overview.
|
|
94
|
-
3. Always use `--silent` to suppress the Pikku banner and inspector logs.
|
|
95
|
-
4. Use `--verbose` when the user asks for details, file paths, or "more info".
|
|
96
|
-
5. Use `--limit N` to control output size (default is 50 rows).
|
|
97
|
-
6. After running the commands, summarize the findings concisely:
|
|
98
|
-
- Total count of functions, tags, middleware, and permissions
|
|
99
|
-
- Notable patterns (e.g., which transport types are in use, which tags group the most functions)
|
|
100
|
-
- Any functions without tags or transport types (potential issues)
|