@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.
Files changed (264) hide show
  1. package/LICENSE +106 -0
  2. package/README.md +25 -2
  3. package/console-app/assets/{index-CSzCJzBb.css → index-D0HG8q0B.css} +1 -1
  4. package/console-app/assets/{index-C5Bd44e4.js → index-DDpIMCpy.js} +149 -149
  5. package/console-app/index.html +2 -2
  6. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  7. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  8. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  9. package/dist/.pikku/cli/pikku-cli-channel.js +6 -1
  10. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  11. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  12. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  13. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  14. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.json +15 -0
  15. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  16. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  17. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  18. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +43 -0
  19. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  20. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  21. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  22. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  23. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  24. package/dist/.pikku/function/pikku-function-types.gen.d.ts +4 -4
  25. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  26. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  27. package/dist/.pikku/function/pikku-functions-meta.gen.json +39 -44
  28. package/dist/.pikku/function/pikku-functions.gen.js +1 -3
  29. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  30. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  31. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  32. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  33. package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +9 -0
  34. package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +9 -0
  35. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  36. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  37. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  38. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  39. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  40. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  41. package/dist/.pikku/pikku-types.gen.js +1 -1
  42. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  43. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  44. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  45. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  46. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  47. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  48. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +1 -1
  49. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.d.ts +1 -0
  50. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +10 -0
  51. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.json +1 -0
  52. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +4 -0
  53. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.js +1 -0
  54. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.d.ts +1 -0
  55. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +10 -0
  56. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +4 -0
  57. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.js +1 -0
  58. package/dist/.pikku/scenarios/schemas/register.gen.d.ts +4 -0
  59. package/dist/.pikku/scenarios/schemas/register.gen.js +4 -0
  60. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  61. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  62. package/dist/.pikku/schemas/register.gen.js +5 -3
  63. package/dist/.pikku/schemas/schemas/FabricSecretsListOutput.schema.json +1 -1
  64. package/dist/.pikku/schemas/schemas/FabricSecretsRotateInput.schema.json +1 -0
  65. package/dist/.pikku/schemas/schemas/FabricSecretsRotateOutput.schema.json +1 -0
  66. package/dist/.pikku/schemas/schemas/FabricSecretsSetOutput.schema.json +1 -1
  67. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  68. package/dist/.pikku/schemas/schemas/ScenarioRunInput.schema.json +1 -1
  69. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
  70. package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
  71. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  72. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  73. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  74. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  75. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  76. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  77. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  78. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  79. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  80. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  81. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  82. package/dist/.pikku/workflow/meta/allWorkflow.gen.json +2 -8
  83. package/dist/.pikku/workflow/pikku-scenario-actors.gen.d.ts +19 -0
  84. package/dist/.pikku/workflow/pikku-scenario-actors.gen.js +17 -0
  85. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +152 -3
  86. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +39 -1
  87. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  88. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  89. package/dist/bin/pikku-bin.mjs +2 -2
  90. package/dist/src/cli.wiring.js +28 -0
  91. package/dist/src/deploy/analyzer/analyzer.js +22 -5
  92. package/dist/src/deploy/build-pipeline.js +5 -1
  93. package/dist/src/fabric/fabric-commands.d.ts +37 -9
  94. package/dist/src/fabric/fabric-commands.js +12 -0
  95. package/dist/src/fabric/functions/domains-add.function.d.ts +4 -4
  96. package/dist/src/fabric/functions/secrets-list.function.d.ts +16 -4
  97. package/dist/src/fabric/functions/secrets-list.function.js +12 -10
  98. package/dist/src/fabric/functions/secrets-rotate.function.d.ts +24 -0
  99. package/dist/src/fabric/functions/secrets-rotate.function.js +36 -0
  100. package/dist/src/fabric/functions/secrets-set.function.d.ts +8 -4
  101. package/dist/src/fabric/functions/secrets-set.function.js +18 -7
  102. package/dist/src/fabric/lib/http.d.ts +7 -1
  103. package/dist/src/fabric/lib/sealed-box.d.ts +16 -0
  104. package/dist/src/fabric/lib/sealed-box.js +72 -0
  105. package/dist/src/functions/commands/dev.js +11 -0
  106. package/dist/src/functions/commands/load-user-project.d.ts +7 -0
  107. package/dist/src/functions/commands/load-user-project.js +21 -0
  108. package/dist/src/functions/commands/pikku-command-bootstrap.js +13 -0
  109. package/dist/src/functions/commands/scenario-browser.d.ts +84 -0
  110. package/dist/src/functions/commands/scenario-browser.js +68 -0
  111. package/dist/src/functions/commands/scenario-environment.d.ts +32 -0
  112. package/dist/src/functions/commands/scenario-environment.js +61 -0
  113. package/dist/src/functions/commands/scenario-formatter.d.ts +81 -0
  114. package/dist/src/functions/commands/scenario-formatter.js +120 -0
  115. package/dist/src/functions/commands/scenario-ladder.d.ts +66 -0
  116. package/dist/src/functions/commands/scenario-ladder.js +132 -0
  117. package/dist/src/functions/commands/scenario-plan.d.ts +61 -0
  118. package/dist/src/functions/commands/scenario-plan.js +106 -0
  119. package/dist/src/functions/commands/scenario.d.ts +24 -0
  120. package/dist/src/functions/commands/scenario.js +322 -50
  121. package/dist/src/functions/commands/serve.js +2 -0
  122. package/dist/src/functions/commands/skills.js +27 -61
  123. package/dist/src/functions/db/db-codegen.d.ts +6 -0
  124. package/dist/src/functions/db/db-codegen.js +9 -0
  125. package/dist/src/functions/db/db-migrator.js +14 -0
  126. package/dist/src/functions/db/local-db.d.ts +8 -0
  127. package/dist/src/functions/db/local-db.js +24 -2
  128. package/dist/src/functions/db/migration-identifiers.d.ts +58 -0
  129. package/dist/src/functions/db/migration-identifiers.js +262 -0
  130. package/dist/src/functions/db/migration-provenance.d.ts +35 -0
  131. package/dist/src/functions/db/migration-provenance.js +80 -0
  132. package/dist/src/functions/db/schema-sql.d.ts +43 -0
  133. package/dist/src/functions/db/schema-sql.js +135 -0
  134. package/dist/src/functions/db/sqlite/sqlite-kysely.js +22 -2
  135. package/dist/src/functions/wirings/functions/pikku-command-functions.js +26 -8
  136. package/dist/src/functions/wirings/functions/schemas.js +13 -1
  137. package/dist/src/functions/wirings/functions/serialize-function-types.js +3 -3
  138. package/dist/src/functions/wirings/rpc/pikku-command-rpc.js +6 -1
  139. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.d.ts +10 -0
  140. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +102 -0
  141. package/dist/src/functions/wirings/scenarios/scenario-partition.d.ts +42 -0
  142. package/dist/src/functions/wirings/scenarios/scenario-partition.js +71 -0
  143. package/dist/src/functions/wirings/scenarios/scenario-schema-partition.d.ts +33 -0
  144. package/dist/src/functions/wirings/scenarios/scenario-schema-partition.js +49 -0
  145. package/dist/src/functions/wirings/scenarios/serialize-feature-meta.d.ts +14 -0
  146. package/dist/src/functions/wirings/scenarios/serialize-feature-meta.js +29 -0
  147. package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.d.ts +12 -0
  148. package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.js +56 -0
  149. package/dist/src/functions/wirings/scenarios/serialize-scenario-registration.d.ts +7 -0
  150. package/dist/src/functions/wirings/scenarios/serialize-scenario-registration.js +40 -0
  151. package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +43 -8
  152. package/dist/src/functions/wirings/workflow/serialize-scenario-actors.d.ts +1 -1
  153. package/dist/src/functions/wirings/workflow/serialize-scenario-actors.js +13 -2
  154. package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.d.ts +4 -0
  155. package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.js +62 -0
  156. package/dist/src/functions/wirings/workflow/serialize-workflow-bootstrap-map.js +10 -3
  157. package/dist/src/functions/wirings/workflow/serialize-workflow-map.js +10 -3
  158. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +4 -4
  159. package/dist/src/functions/wirings/workflow/serialize-workflow-types.d.ts +1 -1
  160. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +232 -3
  161. package/dist/src/functions/workflows/all.workflow.js +2 -7
  162. package/dist/src/server/server-ready.d.ts +12 -0
  163. package/dist/src/server/server-ready.js +12 -0
  164. package/dist/src/server/spawn-dev-server.d.ts +50 -0
  165. package/dist/src/server/spawn-dev-server.js +112 -0
  166. package/dist/src/services.js +12 -1
  167. package/dist/src/utils/file-writer.js +14 -2
  168. package/dist/src/utils/meta-diff.js +5 -2
  169. package/dist/src/utils/pikku-cli-config.d.ts +14 -0
  170. package/dist/src/utils/pikku-cli-config.js +60 -0
  171. package/dist/src/utils/remove-legacy-scaffold-file.d.ts +14 -0
  172. package/dist/src/utils/remove-legacy-scaffold-file.js +23 -0
  173. package/dist/src/utils/resolve-scenario-actors.d.ts +23 -0
  174. package/dist/src/utils/resolve-scenario-actors.js +74 -0
  175. package/dist/src/utils/serialize-schemas.d.ts +3 -1
  176. package/dist/src/utils/serialize-schemas.js +39 -4
  177. package/dist/tsconfig.tsbuildinfo +1 -1
  178. package/package.json +18 -8
  179. package/dist/.pikku/schemas/schemas/PikkuScenarioFunctionsOutput.schema.json +0 -1
  180. package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.d.ts +0 -1
  181. package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.js +0 -31
  182. package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.d.ts +0 -10
  183. package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.js +0 -104
  184. package/skills/pikku-addon/SKILL.md +0 -243
  185. package/skills/pikku-addon/references/addon-package-manifest.md +0 -63
  186. package/skills/pikku-ai-agent/SKILL.md +0 -231
  187. package/skills/pikku-ai-vercel/SKILL.md +0 -82
  188. package/skills/pikku-ai-voice/SKILL.md +0 -88
  189. package/skills/pikku-audit/SKILL.md +0 -175
  190. package/skills/pikku-aws/SKILL.md +0 -111
  191. package/skills/pikku-backblaze/SKILL.md +0 -71
  192. package/skills/pikku-better-auth/SKILL.md +0 -298
  193. package/skills/pikku-cli/SKILL.md +0 -198
  194. package/skills/pikku-cli/references/complete-example.md +0 -82
  195. package/skills/pikku-concepts/SKILL.md +0 -250
  196. package/skills/pikku-concepts/references/concept-mapping.md +0 -556
  197. package/skills/pikku-concepts/references/packages.md +0 -29
  198. package/skills/pikku-config/SKILL.md +0 -212
  199. package/skills/pikku-cron/SKILL.md +0 -214
  200. package/skills/pikku-deploy-azure/SKILL.md +0 -71
  201. package/skills/pikku-deploy-cloudflare/SKILL.md +0 -82
  202. package/skills/pikku-deploy-express/SKILL.md +0 -86
  203. package/skills/pikku-deploy-fastify/SKILL.md +0 -73
  204. package/skills/pikku-deploy-lambda/SKILL.md +0 -110
  205. package/skills/pikku-deploy-nextjs/SKILL.md +0 -78
  206. package/skills/pikku-deploy-uws/SKILL.md +0 -88
  207. package/skills/pikku-deps/SKILL.md +0 -98
  208. package/skills/pikku-emails/SKILL.md +0 -163
  209. package/skills/pikku-fabric/SKILL.md +0 -318
  210. package/skills/pikku-fabric-debug/SKILL.md +0 -112
  211. package/skills/pikku-feature/SKILL.md +0 -258
  212. package/skills/pikku-gateway-slack/SKILL.md +0 -115
  213. package/skills/pikku-http/SKILL.md +0 -220
  214. package/skills/pikku-http/references/http-options.md +0 -55
  215. package/skills/pikku-i18n/SKILL.md +0 -137
  216. package/skills/pikku-info/SKILL.md +0 -100
  217. package/skills/pikku-jose/SKILL.md +0 -105
  218. package/skills/pikku-kysely/SKILL.md +0 -219
  219. package/skills/pikku-machine-auth/SKILL.md +0 -183
  220. package/skills/pikku-mcp/SKILL.md +0 -241
  221. package/skills/pikku-middleware/SKILL.md +0 -231
  222. package/skills/pikku-middleware/references/middleware-patterns.md +0 -61
  223. package/skills/pikku-mongodb/SKILL.md +0 -105
  224. package/skills/pikku-n8n-import/SKILL.md +0 -109
  225. package/skills/pikku-n8n-import/SPEC.md +0 -84
  226. package/skills/pikku-n8n-import/references/addon-mapping.md +0 -121
  227. package/skills/pikku-n8n-import/references/code-translation.md +0 -121
  228. package/skills/pikku-n8n-import/references/loops-and-control.md +0 -87
  229. package/skills/pikku-paraglide/SKILL.md +0 -117
  230. package/skills/pikku-permissions/SKILL.md +0 -192
  231. package/skills/pikku-pino/SKILL.md +0 -79
  232. package/skills/pikku-product-second-opinion/README.md +0 -43
  233. package/skills/pikku-product-second-opinion/SKILL.md +0 -158
  234. package/skills/pikku-product-second-opinion/example/sample-report.md +0 -90
  235. package/skills/pikku-product-second-opinion/references/report-template.md +0 -73
  236. package/skills/pikku-queue/SKILL.md +0 -240
  237. package/skills/pikku-react/SKILL.md +0 -212
  238. package/skills/pikku-react-query/SKILL.md +0 -242
  239. package/skills/pikku-realtime/SKILL.md +0 -236
  240. package/skills/pikku-realtime/references/other-routes.md +0 -23
  241. package/skills/pikku-redis/SKILL.md +0 -90
  242. package/skills/pikku-rpc/SKILL.md +0 -171
  243. package/skills/pikku-rtl/SKILL.md +0 -219
  244. package/skills/pikku-scenario/SKILL.md +0 -215
  245. package/skills/pikku-schedule/SKILL.md +0 -57
  246. package/skills/pikku-schema-ajv/SKILL.md +0 -62
  247. package/skills/pikku-schema-cfworker/SKILL.md +0 -63
  248. package/skills/pikku-security/SKILL.md +0 -108
  249. package/skills/pikku-services/SKILL.md +0 -248
  250. package/skills/pikku-services/references/audit-wire-service.md +0 -34
  251. package/skills/pikku-software-archaeology/README.md +0 -70
  252. package/skills/pikku-software-archaeology/SKILL.md +0 -186
  253. package/skills/pikku-software-archaeology/references/blueprint.schema.json +0 -625
  254. package/skills/pikku-software-archaeology/references/pikku-mapping.md +0 -49
  255. package/skills/pikku-software-archaeology/scripts/validate.mjs +0 -173
  256. package/skills/pikku-tag-middleware/SKILL.md +0 -13
  257. package/skills/pikku-template-clone/SKILL.md +0 -40
  258. package/skills/pikku-trigger/SKILL.md +0 -181
  259. package/skills/pikku-versioning/SKILL.md +0 -173
  260. package/skills/pikku-websocket/SKILL.md +0 -243
  261. package/skills/pikku-workflow/SKILL.md +0 -172
  262. package/skills/pikku-workflow/references/workflow-reference.md +0 -63
  263. package/skills/pikku-workflows-client/SKILL.md +0 -150
  264. package/skills/pikku-ws/SKILL.md +0 -47
@@ -1,108 +0,0 @@
1
- ---
2
- name: pikku-security
3
- description: >-
4
- Use when adding authentication or session management to a Pikku app — pikkuAuth, session
5
- lifecycle (setSession/clearSession), built-in auth strategies (authBearer, authCookie,
6
- authAPIKey), or JWT setup. TRIGGER when: user asks about login, logout, session, bearer tokens,
7
- cookie auth, API keys, or JWT. DO NOT TRIGGER when: user asks about middleware (use
8
- pikku-middleware), permissions/authorization checks (use pikku-permissions), or secrets/env vars
9
- (use pikku-config).
10
- installGroups: [core]
11
- ---
12
-
13
- # Pikku Security (Authentication & Sessions)
14
-
15
- ## Agent Operating Procedure
16
-
17
- 1. Discover before editing. Run `pikku info middleware --verbose` and `pikku info functions --verbose` to understand existing auth setup.
18
- 2. Auth strategies live in wirings files — do not put `addHTTPMiddleware` calls inside function bodies.
19
- 3. Validate with `pikku all --tsc` after changes — it regenerates and then type-checks in one pass, and fails on type errors. Use `--tsc-summary` for a compact one-line-per-error report.
20
-
21
- For **middleware** (including tag middleware and service-to-service bearer auth) see `pikku-middleware`.
22
- For **permissions** (pikkuPermission, pikkuAuth, per-function authorization) see `pikku-permissions`.
23
-
24
- ## Session Management
25
-
26
- ```typescript
27
- // Read session in pikkuFunc (session guaranteed to exist)
28
- const getProfile = pikkuFunc({
29
- func: async ({ db }, _data, { session }) => {
30
- return await db.getUser(session.userId)
31
- },
32
- })
33
-
34
- // Set session (e.g., after login)
35
- const login = pikkuFunc({
36
- auth: false,
37
- func: async ({ jwt, db }, { email, password }, { setSession }) => {
38
- const user = await db.verifyCredentials(email, password)
39
- setSession({ userId: user.id })
40
- return { token: jwt.sign({ userId: user.id }) }
41
- },
42
- })
43
-
44
- // Clear session (logout)
45
- const logout = pikkuFunc({
46
- func: async ({}, _data, { clearSession }) => {
47
- clearSession()
48
- },
49
- })
50
- ```
51
-
52
- ## Built-in Auth Strategies
53
-
54
- Apply these via `addHTTPMiddleware` in a wirings file:
55
-
56
- ```typescript
57
- import { authBearer, authCookie, authAPIKey } from '@pikku/core/middleware'
58
- import { addHTTPMiddleware } from '@pikku/core/http'
59
-
60
- // JWT bearer token — reads Authorization header
61
- addHTTPMiddleware('*', [authBearer()])
62
-
63
- // Cookie-based sessions — auto-refreshes JWT
64
- addHTTPMiddleware('*', [
65
- authCookie({
66
- name: 'session',
67
- expiresIn: { value: 30, unit: 'day' },
68
- options: { httpOnly: true, secure: true },
69
- }),
70
- ])
71
-
72
- // API key — from x-api-key header or ?apiKey= query param
73
- addHTTPMiddleware('*', [authAPIKey({ source: 'all' })])
74
- ```
75
-
76
- ## Complete Example
77
-
78
- ```typescript
79
- // permissions.ts
80
- import { pikkuAuth, pikkuPermission } from '#pikku'
81
-
82
- export const isAuthenticated = pikkuAuth(async (_services, session) => !!session)
83
- export const isVerified = pikkuAuth(async (_services, session) => !!session?.emailVerified)
84
-
85
- // wirings/auth.wiring.ts
86
- import { authCookie } from '@pikku/core/middleware'
87
- import { addHTTPMiddleware } from '@pikku/core/http'
88
-
89
- addHTTPMiddleware('*', [
90
- authCookie({ name: 'session', expiresIn: { value: 30, unit: 'day' } }),
91
- ])
92
-
93
- // functions/auth.functions.ts
94
- export const login = pikkuFunc({
95
- auth: false,
96
- func: async ({ jwt, db }, { email, password }, { setSession }) => {
97
- const user = await db.verifyCredentials(email, password)
98
- setSession({ userId: user.id })
99
- return { token: jwt.sign({ userId: user.id }) }
100
- },
101
- })
102
-
103
- export const logout = pikkuFunc({
104
- func: async ({}, _data, { clearSession }) => {
105
- clearSession()
106
- },
107
- })
108
- ```
@@ -1,248 +0,0 @@
1
- ---
2
- name: pikku-services
3
- description: >-
4
- Use when setting up dependency injection, creating custom services, or configuring the service
5
- layer in a Pikku app. Covers pikkuServices (singleton), pikkuWireServices (per-request), service
6
- typing, built-in services, and tree-shaking. TRIGGER when: code uses
7
- pikkuServices/pikkuWireServices, user asks about services.ts, dependency injection, service
8
- factories, or built-in services (ConsoleLogger, JoseJWTService). DO NOT TRIGGER when: user asks
9
- about auth middleware (use pikku-security) or secrets/variables (use pikku-config).
10
- installGroups: [core]
11
- ---
12
-
13
- # Pikku Services (Dependency Injection)
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
- Pikku uses factory functions for dependency injection. Singleton services are created once at startup; wire services are created fresh per request/job/command. See `pikku-concepts` for the core mental model.
26
-
27
- ## Before You Start
28
-
29
- ```bash
30
- pikku info functions --verbose # See which services existing functions use
31
- pikku info tags --verbose # Understand project organization
32
- ```
33
-
34
- ## API Reference
35
-
36
- ### `pikkuServices(factory)` — singleton services (created once at startup)
37
-
38
- ```typescript
39
- import { pikkuServices } from '#pikku'
40
- import { ConsoleLogger } from '@pikku/core/services'
41
- import { JoseJWTService } from '@pikku/jose'
42
-
43
- export const createSingletonServices = pikkuServices(
44
- async (config, existingServices?) => {
45
- // config: your CoreConfig object
46
- // existingServices: optional, for chaining factories
47
- const logger = new ConsoleLogger()
48
- const database = new DatabasePool(config.database)
49
- await database.connect()
50
- const jwt = new JoseJWTService(
51
- async () => [{ id: 'my-key', value: config.jwtSecret }],
52
- logger
53
- )
54
- return { config, logger, database, jwt, books: new BookService() }
55
- }
56
- )
57
- ```
58
-
59
- ### `pikkuWireServices(factory)` — per-request services (fresh per HTTP request, queue job, CLI command, etc.)
60
-
61
- ```typescript
62
- import { pikkuWireServices } from '#pikku'
63
-
64
- export const createWireServices = pikkuWireServices(
65
- async (singletonServices, wire) => {
66
- // singletonServices: all singleton services
67
- // wire: transport context (session, channel, etc.)
68
- // Pikku merges these with singleton services automatically
69
- return {
70
- userSession: createUserSessionService(wire),
71
- dbTransaction: new DatabaseTransaction(singletonServices.database),
72
- }
73
- }
74
- )
75
- ```
76
-
77
- ### Auto-Generated Service Manifest
78
-
79
- After `npx pikku all`, Pikku generates `.pikku/pikku-services.gen.ts`, a manifest of which services are actually used by wired functions:
80
-
81
- ```typescript
82
- export const requiredSingletonServices = {
83
- database: true, // used by getUser, deleteUser
84
- audit: true, // used by deleteUser
85
- cache: false, // not used by any wired function
86
- jwt: true, // used by auth middleware
87
- } as const
88
-
89
- export type RequiredSingletonServices = Pick<
90
- SingletonServices,
91
- 'database' | 'audit' | 'jwt'
92
- > &
93
- Partial<Omit<SingletonServices, 'database' | 'audit' | 'jwt'>>
94
- ```
95
-
96
- ## Usage Patterns
97
-
98
- ### Using Services in Functions
99
-
100
- **Every service must be declared in `SingletonServices` (or `Services`) in `application-types.d.ts`.** Never access a service via a body-level cast (`services as typeof services & { myService: MyService }`) — that means the type is missing. Add the import and the field to `SingletonServices`, then destructure inline in the function signature. The inspector emits `SERVICES_NOT_DESTRUCTURED` and tree-shaking breaks when the first param is a plain identifier rather than an object pattern. Never `new` a service inside a function — services arrive only via injection.
101
-
102
- ```typescript
103
- // ✅ Correct — inline destructure, no cast
104
- const getUser = pikkuFunc({
105
- title: 'Get User',
106
- func: async ({ db, logger, jwt }, { userId }) => {
107
- logger.info('Fetching user', { userId })
108
- return { user: await db.getUser(userId) }
109
- },
110
- })
111
-
112
- // ❌ Wrong — named param + body cast; inspector warns + tree-shaking breaks
113
- const getUser = pikkuFunc({
114
- func: async (services, { userId }) => {
115
- const { db } = services as typeof services & { db: DbService }
116
- // ...
117
- },
118
- })
119
- ```
120
-
121
- ### Services Are Never Optional Inside a Function
122
-
123
- **Never write a `if (!service) throw ...` existence guard in a function body.** It is dead code, and it defeats the platform.
124
-
125
- Optionality lives in exactly one place — `services.ts` / the `SingletonServices` declaration — and it means *"this may not be created"*, not *"this may be missing at call time"*. A service is optional precisely because **nothing destructures it**, and `requireSingletonServices` therefore never creates it. The moment any wired function destructures it, Pikku creates it and guarantees it is there.
126
-
127
- The types enforce this rather than merely documenting it. The inspector records the services destructured by every wired `func`, `permissions` **and** `middleware`, and emits them as `RequiredSingletonServices`. The generated function types then default their service parameter to:
128
-
129
- ```typescript
130
- export type WiredSingletonServices = RequiredSingletonServices & SingletonServices
131
- export type WiredServices = RequiredSingletonServices & Services
132
- ```
133
-
134
- so a service that is `foo?: Foo` in `SingletonServices` arrives as a non-optional `Foo` in every function, permission and middleware that uses it. There is nothing to guard against.
135
-
136
- ```typescript
137
- // ✅ Correct — destructure and use; creation is guaranteed by the manifest
138
- const listThreads = pikkuFunc({
139
- func: async ({ agentRunService }, { threadId }) => {
140
- return await agentRunService.getThreadMessages(threadId)
141
- },
142
- })
143
-
144
- // ❌ Wrong — unreachable guard; signals a misunderstanding of service wiring
145
- const listThreads = pikkuFunc({
146
- func: async ({ agentRunService }, { threadId }) => {
147
- if (!agentRunService) throw new MissingServiceError('agentRunService')
148
- return await agentRunService.getThreadMessages(threadId)
149
- },
150
- })
151
- ```
152
-
153
- If a service really is conditional at runtime (e.g. an optional integration a deployment may not configure), that is a **configuration** concern: branch on config, or fail fast at startup in `services.ts` — not per-request in every function.
154
-
155
- ### Dynamic Import Optimization
156
-
157
- Use the generated manifest to conditionally import heavy dependencies — only the services actually wired get instantiated:
158
-
159
- ```typescript
160
- import { requiredSingletonServices } from '.pikku/pikku-services.gen.js'
161
-
162
- const createSingletonServices = pikkuServices(async (config) => {
163
- const logger = new ConsoleLogger()
164
-
165
- let jwt: JWTService | undefined
166
- if (requiredSingletonServices.jwt) {
167
- const { JoseJWTService } = await import('@pikku/jose')
168
- jwt = new JoseJWTService(keys, logger)
169
- }
170
-
171
- let database: Database | undefined
172
- if (requiredSingletonServices.database) {
173
- database = await createDatabase(config.databaseUrl)
174
- }
175
-
176
- return { config, logger, jwt, database }
177
- })
178
- ```
179
-
180
- ### Audit Wire Service
181
-
182
- `createInvocationAudit` + `createAuditedKysely` add per-request audit buffering that flushes on request close (no-op if `audit` is unconfigured). For the full pattern, no-op behavior, custom-event usage, and Fabric notes, read `references/audit-wire-service.md`.
183
-
184
- ### Built-in Services
185
-
186
- | Service | Package | Purpose |
187
- | -------------------------- | ---------------------- | -------------------------------- |
188
- | `ConsoleLogger` | `@pikku/core/services` | Console-based logging |
189
- | `JoseJWTService` | `@pikku/jose` | JWT sign/verify via jose |
190
- | `LocalSecretService` | `@pikku/core/services` | Local development secrets |
191
- | `LocalVariablesService` | `@pikku/core/services` | Local environment variables |
192
- | `PinoLogger` | `@pikku/pino` | Structured logging via Pino |
193
- | `createInvocationAudit` | `@pikku/core/services` | Per-request audit buffer |
194
- | `createAuditedKysely` | `@pikku/kysely` | Auto-capture DB queries as audit events |
195
-
196
- ## Complete Example
197
-
198
- ```typescript
199
- // services.ts
200
- import { pikkuServices, pikkuWireServices } from '#pikku'
201
- import { ConsoleLogger } from '@pikku/core/services'
202
- import { JoseJWTService } from '@pikku/jose'
203
-
204
- // Custom service
205
- class TodoStore {
206
- private todos: Map<string, Todo> = new Map()
207
- async create(title: string, priority: string) {
208
- const todo = { id: crypto.randomUUID(), title, priority, completed: false }
209
- this.todos.set(todo.id, todo)
210
- return todo
211
- }
212
- async get(id: string) { return this.todos.get(id) }
213
- async list() { return [...this.todos.values()] }
214
- async delete(id: string) { this.todos.delete(id) }
215
- }
216
-
217
- export const createSingletonServices = pikkuServices(async (config) => {
218
- const logger = new ConsoleLogger()
219
- const jwt = new JoseJWTService(
220
- async () => [{ id: 'my-key', value: config.jwtSecret }],
221
- logger
222
- )
223
- return {
224
- config,
225
- logger,
226
- jwt,
227
- secrets: new LocalSecretService(),
228
- variables: new LocalVariablesService(),
229
- todoStore: new TodoStore(),
230
- }
231
- })
232
-
233
- export const createWireServices = pikkuWireServices(
234
- async (singletonServices, wire) => ({
235
- scopedLogger: new ScopedLogger(wire.session?.initial?.userId),
236
- })
237
- )
238
-
239
- // functions/todos.functions.ts — services are auto-injected
240
- export const createTodo = pikkuFunc({
241
- title: 'Create Todo',
242
- func: async ({ todoStore, logger }, { title, priority }) => {
243
- const todo = await todoStore.create(title, priority)
244
- logger.info('Created todo', { id: todo.id })
245
- return { todo }
246
- },
247
- })
248
- ```
@@ -1,34 +0,0 @@
1
- # Audit Wire Service
2
-
3
- `createInvocationAudit` creates a per-request `InvocationAuditLog` that buffers audit events in memory and flushes them as a batch when the function-runner calls `closeWireServices` at the end of the request. If `singletonServices.audit` is not configured (local dev without Fabric), it returns a no-op `DisabledInvocationAudit` — no crash, events are silently dropped.
4
-
5
- Pair with `createAuditedKysely` to auto-capture every Kysely query as an audit event.
6
-
7
- ```typescript
8
- // services.ts
9
- import { createInvocationAudit } from '@pikku/core/services'
10
- import { createAuditedKysely } from '@pikku/kysely'
11
-
12
- export const createWireServices = pikkuWireServices(async (singletonServices, wire) => {
13
- const audit = createInvocationAudit(singletonServices.audit, wire)
14
- const kysely = singletonServices.kysely
15
- ? createAuditedKysely(singletonServices.kysely, { audit })
16
- : undefined
17
- return { audit, ...(kysely ? { kysely } : {}) }
18
- })
19
- ```
20
-
21
- The `audit` wire service is typed as `AuditLog` (from `@pikku/core`). Functions that emit custom events use it directly:
22
-
23
- ```typescript
24
- const deleteUser = pikkuFunc({
25
- func: async ({ audit }, { userId }) => {
26
- await audit.audit({ type: 'user.deleted', actor_user_id: userId })
27
- // ...
28
- },
29
- })
30
- ```
31
-
32
- `closeWireServices` (called automatically by the function-runner) invokes `audit.close()` → `singletonServices.audit.write(batch)` → platform-specific flush (e.g. CF Queue, libsql INSERT). No manual flushing needed.
33
-
34
- > **Fabric note:** Fabric provisions the audit queue and consumer worker automatically. The audit table schema is in `db/sqlite/0003-audit.sql` (starter-template). Run `pikku fabric validate` to confirm the migration is in place.
@@ -1,70 +0,0 @@
1
- # pikku-software-archaeology
2
-
3
- Reverse-engineers an existing repository into a **Product Blueprint**: the product intelligence hidden inside an implementation (domains, entities, commands, queries, events, policies, workflows, invariants, integrations, gaps), extracted as schema-validated JSON that a generator — in our case Pikku — can rebuild from.
4
-
5
- ```
6
- Existing Repository → pikku-software-archaeology → .knowledge/ blueprint → new Pikku application
7
- ```
8
-
9
- This is **not** a code indexer or doc generator. It extracts *intent over implementation*: `POST /api/users/:id/status` becomes the command `ActivateUser`; three scattered `if (inv.user_id !== req.user.id)` checks become one `InvoiceOwnerOnly` policy with three `enforcedAt` citations.
10
-
11
- ## Design decision: the AI is the parser
12
-
13
- There is deliberately **no scanner/AST tooling** in this skill. Static extraction is brittle and per-language (the first prototype's regex scanner broke before it ran once); the analyzing model already reads every language — JS, TS, Ruby, Python, PHP, Go — follows indirection, and understands intent. Determinism lives in the **output contract** instead: fixed file names, schema-validated shapes, sorted unordered collections (sequence-bearing arrays keep their observed order), and stable concept names, all enforced by a dumb JSON validator (`scripts/validate.mjs`). The audit is expensive; that's the trade we chose.
14
-
15
- ## How to run it
16
-
17
- In Claude Code, from (or pointing at) the target repo:
18
-
19
- > Use the pikku-software-archaeology skill to extract a product blueprint from /path/to/repo
20
-
21
- The agent then:
22
- 1. **Surveys** the repo (manifests, entry points, routes, jobs, webhooks, schema, config, TODO/HACK markers) — facts only.
23
- 2. **Excavates the test suite** — `describe`/`it` names become workflow scenarios; assertions confirm policies and upgrade confidence; rules that exist *only* in tests are captured.
24
- 3. **Extracts** through twelve lenses (domains, entities, commands, …) per the pipeline in `SKILL.md`. Large repos fan out subagents per lens and merge.
25
- 4. **Cross-checks and validates**:
26
- ```bash
27
- node .claude/skills/pikku-software-archaeology/scripts/validate.mjs <repo>/.knowledge
28
- ```
29
- The validator checks every file against `references/blueprint.schema.json` plus referential integrity across files (commands reference defined domains, api surfaces map to defined commands/queries, events have producers, …).
30
- 5. Writes `blueprint.md`, the human synthesis.
31
-
32
- Output lands in `<repo>/.knowledge/` — 14 core JSON files + `blueprint.md` (see `SKILL.md` for the full listing). Repos with a frontend and/or non-HTTP consumer channels also get an **optional consumer-surface layer**: `interfaces.json` (every way the product is used — web UI, CLI, MCP server for AI agents, OpenAPI/REST, SDK, realtime, webhooks) plus `frontend.json` / `frontend-routes.json` / `frontend-components.json`. The frontend component inventory's `rebuild` field is the key output: it separates trivially-rebuildable standard components from the **custom-logic** pieces (charts, complex tables, editors) that must be carefully ported. Backend-only repos omit these and the validator does not complain.
33
-
34
- ### Incremental re-analysis
35
-
36
- Concept names are the stable IDs. On re-run after code changes, re-extract only the affected lens/domain, diff against the existing `.knowledge/`, and leave unrelated entries verbatim. Unordered collections are sorted so diffs stay reviewable; sequence-bearing arrays stay in observed order.
37
-
38
- ## How Pikku consumes the blueprint
39
-
40
- Full mapping table in `references/pikku-mapping.md`. Summary: entities → Kysely migrations + Zod schemas; commands/queries → `pikkuFunc`s; api surfaces → `wireHTTP`; policies → shared permission functions (collapsing duplicated legacy checks); system workflows → `wireScheduler`/`wireQueueWorker`/`pikkuWorkflowFunc`; integrations → injected services with `wireSecret`/`wireCredential`; test-derived scenarios → `pikkuUserFlow` stories / e2e tests. Humans resolve `migration.json.decisionsNeeded` before any generation starts.
41
-
42
- ## How uncertainty is represented
43
-
44
- Every extracted concept carries:
45
-
46
- ```json
47
- { "evidence": [{ "file": "controllers/invoices.js", "lines": "52", "note": "guard: only drafts editable" }],
48
- "confidence": "high" }
49
- ```
50
-
51
- - **high** — the behavior itself is in the cited code/schema/test. Generates directly.
52
- - **medium** — inferred from converging signals. Generates with a review marker.
53
- - **low** — plausible reconstruction. Never auto-generated; surfaced for human review.
54
-
55
- Two further distinctions keep facts and guesses separate:
56
- - `events[].explicit: false` — the event was *reconstructed* from side-effect clusters (email + status flip), not emitted by the code.
57
- - Comments/docs vs code: comments describe intent, code describes behavior. Disagreements are recorded as the code's behavior plus a `gaps.json` entry.
58
-
59
- ## Repo layout
60
-
61
- ```
62
- pikku-software-archaeology/
63
- ├── SKILL.md # skill definition + extraction pipeline
64
- ├── README.md # this file
65
- ├── references/
66
- │ ├── blueprint.schema.json # the output contract (JSON Schema)
67
- │ └── pikku-mapping.md # blueprint → Pikku primitives
68
- └── scripts/
69
- └── validate.mjs # schema + cross-file validation (node, no deps)
70
- ```